How to SUM an AS column in SQL - sql

I have the following code...
SELECT WF.Word, WF.Frequency, WW.Weight, (WF.Frequency * WW.Weight) AS Product
FROM WF
INNER JOIN WW ON WW.Word = WF.word
Which outputs the following...
WORD | FREQUENCY | WEIGHT | PRODUCT
Fat 3 2 6
Ugly 2 4 8
Stupid 1 7 7
I also want to sum the product column at the same time. I understand how to sum an existing column but unsure how to sum a column i'm creating.

SELECT SUM(WF.Frequency * WW.Weight) AS Product
FROM WF
INNER JOIN WW ON WW.Word = WF.word

SELECT WF.Word, SUM(WF.Frequency) Frequency, SUM(WW.Weight) Weight, SUM(WF.Frequency * WW.Weight) AS Product
FROM WF
INNER JOIN WW ON WW.Word = WF.word
GROUP BY WF.Word
;
SELECT SUM(WF.Frequency * WW.Weight) Product
FROM WF
INNER JOIN
WW ON WW.Word = WF.word

Related

ORA-00904: "Q"."ITEM_NO": invalid identifier - Oracle SQL group by issue

I have this query to fetch item no's and their quantities filtered by a specific unit.
select q.item_no, sum(q.quantity) from item_unit_quantity q
where q.unit_no = 'PH00000096' group by q.item_no
Now I want to add price column which I get from another two tables
There is a condition, Price is always the maximum of the latest three GRN dates.
select max(price) from (select price from grn_item gi join grn g on gi.grn_no = g.grn_no
where gi.item_no = 'IT00001896' order by g.grn_date desc) where rownum <= 3
When I combined the queries as below,
select q.item_no, sum(q.quantity),
(select max(price) from (select price from grn_item gi join grn g on gi.grn_no = g.grn_no
where gi.item_no = q.item_no order by g.grn_date desc) where rownum <= 3) "PRICE"
from item_unit_quantity q where q.unit_no = 'PH00000096' group by q.item_no
I get
ORA-00904: "Q"."ITEM_NO": invalid identifier
But if I change the above as "gi.item_no = 'IT00001896'" I get
ITEM_NO | Sum(Quantity) | Price
--------------------------------------
IT00012824 | 14 | 3.68
IT00006345 | 494 | 3.68
IT00001896 | 5 | 3.68
I still want to display the Item no, Item quantity and price for each Item no in this query, how can I do this?
Your question is a bit hard to follow without sample data. However, subqueries with GROUP BY can be finicky. A simple solution is to move the subquery to the FROM clause:
select q.item_no, sum(q.quantity), max(max_price)
from item_unit_quantity q left join
(select gi.item_no, max(g.price) as max_price
from grn_item gi join
grn g
on gi.grn_no = g.grn_no
group by gi.item_no
) gi
on gi.item_no = q.item_no
where q.unit_no = 'PH00000096'
group by q.item_no

Sum of a subquery?

Background:
We are doing a price adjustment in our database. The price adjustment is based on the bill of materials, and what each materials' new cost is. So I have to select the item from the item table, its BOM, and the new price table, and adjust the price based on the total of the materials it takes to make each item. Items are comprised of varying quantities of varying materials, so the master query will call this subquery to get the total adjustment:
select
ta.Code,
ta.Quantity,
(select tb.cost - tb.NewCost * ta.Quantity ) as BOMEffect
from BOM TA
inner join ITEM TC on tC.ItemCode = tA.Father
inner join NewPriceTable TB on tA.Code = tB.Item
where TA.Father = '100-01'
and tc.PriceList = 3
order by ta.Father
Which gives me the results (this is all of the materials of one item, quantity of each material, and the price adjustment):
Code Quantity BOMEffect
D .003 56.000000 -95.08
D .004 28.000000 -62
D .005 20.000000 -54.6
d .006 2.000000 -3.3
D .01 2.000000 -5.5
D .015 4.000000 -25.52
D .02 4.000000 -34
All I need from this query is the total BOMEffect (-280). But if I just replace the select statement with:
select
sum((select tb.cost - tb.NewCost * ta.Quantity )) as BOMEffect
from BOM TA
inner join ITEM TC on tC.ItemCode = tA.Father
inner join NewPriceTable TB on tA.Code = tB.Item
where TA.Father = '100-01'
and tc.PriceList = 3
order by ta.Father
I get:
Cannot perform an aggregate function on an expression containing an aggregate or a subquery.
I know what it's saying, but I don't know any other way to do it. How else can I get this total? This is a small subquery that is part of a larger query, so I only need to return the total. I could probably use a view or a temp table, but I would like to stay away from that if possible.
remove the select inside the sum and order by
select
sum(tb.cost - tb.NewCost * ta.Quantity) as BOMEffect
from BOM TA
inner join ITEM TC on tC.ItemCode = tA.Father
inner join NewPriceTable TB on tA.Code = tB.Item
where TA.Father = '100-01'
and tc.PriceList = 3
If you want to include Code and Quantity you would have to include those in the GROUP BY clause:
select
ta.Code,
ta.Quantity,
sum(tb.cost - tb.NewCost * ta.Quantity) as BOMEffect
from BOM TA
inner join ITEM TC on tC.ItemCode = tA.Father
inner join NewPriceTable TB on tA.Code = tB.Item
where TA.Father = '100-01'
and tc.PriceList = 3
GROUP BY ta.Code, ta.Quantity

