GROUP BY AND RIGHT JOINS IN DB2 - group-by

Select p.prodCode,
p.description,
p.unit,
SUM(sd.quantity) "Total quantity"
FROM salesDetail sd
RIGHT JOIN product p
ON p.prodCode = sd.prodCode
GROUP BY p.prodCode
ORDER BY 4 DESC
Help! My Script is not running. I need to get the total quantity of every product but my group by is not working.

Compute the sum of the quantity per product in separate subquery, and then join this back to the original product table:
SELECT t1.prodCode,
t1.description,
t1.unit,
t2.total_quantity
FROM product t1
INNER JOIN
(
SELECT p.prodCode, SUM(sd.quantity) total_quantity
FROM product p
LEFT JOIN salesDetail sd
ON p.prodCode = sd.prodCode
GROUP BY p.prodCode
) t2
ON t1.prodCode = t2.prodCode
Note that I replaced the RIGHT JOIN with a LEFT JOIN by switching the order of the joined tables in the subquery.
Update:
If you absolutely need to use a RIGHT JOIN, then just replace the subquery with this:
SELECT p.prodCode, SUM(sd.quantity) total_quantity
FROM salesDetail sd
RIGHT JOIN product p
ON p.prodCode = sd.prodCode
GROUP BY p.prodCode

Related

Compare an aggregate to another aggregate with window functions

The following query (tested with Postgresql 11.1) evaluates, for each customer/product combination, the following elements:
(A) the sum of sales value that the customer spent on this product
(B) the sum of sales value that the customer spent in the parent category of this product
And divides A / B to get to a metric called loyalty.
select
pp.customer, pp.product, pp.category,
pp.sales_product / pc.sales_category as loyalty
from (
select
t.household_key as customer,
t.product_id as product,
p.commodity as category,
sum(t.sales_value) as sales_product
from transaction_data t
left join product p on p.product_id = t.product_id
group by t.household_key, t.product_id, p.commodity
) pp
left join (
select
t.household_key as customer,
p.commodity as category,
sum(t.sales_value) as sales_category
from transaction_data t
left join product p on p.product_id = t.product_id
group by t.household_key, p.commodity
) pc on pp.customer = pc.customer and pp.category = pc.category
;
Results are of this form:
customer product category loyalty
---------------------------------------------
1 tomato food 0.01
1 beef food 0.02
1 toothpaste hygiene 0.04
1 toothbrush hygiene 0.03
My question is, instead of having to rely on two sub-queries which are then left-joined, would it be feasible with a single query using window functions instead?
I've tried to do something like the following, but obviously this doesn't work because, in this case, column "t.sales_value" must appear in the GROUP BY clause or be used in an aggregate function. I don't see what can be done to fix this.
-- does not work
select
t.household_key as customer,
t.product_id as product,
p.commodity as category,
sum(t.sales_value) as sales_product,
sum(t.sales_value) over (partition by t.household_key, p.commodity) as sales_category
from transaction_data t
left join product p on p.product_id = t.product_id
group by t.household_key, t.product_id, p.commodity;
I don't know how to do this without using either a join or a subquery, but here is one way to do this with a subquery, using analytic functions:
WITH cte AS (
SELECT
t.household_key AS customer,
t.product_id AS product,
p.commodity as category,
SUM(t.sales_value) OVER (PARTITION BY t.household_key, t.product_id, p.commodity)
AS sales_product,
SUM(t.sales_value) OVER (PARTITION BY t.household_key, p.commodity)
AS sales_category
FROM transaction_data t
LEFT JOIN product p
ON p.product_id = t.product_id
)
SELECT
t.customer,
t.product,
t.category
MAX(t.sales_product) / MAX(t.sales_category) AS loyalty
FROM cte
GROUP BY
t.customer,
t.product,
t.category;
The trick here is to make a single pass over your joined tables, and use analytic sum to compute the aggregates you want, with two different partitions, one with 2 columns and the other with three columns. Then, we can aggregate by 3 columns and just arbitrarily take the max value of the aggregates for each group.

Sum of two columns showing wrong result tsql

I have query as
select distinct
EnglishProductCategoryName,
sum(isnull(fic.SalesAmount,0))InternetSalesAmount,
sum(isnull(frs.SalesAmount,0))ResellerSalesAmount
from dimproduct dp join DimProductSubcategory dps on dp.ProductSubcategoryKey=dps.ProductSubcategoryKey
join DimProductCategory dpc on dpc.ProductCategoryKey=dps.ProductCategoryKey
left join FactInternetSales fic on fic.ProductKey=dp.ProductKey
left join FactResellerSales frs on frs.ProductKey= dp.ProductKey
group by EnglishProductCategoryName
but when I do
select sum(isnull(fis.SalesAmount,0))InternetSalesAmount from FactInternetSales
select sum(isnull(frs.SalesAmount,0))resellerSalesAmount from FactResellerSales
and compare sum of whole englishproductcategoryname and sum of internet sales amount,reseller sales amount should be same but its not same
Help will be appriciated
Thanks
Check for missing ProductSubcategory or ProductCategory
select distinct
EnglishProductCategoryName,
sum(isnull(fic.SalesAmount,0))InternetSalesAmount,
sum(isnull(frs.SalesAmount,0))ResellerSalesAmount
from dimproduct dp left join DimProductSubcategory dps on dp.ProductSubcategoryKey=dps.ProductSubcategoryKey
left join DimProductCategory dpc on dpc.ProductCategoryKey=dps.ProductCategoryKey
left join FactInternetSales fic on fic.ProductKey=dp.ProductKey
left join FactResellerSales frs on frs.ProductKey= dp.ProductKey
group by EnglishProductCategoryName

