I have a query I've used to extract data from a database:
SELECT a.YOA YOA, a.Claim_Status_Type,
SUM(Cumulative_Total_Incurred_Cost*Exchange_Rate_Multiplier)AS
Cumulative_Total_Incurred_Cost
FROM F_Claims_Monthly_Snapshot a
inner join Dim_period b on (b.Period_Key = a.Accounting_Period_Key)
inner join tgt.Dim_BusinessDate c on (b.Month_End_Date_Key =
c.Business_Date_Key)
inner join tgt.Dim_BusinessUnit h on (a.Business_Unit_Key = h.Business_Unit_Key)
inner join tgt.Dim_Currency ccy on ccy.Currency_Key= a.Currency_Key
inner join tgt.Dim_Currency input_curr on input_curr.Currency_Key = a.Currency_Key
inner join tgt.Fct_CurrencyRate cr on cr.FROM_Currency_Key = a.Currency_Key and cr.Exchange_Date_Key = a.Month_End_Date_Key and Exchange_Rate_Type = 'Actual Rates'
inner join tgt.Dim_Currency report_curr on report_curr.Currency_Key = cr.To_Currency_Key and report_curr.Currency_Code='GBP'
inner join tgt.Dim_PRAClass i on (a.PRA_Class_Key=i.PRA_Class_Key)
inner join tgt.Dim_MasterAgreement j on (a.Master_Agreement_Key = j.Master_Agreement_Key)
inner join tgt.Dim_BusinessDate k on (a.Month_End_Date_Key = k.Business_Date_Key)
WHERE a.YOA between 2014 and 2018
and left(convert(date,(cast(a.Month_End_Date_Key as char(10))),3),8) = left(convert(date,(cast(First_Cost_Movement_Date_Key as char(10))),3),8)
and h.Business_Unit_name = 'Delegated Commercial'
GROUP BY a.YOA,i.PRA_Class,a.Claim_Status_Type;
The Query produces the following table:
YOA Claim_Status Total_Cost
2016 CLOSED 2266634.000000
2014 CLOSED 9880638.990000
2015 OPEN 5904188.060000
2016 CLOSED 4088.570000
2016 OPEN 3589749.000000
2015 CLOSED 22701.000000
2017 OPEN 1001.000000
2017 OPEN 844649.000000
2016 OPEN 6594017.000000
2014 OPEN 50000.000000
2017 OPEN 1835594.810000
2017 CLOSED 112805.000000
2016 CLOSED 4292586.25000
I would now like to alter the table above to look like below:
YOA Open_Total Closed_Total
2017 (SUM of all OPEN Status'for 2017) (SUM of all CLOSED Status' for 2017)
2016 (SUM of all OPEN Status'for 2016) (SUM of all CLOSED Status' for 2016)
2015 (SUM of all OPEN Status'for 2015) (SUM of all CLOSED Status' for 2015)
2014 (SUM of all OPEN Status'for 2014) (SUM of all CLOSED Status' for 2014)
So in short I would like to create a new query which will produce a table that will displayed the:
SUM of all OPEN total_costs for 2016 as new column called 'OPEN total'
SUM of all CLOSED total_costs for 2015 as new column called 'CLOSED_total'
Try with a CASE WHEN inside your SUM(..):
SELECT
a.YOA YOA,
SUM(CASE a.Claim_Status_Type
WHEN N'OPEN'
THEN Cumulative_Total_Incurred_Cost*Exchange_Rate_Multiplier
ELSE 0.0 END) AS Open_Cumulative_Total_Incurred_Cost,
SUM(CASE a.Claim_Status_Type
WHEN N'CLOSED'
THEN Cumulative_Total_Incurred_Cost*Exchange_Rate_Multiplier
ELSE 0.0 END) AS Closed_Cumulative_Total_Incurred_Cost
FROM F_Claims_Monthly_Snapshot a
inner join Dim_period b on (b.Period_Key = a.Accounting_Period_Key)
inner join tgt.Dim_BusinessDate c
on (b.Month_End_Date_Key = c.Business_Date_Key)
inner join tgt.Dim_BusinessUnit h on (a.Business_Unit_Key = h.Business_Unit_Key)
inner join tgt.Dim_Currency ccy on ccy.Currency_Key= a.Currency_Key
inner join tgt.Dim_Currency input_curr on input_curr.Currency_Key = a.Currency_Key
inner join tgt.Fct_CurrencyRate cr on cr.FROM_Currency_Key = a.Currency_Key and cr.Exchange_Date_Key = a.Month_End_Date_Key and Exchange_Rate_Type = 'Actual Rates'
inner join tgt.Dim_Currency report_curr on report_curr.Currency_Key = cr.To_Currency_Key and report_curr.Currency_Code='GBP'
inner join tgt.Dim_PRAClass i on (a.PRA_Class_Key=i.PRA_Class_Key)
inner join tgt.Dim_MasterAgreement j on (a.Master_Agreement_Key = j.Master_Agreement_Key)
inner join tgt.Dim_BusinessDate k on (a.Month_End_Date_Key = k.Business_Date_Key)
WHERE a.YOA between 2014 and 2018
and left(convert(date,(cast(a.Month_End_Date_Key as char(10))),3),8) = left(convert(date,(cast(First_Cost_Movement_Date_Key as char(10))),3),8)
and h.Business_Unit_name = 'Delegated Commercial'
GROUP BY a.YOA;
select yoa, sum(case when claimstatus='open' then Total_Cost else null end) open_total,
sum(case when claimstatus='closed' then Total_Cost else null end) closed_total
from table_name
group by yoa
Related
I have a sql query that creates a label in a cab file for a shopping company. I want to include the amount of packages in an order, some have multiple.
Each returns line in my select query has an I’d and contains a package but I need to count them.
So I have:
Name Email Weight Price ID
Joe B J#.com 10 12.5. 1
Joe B J#.com 10 12.5. 1
Joe C JC#.com 10 14.5. 2
How can I count the ID’s to return a column called pieces and in this example it would be 2 for ID 1 and 1 for ID 2
Thanks
James
enter code here
Select
'WPX' As 'Product Code',
delivery_header.dh_datetime As 'Shipment Date',
'G' As 'Shipment Type',
order_header_detail.ohd_delivery_email As 'Receiver Email Address',
variant_detail.vad_weight As 'Shipment Weight in KG',
(lots of other fields....)
delivery_header.dh_number As 'Shippers Reference',
(SELECT Count(*)
FROM delivery_header
WHERE
dh_number = OU.dh_number
) As 'Number of Pieces',
From delivery_line_item Inner Join
delivery_header On delivery_header.dh_id = delivery_line_item.dli_dh_id
Inner Join
order_line_item On delivery_line_item.dli_oli_id = order_line_item.oli_id
Inner Join
variant_detail On variant_detail.vad_id = order_line_item.oli_vad_id
Inner Join
order_header On order_header.oh_id = order_line_item.oli_oh_id Inner Join
stock_location On stock_location.sl_id = order_line_item.oli_sl_id Inner Join
customer_detail On customer_detail.cd_id = order_header.oh_cd_id Inner Join
order_header_detail On order_header.oh_id = order_header_detail.ohd_oh_id
Left Join
order_header_analysis On order_header.oh_id = order_header_analysis.oha_oh_id
Left Join
order_customer_analysis On order_header.oh_id =
order_customer_analysis.oca_oh_id Left Join
order_delivery_analysis On order_header.oh_id =
order_delivery_analysis.oda_oh_id Left Join
order_line_analysis On order_line_item.oli_id = order_line_analysis.ola_oli_id
Left Join
order_line_product_analysis On order_line_item.oli_id =
order_line_product_analysis.olpa_oli_id Left Join
order_line_variant_analysis On order_line_item.oli_id =
order_line_variant_analysis.olva_oli_id Inner Join
product_detail On product_detail.pd_id = variant_detail.vad_pd_id Inner Join
delivery_method On delivery_method.dm_id = order_header_detail.ohd_dm_id
Inner Join
delivery_method [Delivery Method] On [Delivery Method].dm_id =
order_header_detail.ohd_dm_id Inner Join
currency On currency.c_id = order_header.oh_c_id And currency.c_id =
delivery_method.dm_c_id And currency.c_id = [Delivery Method].dm_c_id
Where
delivery_header.dh_number IN (199364,199363,199362,199360)
Order By delivery_header.dh_number
You can use GROUP BY with COUNT like this:
SELECT ID, COUNT(*) as count FROM tbl GROUP BY ID
What I understood from your question is that, you are looking for output like
Name Email Weight Price ID Pieces
Joe B J#.com 10 12.5. 1 2
Joe B J#.com 10 12.5. 1 2
Joe C JC#.com 10 14.5. 2 1
Using following query you should get the desired output in most of the DBMS.
SELECT NAME,
EMAIL,
WEIGHT,
PRICE,
ID,
(SELECT Count(*)
FROM <YOUR_TABLE_NAME>
WHERE ID= OU.ID) AS Pieces
FROM <YOUR_TABLE_NAME> OU
Similar Query for MS SQL Server can be
SELECT NAME, EMAIL,WEIGHT , Price, ID,CT.Pieces
FROM <YOUR_TABLE_NAME> OU
CROSS APPLY
(
SELECT COUNT(*) AS Pieces FROM <YOUR_TABLE_NAME> IU WHERE OU.ID=IU.ID
)CT
This question already has answers here:
Each GROUP BY expression must contain at least one column that is not an outer reference
(8 answers)
Closed 6 years ago.
I get this error
Each GROUP BY expression must contain at least one column that is not an outer reference
while running this query:
SELECT TOP 1
SUM(mla.total_current_attribute_value)
FROM
partstrack_machine_location_attributes mla (NOLOCK)
INNER JOIN
#tmpInstallParts_Temp installpartdetails ON mla.machine_sequence_id = installpartdetails.InstallKitToMachineSequenceId
AND (CASE WHEN mla.machine_side_id IS NULL THEN 1
WHEN mla.machine_side_id = installpartdetails.InstallKitToMachineSideId THEN 1 END
) = 1
INNER JOIN
partstrack_mes_attribute_mapping mam (NOLOCK) ON mla.mes_attribute = mam.mes_attribute_name
INNER JOIN
partstrack_attribute_type at (NOLOCK) ON mam.pt_attribute_id = at.pt_attribute_id
INNER JOIN
partstrack_ipp_mes_attributes ima(NOLOCK) ON at.pt_attribute_id = ima.pt_attribute_id
WHERE
mla.active_ind = 'Y' AND
ima.ipp_ID IN (SELECT ipp.ipp_id
FROM partstrack_individual_physical_part ipp
INNER JOIN #tmpInstallParts_Temp tmp ON (ipp.ipp_id = tmp.InstallingPartIPPId OR
(CASE WHEN tmp.InstallingPartIPKId = '-1' THEN 1 END) = 1
)
GROUP BY
ima.ipp_id
Can someone help me?
This is the text of the query from the first revision of the question.
In later revisions you removed the last closing bracket ) and the query became syntactically incorrect. You'd better check and fix the text of the question and format the text of the query, so it is readable.
SELECT TOP 1
SUM(mla.total_current_attribute_value)
FROM
partstrack_machine_location_attributes mla (NOLOCK)
INNER JOIN #tmpInstallParts_Temp installpartdetails
ON mla.machine_sequence_id = installpartdetails.InstallKitToMachineSequenceId
AND (CASE WHEN mla.machine_side_id IS NULL THEN 1
WHEN mla.machine_side_id = installpartdetails.InstallKitToMachineSideId THEN 1 END) = 1
INNER JOIN partstrack_mes_attribute_mapping mam (NOLOCK) ON mla.mes_attribute = mam.mes_attribute_name
INNER JOIN partstrack_attribute_type at (NOLOCK) ON mam.pt_attribute_id = at.pt_attribute_id
INNER JOIN partstrack_ipp_mes_attributes ima(NOLOCK) ON at.pt_attribute_id = ima.pt_attribute_id
WHERE
mla.active_ind = 'Y'
AND ima.ipp_ID IN
(
Select
ipp.ipp_id
FROM
partstrack_individual_physical_part ipp
INNER JOIN #tmpInstallParts_Temp tmp
ON (ipp.ipp_id = tmp.InstallingPartIPPId
OR (CASE WHEN tmp.InstallingPartIPKId = '-1' THEN 1 END) = 1)
GROUP BY
ima.ipp_id
)
With this formatting it is clear now that there is a subquery with GROUP BY.
Most likely it is just a typo: you meant to write GROUP BY ipp.ipp_id instead of GROUP BY ima.ipp_id.
If you really wanted to have the GROUP BY not in a subquery, but in the main SELECT, then you misplaced the closing bracket ) and the query should look like this:
SELECT TOP 1
SUM(mla.total_current_attribute_value)
FROM
partstrack_machine_location_attributes mla (NOLOCK)
INNER JOIN #tmpInstallParts_Temp installpartdetails
ON mla.machine_sequence_id = installpartdetails.InstallKitToMachineSequenceId
AND (CASE WHEN mla.machine_side_id IS NULL THEN 1
WHEN mla.machine_side_id = installpartdetails.InstallKitToMachineSideId THEN 1 END) = 1
INNER JOIN partstrack_mes_attribute_mapping mam (NOLOCK) ON mla.mes_attribute = mam.mes_attribute_name
INNER JOIN partstrack_attribute_type at (NOLOCK) ON mam.pt_attribute_id = at.pt_attribute_id
INNER JOIN partstrack_ipp_mes_attributes ima(NOLOCK) ON at.pt_attribute_id = ima.pt_attribute_id
WHERE
mla.active_ind = 'Y'
AND ima.ipp_ID IN
(
Select
ipp.ipp_id
FROM
partstrack_individual_physical_part ipp
INNER JOIN #tmpInstallParts_Temp tmp
ON (ipp.ipp_id = tmp.InstallingPartIPPId
OR (CASE WHEN tmp.InstallingPartIPKId = '-1' THEN 1 END) = 1)
)
GROUP BY
ima.ipp_id
In any case, proper formatting of the source code can really help.
Group By ima.ipp_id
should be applicable to outer query. Because of incorrect placement of '(' it was applying to inner query.
Now after correcting the query,it's working fine without any issues.
Final Query is :
SELECT TOP 1
SUM(mla.total_current_attribute_value)
FROM
partstrack_machine_location_attributes mla (NOLOCK)
INNER JOIN #tmpInstallParts_Temp installpartdetails
ON mla.machine_sequence_id = installpartdetails.InstallKitToMachineSequenceId
AND (CASE WHEN mla.machine_side_id IS NULL THEN 1
WHEN mla.machine_side_id = installpartdetails.InstallKitToMachineSideId THEN 1 END ) = 1
INNER JOIN partstrack_mes_attribute_mapping mam (NOLOCK) ON mla.mes_attribute = mam.mes_attribute_name
INNER JOIN partstrack_attribute_type at (NOLOCK) ON mam.pt_attribute_id = at.pt_attribute_id
INNER JOIN partstrack_ipp_mes_attributes ima(NOLOCK) ON at.pt_attribute_id = ima.pt_attribute_id
WHERE
mla.active_ind = 'Y'
AND ima.ipp_ID IN
(
Select
ipp.ipp_id
FROM
partstrack_individual_physical_part ipp
INNER JOIN #tmpInstallParts_Temp tmp
ON (ipp.ipp_id = tmp.InstallingPartIPPId
OR (CASE WHEN tmp.InstallingPartIPKId = '-1' THEN 1 END ) =1)
)
GROUP BY ima.ipp_id
Thank you all.
I am trying to compare a table to itself in SQL Server 2012. The table consists of among other columns Client Name, Client Number and Fiscal Year. Within the table there is data for FY15 and FY16 and clients can repeat multiple times.
I am trying to add a column to the table that will stipulate whether the client in each row is either "New" (exists in FY16 but not FY15), "Existing" (exists in FY16 and FY15), or "Lost" (exists in FY15 but not FY16).
I've tried joining the table to itself and using case statements but no luck.
You can do it using a LEFT JOIN:
SELECT c1.Name, c1.Number, c1.FiscalYear,
CASE
WHEN c1.FiscalYear = 2015 AND c2.FiscalYear = 2016 THEN 'Existing'
WHEN c1.FiscalYear = 2015 AND c2.FiscalYear IS NULL THEN 'Lost'
WHEN c1.FiscalYear = 2016 AND c2.FiscalYear = 2015 THEN 'Existing'
WHEN c1.FiscalYear = 2016 AND c2.FiscalYear IS NULL THEN 'New'
END AS category
FROM clients AS c1
LEFT JOIN clients AS c2
ON c1.Name = c2.Name AND
((c1.FiscalYear = 2015 AND c2.FiscalYear = 2016) OR
(c1.FiscalYear = 2016 AND c2.FiscalYear = 2015))
Demo here
If you just want to get category per client name, then you can use a GROUP BY:
SELECT Name,
CASE
WHEN COUNT(DISTINCT FiscalYear) = 2 THEN 'Existing'
WHEN SUM(FiscalYear = 2015) > 0 AND SUM(FiscalYear = 2016) = 0 THEN 'Lost'
WHEN SUM(FiscalYear = 2016) > 0 AND SUM(FiscalYear = 2015) = 0 THEN 'New'
END AS category
FROM clients
WHERE FiscalYear IN (2015, 2016)
GROUP BY Name
Demo here
You also can use the above query to perform an UPDATE:
UPDATE clients
INNER JOIN (
SELECT Name,
CASE
WHEN COUNT(DISTINCT FiscalYear) = 2 THEN 'Existing'
WHEN SUM(FiscalYear = 2015) > 0 AND SUM(FiscalYear = 2016) = 0 THEN 'Lost'
WHEN SUM(FiscalYear = 2016) > 0 AND SUM(FiscalYear = 2015) = 0 THEN 'New'
END AS category
FROM clients
WHERE FiscalYear IN (2015, 2016)
GROUP BY Name
) AS t ON clients.name = t.name
SET clients.category = t.category
Demo here
Version with update:
update customer
set status = case when
(select count(*) from customer C2 where C2. ClientName = customer.ClientName and C2.Year in (2015,2016) ) = 2 then 'Existing'
when
(select count(*) from customer C2 where C2.clientName = customer.ClientName and C2.Year = 2015 ) = 1 then 'Lost'
when
(select count(*) from customer C2 where C2.clientName = customer.ClientName and C2.Year in (2016) ) = 1 then 'New'
end;
Sample in SQL Fiddle here
This question already has answers here:
Convert Rows to columns using 'Pivot' in SQL Server
(9 answers)
Closed 7 years ago.
My query:
select (sum( c20 ))as total , año
FROM(
select distinct datepart(year,DATEADD(DAY,CONVERT(FLOAT(10),KDUD.C16),A1.C7))as año, (a1.c20) as c20
from
KDUE A1
LEFT JOIN KDMM ON KDMM.C1='U' AND A1.C3=KDMM.C2 AND A1.C4=KDMM.C3 AND A1.C5=KDMM.C4
LEFT JOIN KDMS ON A1.C1=KDMS.C1
LEFT JOIN KDUD ON A1.C2=KDUD.C2
LEFT JOIN KDUV ON A1.C18=KDUV.C2
where a1.c20 != 0) as aas
group by año
this gives this table as a result:
total año
--------------------------------------- -----------
409782.45 2013
2442993.24 2014
10810460.01 2015
but i wish i could get the years as headers and the totals as a single row... help :c
with x as
(select (sum( c20 ))as total , año
FROM(
select distinct datepart(year,DATEADD(DAY,CONVERT(FLOAT(10),KDUD.C16),A1.C7))as año, (a1.c20) as c20
from
KDUE A1
LEFT JOIN KDMM ON KDMM.C1='U' AND A1.C3=KDMM.C2 AND A1.C4=KDMM.C3 AND A1.C5=KDMM.C4
LEFT JOIN KDMS ON A1.C1=KDMS.C1
LEFT JOIN KDUD ON A1.C2=KDUD.C2
LEFT JOIN KDUV ON A1.C18=KDUV.C2
where a1.c20 != 0) as aas
group by año)
select case when ano = '2013' then total end as '2013',
case when ano = '2014' then total end as '2014',
case when ano = '2015' then total end as '2015'
from x
This is one way to do it but will be more manual as you have more than a handful of values in ano column.
I wrote the this T-SQL query:
SELECT
B.[Year], E.[Description] as GLClass,
D.Code, D.[GLDescription],
SUM(A.Jan) AS Jan,
SUM(A.Feb) AS Feb,
SUM(A.Mar) AS Mar,
SUM(A.Apr) AS Apr
FROM
GeneralLedgers A
INNER JOIN
Years B ON A.YearID = B.ID
INNER JOIN
CostCenters C ON A.CostCenterID = C.ID
INNER JOIN
GLCodes D ON A.GLCodeID = D.ID
INNER JOIN
GLClassificationTypes E ON D.GLClassificationTypeID = E.ID
WHERE
A.YearID = '13'
GROPU BY
B.[Year], D.Code, E.[Description], D.[GLDescription]
ORDER BY
D.Code, E.[Description]
It outputs this result:
I want to combine "Freight-in (Go) and Freight Savings" row into a single row and sum the value from column Jan, Feb, Mar, Apr. I was trying to used the Case When clause on the "Code" column to look for '401040110' and '441010300' but still can't figure it out.
How can this be accomplish?
Convert one of the 2 rows into the other for your groupings logic and the rest of the aggregation should work on top of that seamlessly.
SELECT B.[Year]
,E.[Description] AS GLClass
,case when D.Code = '441010300' then '401040110' else D.Code END Code
,case when D.Code = '441010300' then 'Freight-in (Go)' else D.[GLDescription] end [GLDescription]
,Sum(A.Jan) AS Jan
,Sum(A.Feb) AS Feb
,Sum(A.Mar) AS Mar
,Sum(A.Apr) AS Apr
FROM GeneralLedgers A
INNER JOIN Years B ON A.YearID = B.ID
INNER JOIN CostCenters C ON A.CostCenterID = C.ID
INNER JOIN GLCodes D ON A.GLCodeID = D.ID
INNER JOIN GLClassificationTypes E ON D.GLClassificationTypeID = E.ID
WHERE A.YearID = '13'
GROUP BY B.[Year]
, case when D.Code = '441010300' then '401040110' else D.Code END
, E.[Description]
, case when D.Code = '441010300' then 'Freight-in (Go)' else D.[GLDescription] end
ORDER BY 3,2