Grouping and subtotalling

I am currently writing a report which I wish to group by the field apar_id and also have a sub total for each of these.
Given my limited knowledged and being bambozled by many google answer I am asking for your kind input.
My code is as follows:
SELECT d.apar_name,a.*,b.rel_value,c.dim_b
FROM acutrans a
LEFT JOIN aglrelvalue b ON a.apar_id=b.att_value
LEFT JOIN acrtrees c ON b.rel_value=c.cat_1
LEFT JOIN acuheader d ON a.apar_id=d.apar_id
WHERE b.rel_attr_id='212'
AND b.attribute_id='A4'
AND a.client='CL'
AND a.client=b.client
AND a.client=c.client
AND c.att_agrid='60'
AND (b.rel_value='X24' OR c.dim_b='PCT')
ORDER BY a.apar_id
The results are similar to
apar_id | ..... | amount.....
x 100
x 300
x -100
Y 400
Y 100
and would like
apar_id | ..... | amount.....
x 100
x 300
x -100
Total X 300
Y 400
Y 100
Total Y 500
Thanks in advance
Many databases support the with rollup clause for group by. If yours does, you can do what you want by making this a group by statement.
SELECT d.apar_name, sum(amount) as amount
FROM acutrans a
LEFT JOIN aglrelvalue b ON a.apar_id=b.att_value
LEFT JOIN acrtrees c ON b.rel_value=c.cat_1
LEFT JOIN acuheader d ON a.apar_id=d.apar_id
WHERE b.rel_attr_id='212'
AND b.attribute_id='A4'
AND a.client='CL'
AND a.client=b.client
AND a.client=c.client
AND c.att_agrid='60'
AND (b.rel_value='X24' OR c.dim_b='PCT')
GROUP BY d.apar_name WITH ROLLUP;
This will not specifically solve this problem, although you can adapt this solution (if your database supports it).

Crosstab/cross over query

Given data looks like
PLI_ID OWN_ID DCSF_ID SCH_NAME PREMIUM1 PREMIUM2 DESCRIPTION
901 2 1000 Dfe-School 1 86.40 7.20 Heads, Deps
902 2 1000 Dfe-School 2 403.30 8.40 Relief Bursar
903 2 1000 Dfe-School 3 327.00 8.40 £10.00
904 2 1000 Dfe-School 4 381.50 8.40 £11.00
905 2 1000 Dfe-School 5 152.60 8.40 Teaching staff
Expected data to look like
School £10.00 £11.00 Heads, Deps Relief Bursar Teaching staff Total
Dfe-School 1
Dfe-School 2
Dfe-School 3
Dfe-School 4
Total [Pre-Total]
I am not sure whether to write a Cross Tab or Cross Over query, as suggested. Let me know, if need more explanation.
My query uses around 6 tables and it looks like this:
SELECT PolicyLine.PLI_POS_Id, Policy.POL_OWN_Id, Policy.POL_DCSF, School.SCH_Name, PolicyLine.PLI_Premium, CoverPremium.CPR_Premium, StaffCategory.SCA_Description FROM
School
INNER JOIN Policy ON School.SCH_OWN_Id = Policy.POL_OWN_Id AND School.SCH_DCSF = Policy.POL_DCSF
INNER JOIN PolicyLine ON Policy.POL_Id = PolicyLine.PLI_POL_Id
INNER JOIN CoverOption ON PolicyLine.PLI_COP_Id = CoverOption.COP_Id
INNER JOIN CoverPremium ON CoverOption.COP_Id = CoverPremium.CPR_COP_Id AND Policy.POL_OWN_Id = CoverPremium.CPR_OWN_Id
RIGHT OUTER JOIN StaffCategory ON CoverOption.COP_SCA_Id = StaffCategory.SCA_
Based on your existing query you would use something like this:
SELECT School.SCH_Name school,
[£10.00], [£11.00],
[Heads, Deps], [Relief Bursar], [Teaching staff]
FROM
(
SELECT PolicyLine.PLI_POS_Id,
Policy.POL_OWN_Id,
Policy.POL_DCSF,
School.SCH_Name,
PolicyLine.PLI_Premium,
CoverPremium.CPR_Premium,
StaffCategory.SCA_Description
FROM School
INNER JOIN Policy
ON School.SCH_OWN_Id = Policy.POL_OWN_Id
AND School.SCH_DCSF = Policy.POL_DCSF
INNER JOIN PolicyLine
ON Policy.POL_Id = PolicyLine.PLI_POL_Id
INNER JOIN CoverOption
ON PolicyLine.PLI_COP_Id = CoverOption.COP_Id
INNER JOIN CoverPremium
ON CoverOption.COP_Id = CoverPremium.CPR_COP_Id
AND Policy.POL_OWN_Id = CoverPremium.CPR_OWN_Id
RIGHT OUTER JOIN StaffCategory
ON CoverOption.COP_SCA_Id = StaffCategory.SCA_
) x
PIVOT
(
sum(PLI_Premium)
for SCA_Description in([£10.00], [£11.00],
[Heads, Deps], [Relief Bursar], [Teaching staff])
) p
See SQL Fiddle with Demo
You probably want a PIVOT query, but from your example it's hard to tell what that should look like.
SELECT *
FROM yourtable
PIVOT
(SUM(Premium) FOR sch_name in ([£10.00],[£11.00],[Heads, Deps],[Relief Bursar],[Teaching staff]))