Is there any way to find out total size of a collection and its items in Dspace?

i am trying to find out total "size of each individual collection" in Dspace for my MIS report.
Use this query to get.. total collections , no of files and item size.
select ab.TotalSize,cd.text_value,count_pdf from
(Select a.collection_id,sum(size_bytes) as TotalSize from collection2item a inner join item2bundle b on a.item_id=b.item_id
inner join bundle2bitstream c on b.bundle_id=c.bundle_id inner join bitstream d on c.bitstream_id=d.bitstream_id where d.deleted='f'
group by a.collection_id) ab
inner join
(SELECT resource_id,count(collection2item.item_id) as count_pdf,metadatavalue.text_value FROM
collection2item inner join metadatavalue on
collection2item.collection_id=metadatavalue.resource_id where
metadata_field_id=64 and resource_type_id=3 GROUP BY
metadatavalue.text_value,metadatavalue.resource_id) cd
on ab.collection_id=cd.resource_id;
I create this query to obtain the number of items per collection and year
SELECT metadatavalue.resource_id AS "Colection", metadatavalue.text_value AS "Collection name",
count(item.item_id) AS "Elements", EXTRACT(YEAR FROM item.last_modified) AS "Year"
FROM item INNER JOIN metadatavalue ON item.owning_collection = metadatavalue.resource_id
WHERE metadatavalue.metadata_field_id=66 AND metadatavalue.resource_type_id=3
GROUP BY item.owning_collection, "Year", metadatavalue.resource_id, metadatavalue.text_value
ORDER BY owning_collection

Group by with left join

I need to to sum (quantity and amount) for each product sold in in the table "account_invoice_line"
SELECT seller.name
ipartner.name AS invoice
brand.name AS brand, pt.name AS product,
SUM(ail.quantity) AS quantity, SUM(ail.price_subtotal) as amount
FROM account_invoice_line ail
LEFT JOIN account_invoice i ON ail.invoice_id = i.id
LEFT JOIN res_partner AS ipartner on ipartner.id = i.partner_id
LEFT JOIN res_users u ON u.id = i.user_id
LEFT JOIN res_partner AS seller ON seller.id = u.partner_id
LEFT JOIN product_product pp ON pp.id = ail.product_id
LEFT JOIN product_template pt ON pt.id = pp.product_tmpl_id
LEFT JOIN brand ON brand.id = pp.brand_id
GROUP BY seller.name, invoice, brand, pt.name
ORDER BY seller.name, invoice, brand, pc.name, pt.name
Unfortunately, I get this king of result:
-
Seller, Invoice, Brand, Product, Quantity, Amount
...
Seller1, Customer1, Brand1, Product1, 5, 4.70
Seller1, Customer1, Brand1, Product1, 10, 9.30
...
I was expecting for this (summed quantity and amount for the same product):
Seller1, Customer1, Brand1, Product1, 15, 14.0
Are you sure you need left joins for all of the tables?
Having account_invoice_line and then add LEFT JOIN, could make that one of the fields is NULL on the other tables, and that might be a reason why you see 2 records instead of one (let's say partner id is NULL in one of them).
If u just group by one column name only (for example: brand), do u still get same result?

how to solve this complicated sql query

these are the five given tables
http://i58.tinypic.com/53wcxe.jpg
this is the recomanded result
http://i58.tinypic.com/2vsrts7.jpg
please help how can i write a query to have this result.
no idea how!!!!
SELECT K.* , COUNT (A.Au_ID) AS AnzahlAuftr
FROM Kunde K
LEFT JOIN Auftrag A ON K.Kd_ID = A.Au_Kd_ID
GROUP BY K.Kd_ID,K.Kd_Firma,K.Kd_Strasse,K.Kd_PLZ,K.Kd_Ort
ORDER BY K.Kd_PLZ DESC;
SELECT COUNT (F.F_ID) AS AnzahlFahrt
FROM Fahrten F
RIGHT JOIN Auftrag A ON A.Au_ID = F.F_Au_ID
SELECT SUM (T.Ts_Strecke) AS SumStrecke
FROM Teilstrecke T
LEFT JOIN Fahrten F ON F.F_ID = T.Ts_F_ID
how to join these 3 in one?
Grouping on Strasse etc. is not necessary and can be quite expensive. What about this approach:
SELECT K.*, ISNULL(Au.AnzahlAuftr,0) AS AnzahlAuftr, ISNULL(Au.AnzahlFahrt,0) AS AnzahlFahrt, ISNULL(Au.SumStrecke,0) AS SumStrecke
FROM Kunde K
LEFT OUTER JOIN
(SELECT A.Au_Kd_ID, COUNT(*) AS AnzahlAuftr, SUM(Fa.AnzahlFahrt1) AS AnzahlFahrt, SUM(Fa.SumStrecke2) AS SumStrecke
FROM Auftrag A LEFT OUTER JOIN
(SELECT F.F_Au_ID, COUNT(*) AS AnzahlFahrt1, SUM(Ts.SumStrecke1) AS SumStrecke2
FROM Fahrten F LEFT OUTER JOIN
(SELECT T.Ts_F_ID, SUM(T.Ts_Strecke) AS SumStrecke1
FROM Teilstrecke T
GROUP BY T.Ts_F_ID) AS Ts
ON Ts.Ts_F_ID = F.F_ID
GROUP BY F.F_Au_ID) AS Fa
ON Fa.F_Au_ID = A.Au_ID
GROUP BY A.Au_Kd_ID) AS Au
ON Au.Au_Kd_ID = K.Kd_ID