Join SQL Query Problem?

First Select Statement:
SELECT
dbo.FG_FILLIN.PartNumber,
dbo.DropshipPackinglist.Shiplist_Qty,
dbo.DropshipPackinglist.Quantity
FROM dbo.FG_FILLIN INNER JOIN
dbo.DropshipPackinglist ON
dbo.FG_FILLIN.PartNumber = dbo.DropshipPackinglist.PartNumber
WHERE (dbo.FG_FILLIN.Batch = 'CIP_HK_6')
GROUP BY
dbo.FG_FILLIN.Batch,
dbo.FG_FILLIN.PartNumber,
dbo.FG_FILLIN.ItemNumber,
dbo.DropshipPackinglist.Shiplist_Qty,
dbo.DropshipPackinglist.Quantity
Result :
PartNumber Shiplist_Qty Quantity
P02-070161-00111-C100 6 3
P02-070161-10111-C100 6 3
2nd :
SELECT PartNumber,COUNT(Batch) AS Created
FROM dbo.FG_FILLIN
WHERE Batch='CIP_HK_6'
GROUP BY Batch,PartNumber
Result :
PartNumber Created
P02-070161-00111-C100 3
P02-070161-10111-C100 1
Joining this two Query I cant show this one: RESULT NEEDED
PartNumber Shiplist_Qty Quantity Created
P02-070161-00111-C100 6 3 3
P02-070161-10111-C100 6 3 1
It always show : when i Add Count(dbo.FG_FILLIN.Batch) as Created
PartNumber Shiplist_Qty Quantity Created
P02-070161-00111-C100 6 3 6
P02-070161-10111-C100 6 3 2
Any Advice.? Thanks In Regards!
Using a subselect:
SELECT f.PartNumber,
dpl.Shiplist_Qty,
dpl.Quantity,
(SELECT COUNT(Batch) AS Created
FROM dbo.FG_FILLIN x
WHERE x.batch = f.batch
AND x.partnumber = f.partnumber
GROUP BY Batch, PartNumber) AS created
FROM dbo.FG_FILLIN f
JOIN dbo.DropshipPackinglist dpl ON dpl.partnumber = f.partnumber
WHERE f.Batch = 'CIP_HK_6'
GROUP BY f.Batch, f.PartNumber, f.ItemNumber, dpl.Shiplist_Qty, dpl.Quantity
Using a JOIN to a derived table/inline view
SELECT f.PartNumber,
dpl.Shiplist_Qty,
dpl.Quantity,
x.created
FROM dbo.FG_FILLIN f
JOIN dbo.DropshipPackinglist dpl ON dpl.partnumber = f.partnumber
LEFT JOIN (SELECT t.partnumber,
t.batch,
COUNT(Batch) AS Created
FROM dbo.FG_FILLIN t
GROUP BY Batch, PartNumber) x ON x.partnumber = f.partnumber
AND x.batch = f.batch
WHERE f.Batch = 'CIP_HK_6'
GROUP BY f.Batch, f.PartNumber, f.ItemNumber, dpl.Shiplist_Qty, dpl.Quantity
Change "LEFT JOIN" to "JOIN" if you only want to see parts that have created values.