Erroneous SUM when using JOIN on SQL request - sql

Hi i have two tables with a lot of data. I have to get some data of both tables. to do this i use an inner join. But when i use SUM i get wrong result. i know that the result is multiplied as many rows returned. How can i get arround this ?
The request :
select SUM(CASE WHEN det.IdGarantie != 18 AND det.IdGarantie != 17 AND det.IdGarantie!= 11 THEN det.Q_PrimeNette ELSE 0 END) AS 'cot nette',
SUM(CASE WHEN det.IdGarantie = 18 THEN det.Q_PrimeNette ELSE 0 END) AS 'Fond comp',
SUM(CASE WHEN det.IdGarantie = 11 THEN det.Q_PrimeNette ELSE 0 END) AS 'Carte Verte',
SUM(CASE WHEN det.IdGarantie = 17 THEN det.Q_PrimeNette ELSE 0 END) AS 'Adhesion',
SUM(CASE WHEN det.IdGarantie != 18 AND det.IdGarantie != 17 AND det.IdGarantie!= 11 THEN det.Q_Taxe ELSE 0 END) AS 'Taxe',
SUM(CASE WHEN det.IdGarantie = 18 THEN det.Q_Taxe ELSE 0 END) AS 'Taxe Fond Comp',
SUM(CASE WHEN det.IdGarantie = 17 THEN det.Q_Taxe ELSE 0 END) AS 'Taxe Adhésion',
SUM(CASE WHEN det.IdGarantie = 11 THEN det.Q_Taxe ELSE 0 END) AS 'Taxe carte verte',
SUM(hst.Q_Access) as 'Access'
from OtoHistorique hst
inner Join OtoHistoriqueDet det On det.IdHistorique = hst.IdHistorique
where hst.POLICE = 3221086
i get 60 in Access column when the expected result is 20
Anyone can help me with this ? Sorry if i use bad syntax in my request but i'm just a beginner in SQL and for the moment the result is more important than the syntax.

You probably have one-to-many relationship between the tables, which means some of the values for SUM get duplicated.
You can go around this by avoiding the join like this:
select SUM(CASE WHEN det.IdGarantie != 18 AND det.IdGarantie != 17 AND det.IdGarantie!= 11 THEN det.Q_PrimeNette ELSE 0 END) AS 'cot nette',
SUM(CASE WHEN det.IdGarantie = 18 THEN det.Q_PrimeNette ELSE 0 END) AS 'Fond comp',
SUM(CASE WHEN det.IdGarantie = 11 THEN det.Q_PrimeNette ELSE 0 END) AS 'Carte Verte',
SUM(CASE WHEN det.IdGarantie = 17 THEN det.Q_PrimeNette ELSE 0 END) AS 'Adhesion',
SUM(CASE WHEN det.IdGarantie != 18 AND det.IdGarantie != 17 AND det.IdGarantie!= 11 THEN det.Q_Taxe ELSE 0 END) AS 'Taxe',
SUM(CASE WHEN det.IdGarantie = 18 THEN det.Q_Taxe ELSE 0 END) AS 'Taxe Fond Comp',
SUM(CASE WHEN det.IdGarantie = 17 THEN det.Q_Taxe ELSE 0 END) AS 'Taxe Adhésion',
SUM(CASE WHEN det.IdGarantie = 11 THEN det.Q_Taxe ELSE 0 END) AS 'Taxe carte verte',
(SELECT SUM(hst.Q_Access)
FROM OtoHistorique hst
WHERE det.IdHistorique = hst.IdHistorique) as 'Access'
FROM OtoHistoriqueDet det
WHERE EXISTS (SELECT 1
FROM OtoHistorique hst2
WHERE hst2.POLICE = 3221086
AND hst2.IdHistorique = det.IdHistorique)
This could probably be more optimized but we'd need more info on the logic between the two tables.

One approach is to do the aggregation before the join:
select det.*,
SUM(hst.Q_Access) as "Access"
from OtoHistorique hst inner Join
(select det.IdHistoric,
SUM(CASE WHEN det.IdGarantie != 18 AND det.IdGarantie != 17 AND det.IdGarantie!= 11 THEN det.Q_PrimeNette ELSE 0 END) as "cot nette"
SUM(CASE WHEN det.IdGarantie = 18 THEN det.Q_PrimeNette ELSE 0 END) AS "Fond comp",
SUM(CASE WHEN det.IdGarantie = 11 THEN det.Q_PrimeNette ELSE 0 END) AS "Carte Verte",
SUM(CASE WHEN det.IdGarantie = 17 THEN det.Q_PrimeNette ELSE 0 END) AS "Adhesion",
SUM(CASE WHEN det.IdGarantie != 18 AND det.IdGarantie != 17 AND det.IdGarantie!= 11 THEN det.Q_Taxe ELSE 0 END) AS "Taxe",
SUM(CASE WHEN det.IdGarantie = 18 THEN det.Q_Taxe ELSE 0 END) AS "Taxe Fond Comp",
SUM(CASE WHEN det.IdGarantie = 17 THEN det.Q_Taxe ELSE 0 END) AS "Taxe Adhésion",
SUM(CASE WHEN det.IdGarantie = 11 THEN det.Q_Taxe ELSE 0 END) AS "Taxe carte verte",
SUM(hst.Q_Access) as "Access"
from OtoHistoriqueDet det
group by det.IdHistorique
) det
On det.IdHistorique = hst.IdHistorique
where hst.POLICE = 3221086;
Because you are filtering the query, this might be expensive. The entire details table has to be aggregated. So, you can do the join in the subquery for filtering purposes and then again for the calculation:
select det.*,
SUM(hst.Q_Access) as "Access"
from OtoHistorique hst inner Join
(select det.IdHistoric,
SUM(CASE WHEN det.IdGarantie != 18 AND det.IdGarantie != 17 AND det.IdGarantie!= 11 THEN det.Q_PrimeNette ELSE 0 END) as "cot nette"
SUM(CASE WHEN det.IdGarantie = 18 THEN det.Q_PrimeNette ELSE 0 END) AS "Fond comp",
SUM(CASE WHEN det.IdGarantie = 11 THEN det.Q_PrimeNette ELSE 0 END) AS "Carte Verte",
SUM(CASE WHEN det.IdGarantie = 17 THEN det.Q_PrimeNette ELSE 0 END) AS "Adhesion",
SUM(CASE WHEN det.IdGarantie != 18 AND det.IdGarantie != 17 AND det.IdGarantie!= 11 THEN det.Q_Taxe ELSE 0 END) AS "Taxe",
SUM(CASE WHEN det.IdGarantie = 18 THEN det.Q_Taxe ELSE 0 END) AS "Taxe Fond Comp",
SUM(CASE WHEN det.IdGarantie = 17 THEN det.Q_Taxe ELSE 0 END) AS "Taxe Adhésion",
SUM(CASE WHEN det.IdGarantie = 11 THEN det.Q_Taxe ELSE 0 END) AS "Taxe carte verte"
from OtoHistoriqueDet det join
OtoHistorique hst
On det.IdHistorique = hst.IdHistorique and hst.POLICE = 3221086
group by det.IdHistorique
) det
On det.IdHistorique = hst.IdHistorique
where hst.POLICE = 3221086;

Related

How can I avoid using "SET DATEFIRST 1" instruction?

I need to use the "DirectQuery" function on PowerBI Desktop.
When i try to load the data PBI stops the process because of the "SET DATEFIRST 1" instruction at the beginning of the query.
That happens because PBI elaborates the request like 'SELECT * FROM (Myquery)' and that throws a syntax error near "SET".
I'm asking you if there is a way that allows me to set Monday as the first day of the week without using the "SET DATEFIRST 1" instruction.
Here it is the query i'm talking about:
SET DATEFIRST 1;
SELECT SUM(Tabella2.DC20) AS DC20,
SUM(Tabella2.OT20) AS OT20,
SUM(Tabella2.FR20) AS FR20,
SUM(Tabella2.RF20) AS RF20,
SUM(Tabella2.DC40) AS DC40,
SUM(Tabella2.OT40) AS OT40,
SUM(Tabella2.FR40) AS FR40,
SUM(Tabella2.RH40) AS RH40,
SUM(Tabella2.HC40) AS HC40,
SUM(Tabella2.HP40) AS HW40,
SUM(Tabella2.HC45) AS HC45,
SUM(Tabella2.HP45) AS HP45,
SUM(Tabella2.Altri) AS Altri,
Tabella2.YEAR,
Tabella2.month
FROM (SELECT SUM(CASE GET.Abbreviation WHEN '20DV' THEN 1 ELSE 0 END) AS DC20,
SUM(CASE GET.Abbreviation WHEN '20OT' THEN 1 ELSE 0 END) AS OT20,
SUM(CASE GET.Abbreviation WHEN '20FL' THEN 1 ELSE 0 END) AS FR20,
SUM(CASE GET.Abbreviation WHEN '20RE' THEN 1 ELSE 0 END) AS RF20,
SUM(CASE GET.Abbreviation WHEN '40DV' THEN 1 ELSE 0 END) AS DC40,
SUM(CASE GET.Abbreviation WHEN '40OT' THEN 1 ELSE 0 END) AS OT40,
SUM(CASE GET.Abbreviation WHEN '40FL' THEN 1 ELSE 0 END) AS FR40,
SUM(CASE GET.Abbreviation WHEN '40HR' THEN 1 ELSE 0 END) AS RH40,
SUM(CASE GET.Abbreviation WHEN '40HC' THEN 1 ELSE 0 END) AS HC40,
SUM(CASE GET.Abbreviation WHEN '40HP' THEN 1 ELSE 0 END) AS HP40,
SUM(CASE GET.Abbreviation WHEN '45HC' THEN 1 ELSE 0 END) AS HC45,
SUM(CASE GET.Abbreviation WHEN '45HP' THEN 1 ELSE 0 END) AS HP45,
SUM(CASE
WHEN GET.Abbreviation != '20DV'
AND GET.Abbreviation != '20OT'
AND GET.Abbreviation != '20FL'
AND GET.Abbreviation != '20RE'
AND GET.Abbreviation != '40DV'
AND GET.Abbreviation != '40OT'
AND GET.Abbreviation != '40FL'
AND GET.Abbreviation != '40HR'
AND GET.Abbreviation != '40HC'
AND GET.Abbreviation != '40HP'
AND GET.Abbreviation != '45HC'
AND GET.Abbreviation != '45HP' THEN 1
ELSE 0
END) AS Altri,
GV.Vessel_Name,
GVPC.Import_Documentation_Voyage_Number,
GVPC.Actual_Arrival_Time,
DATEPART(MONTH, GVPC.Actual_Arrival_Time) AS month,
DATEPART(YEAR, GVPC.Actual_Arrival_Time) AS YEAR
FROM [My_DB].[dbo].[GISEquipment] GE,
[Interlink_Main90].[dbo].[GISEquipment_Type] GET,
[Interlink_Main90].[dbo].[Equipment_Cycle] EC,
[Interlink_Main90].[dbo].[Equipment_Cycle_Type] ECT,
[Interlink_Main90].[dbo].[Equipment_Event] EE,
[Interlink_Main90].[dbo].[Equipment_Event_Type] EET,
[Interlink_Main90].[dbo].[GISLocation] GL,
[Interlink_Main90].[dbo].[GISPort] GP,
[Interlink_Main90].[dbo].[GISVoyage] GV,
[Interlink_Main90].[dbo].GISVoyage_Port_Call GVPC,
[Interlink_Main90].[dbo].GISVessel GVE
WHERE GE.Equipment_Type_id = GET.Equipment_Type_id
AND GE.Equipment_id = EC.Equipment_id
AND EC.Eq_Cycle_Type_id = ECT.Eq_Cycle_Type_id
AND EC.Eq_Cycle_id = EE.EQ_Cycle_id
AND EE.EQEV_Type_id = EET.EqEv_Type_id
AND EE.Location_id = GL.Location_id
AND EC.POD_id = GP.Port_id
AND EET.Name IN ('IDV')
AND GL.Global_Name = 'Leghorn'
AND GP.Global_Name = 'Leghorn'
AND EE.[Logical_Cancel] = '0'
AND GVPC.Voyage_Port_Call_id = EC.Voyage_Port_Call_id
AND GV.Vessel_id = GVE.Vessel_id
AND GVPC.Voyage_id = GV.Voyage_id
AND GVPC.Port_id = GP.Port_id
AND GV.Logical_Cancel_Value = 0
AND GVPC.Logical_Cancel_Value = 0
AND GVE.Logical_Cancel_Value = 0
AND GVPC.Import_Documentation_Voyage_Number IS NOT NULL
AND GVPC.Actual_Arrival_Time IS NOT NULL
GROUP BY GV.Vessel_Name,
GVPC.Import_Documentation_Voyage_Number,
GVPC.Actual_Arrival_Time) Tabella2
WHERE YEAR = '2022'
GROUP BY Tabella2.YEAR,
Tabella2.month
ORDER BY YEAR DESC,
month;
SET DATEFIRST 7;
Thanks in advance for the help.

Sum of Values ​of the Same Column in SQL

I need to show the sum of a column, like:
How can I create a sum of the "LQ's", for exemple:
0+0+38+1010+216+664
My code:
select pla.DSC_ACO,
sum(case when res.cod_ordem_producao like 'LQX%' then 1 else 0 end) as lqx,
sum(case when res.cod_ordem_producao like 'LQP%' then 1 else 0 end) as lqp,
sum(case when res.cod_ordem_producao like 'LQT%' then 1 else 0 end) as LQT,
sum(case when res.cod_ordem_producao like 'LQRT%' then 1 else 0 end) as lqrt,
sum(case when res.cod_ordem_producao like 'LQRZ%' then 1 else 0 end) as lqrz,
sum(case when res.cod_ordem_producao like 'LQZ%' then 1 else 0 end) as LQZ,
sum(case when res.cod_ordem_producao like 'LQRW%' then 1 else 0 end) as lqrw,
sum(case when res.cod_ordem_producao like 'LQW%' then 1 else 0 end) as LQW,
sum(case when res.cod_ordem_producao like 'LQ%' then 1 else 0 end) as Lq,
sum(case when res.cod_ordem_producao like 'LQR%' then 1 else 0 end) as LQR
from QT_QTS.RES_TUBO_REVENIMENTO2 res, QT_QTS.PLA_ORDEM_PRODUCAO pla
where res.COD_ORDEM_PRODUCAO = pla.COD_ORDEM_PRODUCAO
and res.DTH_CRIACAO_REG >= :dthini
and res.DTH_CRIACAO_REG <=:dthfim
group by pla.DSC_ACO
I hope it works :)
select pla.DSC_ACO,
sum(case when res.cod_ordem_producao like 'LQX%' then 1 else 0 end) as lqx,
sum(case when res.cod_ordem_producao like 'LQP%' then 1 else 0 end) as lqp,
sum(case when res.cod_ordem_producao like 'LQT%' then 1 else 0 end) as LQT,
sum(case when res.cod_ordem_producao like 'LQRT%' then 1 else 0 end) as lqrt,
sum(case when res.cod_ordem_producao like 'LQRZ%' then 1 else 0 end) as lqrz,
sum(case when res.cod_ordem_producao like 'LQZ%' then 1 else 0 end) as LQZ,
sum(case when res.cod_ordem_producao like 'LQRW%' then 1 else 0 end) as lqrw,
sum(case when res.cod_ordem_producao like 'LQW%' then 1 else 0 end) as LQW,
sum(case when res.cod_ordem_producao like 'LQ%' then 1 else 0 end) as Lq,
sum(case when res.cod_ordem_producao like 'LQR%' then 1 else 0 end) as LQR
from QT_QTS.RES_TUBO_REVENIMENTO2 res, QT_QTS.PLA_ORDEM_PRODUCAO pla
where res.COD_ORDEM_PRODUCAO = pla.COD_ORDEM_PRODUCAO
and res.DTH_CRIACAO_REG >= :dthini
and res.DTH_CRIACAO_REG <=:dthfim
group by pla.DSC_ACO
UNION ALL
SELECT
'TOTAL' DSC,
SUM(lqx),
SUM(lqp),
SUM(LQT),
SUM(lqrt),
SUM(qrz),
SUM(LQZ),
SUM(lqrw),
SUM(LQW),
SUM(Lq),
SUM(LQR)
FROM (select pla.DSC_ACO,
sum(case when res.cod_ordem_producao like 'LQX%' then 1 else 0 end) as lqx,
sum(case when res.cod_ordem_producao like 'LQP%' then 1 else 0 end) as lqp,
sum(case when res.cod_ordem_producao like 'LQT%' then 1 else 0 end) as LQT,
sum(case when res.cod_ordem_producao like 'LQRT%' then 1 else 0 end) as lqrt,
sum(case when res.cod_ordem_producao like 'LQRZ%' then 1 else 0 end) as lqrz,
sum(case when res.cod_ordem_producao like 'LQZ%' then 1 else 0 end) as LQZ,
sum(case when res.cod_ordem_producao like 'LQRW%' then 1 else 0 end) as lqrw,
sum(case when res.cod_ordem_producao like 'LQW%' then 1 else 0 end) as LQW,
sum(case when res.cod_ordem_producao like 'LQ%' then 1 else 0 end) as Lq,
sum(case when res.cod_ordem_producao like 'LQR%' then 1 else 0 end) as LQR
from QT_QTS.RES_TUBO_REVENIMENTO2 res, QT_QTS.PLA_ORDEM_PRODUCAO pla
where res.COD_ORDEM_PRODUCAO = pla.COD_ORDEM_PRODUCAO
and res.DTH_CRIACAO_REG >= :dthini
and res.DTH_CRIACAO_REG <=:dthfim
group by pla.DSC_ACO)
You may use a simple query like this to obtain the result for LQR% predicate that you request in your question
select count(*) as LQR
from QT_QTS.RES_TUBO_REVENIMENTO2 res
join QT_QTS.PLA_ORDEM_PRODUCAO pla on res.COD_ORDEM_PRODUCAO = pla.COD_ORDEM_PRODUCAO
where res.DTH_CRIACAO_REG >= :dthini
and res.DTH_CRIACAO_REG <=:dthfim
and res.cod_ordem_producao like 'LQR%'
select sum(lqx), sum(lqp), sum(lqt), sum(lqrt), sum(lqrz), sum(lqz), sum(lqrw),
sum(lqw), sum(lq)
, sum(lqr) from
(select pla.DSC_ACO,
sum(case when res.cod_ordem_producao like 'LQX%' then 1 else 0 end) as lqx,
sum(case when res.cod_ordem_producao like 'LQP%' then 1 else 0 end) as lqp,
sum(case when res.cod_ordem_producao like 'LQT%' then 1 else 0 end) as LQT,
sum(case when res.cod_ordem_producao like 'LQRT%' then 1 else 0 end) as lqrt,
sum(case when res.cod_ordem_producao like 'LQRZ%' then 1 else 0 end) as lqrz,
sum(case when res.cod_ordem_producao like 'LQZ%' then 1 else 0 end) as LQZ,
sum(case when res.cod_ordem_producao like 'LQRW%' then 1 else 0 end) as lqrw,
sum(case when res.cod_ordem_producao like 'LQW%' then 1 else 0 end) as LQW,
sum(case when res.cod_ordem_producao like 'LQ%' then 1 else 0 end) as Lq,
sum(case when res.cod_ordem_producao like 'LQR%' then 1 else 0 end) as LQR
from QT_QTS.RES_TUBO_REVENIMENTO2 res, QT_QTS.PLA_ORDEM_PRODUCAO pla
where res.COD_ORDEM_PRODUCAO = pla.COD_ORDEM_PRODUCAO
and res.DTH_CRIACAO_REG >= :dthini
and res.DTH_CRIACAO_REG <=:dthfim
group by pla.DSC_ACO) as values
Use a Common Table Expression to organize the data you want, then just select from it with a simple summation. The CTE in the WITH clause will allow you to select from that just like it were a normal table.
WITH temp_table AS (
select pla.DSC_ACO,
case when res.cod_ordem_producao like 'LQX%' then 1 else 0 end as LQX,
case when res.cod_ordem_producao like 'LQP%' then 1 else 0 end as LQP,
case when res.cod_ordem_producao like 'LQT%' then 1 else 0 end as LQT,
case when res.cod_ordem_producao like 'LQRT%' then 1 else 0 end as LQRT,
case when res.cod_ordem_producao like 'LQRZ%' then 1 else 0 end as LQRZ,
case when res.cod_ordem_producao like 'LQZ%' then 1 else 0 end as LQZ,
case when res.cod_ordem_producao like 'LQRW%' then 1 else 0 end as LQRW,
case when res.cod_ordem_producao like 'LQW%' then 1 else 0 end as LQW,
case when res.cod_ordem_producao like 'LQR%' then 1 else 0 end as LQR,
case when res.cod_ordem_producao like 'LQ%' then 1 else 0 end as LQ
from QT_QTS.RES_TUBO_REVENIMENTO2 res, QT_QTS.PLA_ORDEM_PRODUCAO pla
where res.COD_ORDEM_PRODUCAO = pla.COD_ORDEM_PRODUCAO
and res.DTH_CRIACAO_REG >= :dthini
and res.DTH_CRIACAO_REG <= :dthfim)
SELECT SUM(LQ) AS LQ_SUM FROM temp_table
You didn't specify the final format you needed the query in, but your question only asked how do you get the sum of that column. If you need to expand the logic to include other aggregations, you should be able to see how to add more fields to the final SELECT statement there.
Also, you should note that you are going to be double counting some data. For example, LQR will also be counting the same values as in LQRT, LQRZ, and LQRW. And, the LQ will count the same things as all of the fields. This might be the behavior you want, but if you want a unique bin for each value to fall in, you are going to need to do some more logic manipulation to it first.

Pivot Data in SQL

I have the below which gives me SalesExVAT, by BranchNo and by FiscalWeek
there is only 1 record per branch for each week:
Select
sa.BranchNo
,sa.FiscalWeek
,sa.SalesExVAT
From
dbo.SalesAggregateWeek sa
Where
sa.FiscalYear = 2016
I wanted to display this in a Pivoted Format
I have tried the below,
Select
MyData.BranchNo
From
(Select
sa.BranchNo
,sa.FiscalWeek
,sa.SalesExVAT
From
dbo.SalesAggregateWeek sa
Where
sa.FiscalYear = 2016) MyData
Pivot
( sum(MyData.salesexvat)
For
MyData.FiscalWeek In (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26
,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52) )
The desired out come would have the FiscalWeek as the headers along the top, the BranchNo displayed down the left, and SalesExVAT info as the data.
Any ideas on what I must do to correct my code are welcome as I've not used PIVOT yet.
Final Query Looks Like:
Select *
From
(Select
sa.BranchNo
,sa.FiscalWeek
,sa.SalesExVAT
From
dbo.SalesAggregateWeek sa
Where
sa.FiscalYear = 2016) P
Pivot
(Sum (SalesExVAT)
For FiscalWeek In
( [1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12],[13],[14],[15],[16],[17],
[18],[19],[20],[21],[22],[23],[24],[25],[26],[27],[28],[29],[30],[31],[32],
[33],[34],[35],[36],[37],[38],[39],[40],[41],[42],[43],[44],[45],[46],[47],
[48],[49],[50],[51],[52] )
) As pvt ;
Key points:
The FiscalWeek Values all had to be in [Square Brackets]
The Pivot had to use an alias 'As pvt' and be finished with ;
If anyone knows a way I could have wrote FiscalWeek Between 1 And 52 rather than state all the weeks please comment your answer.
Here an option using a dynamic cross tab pivot...
DECLARE
#WeekColumns VARCHAR(8000) = '',
#sql VARCHAR(8000) = '',
#DeBug BIT = 1; -- change to 0 to execute & 1 to print.
SELECT TOP 52
#WeekColumns = CONCAT(#WeekColumns, ',
[',t.n, '] = SUM(CASE WHEN sa.FiscalWeek = ', t.n, ' THEN sa.SalesExVAT ELSE 0 END)')
FROM
dbo.tfn_Tally(52, 1) t;
SET #sql = CONCAT('
SELECT
sa.BranchNo',
#WeekColumns, '
FROM
dbo.SalesAggregateWeek sa
WHERE
sa.FiscalYear = 2016;')
IF #DeBug = 1
BEGIN
PRINT(#sql);
END;
ELSE
BEGIN
EXEC(#sql);
END;
The print output...
SELECT
sa.BranchNo,
[1] = SUM(CASE WHEN sa.FiscalWeek = 1 THEN sa.SalesExVAT ELSE 0 END),
[2] = SUM(CASE WHEN sa.FiscalWeek = 2 THEN sa.SalesExVAT ELSE 0 END),
[3] = SUM(CASE WHEN sa.FiscalWeek = 3 THEN sa.SalesExVAT ELSE 0 END),
[4] = SUM(CASE WHEN sa.FiscalWeek = 4 THEN sa.SalesExVAT ELSE 0 END),
[5] = SUM(CASE WHEN sa.FiscalWeek = 5 THEN sa.SalesExVAT ELSE 0 END),
[6] = SUM(CASE WHEN sa.FiscalWeek = 6 THEN sa.SalesExVAT ELSE 0 END),
[7] = SUM(CASE WHEN sa.FiscalWeek = 7 THEN sa.SalesExVAT ELSE 0 END),
[8] = SUM(CASE WHEN sa.FiscalWeek = 8 THEN sa.SalesExVAT ELSE 0 END),
[9] = SUM(CASE WHEN sa.FiscalWeek = 9 THEN sa.SalesExVAT ELSE 0 END),
[10] = SUM(CASE WHEN sa.FiscalWeek = 10 THEN sa.SalesExVAT ELSE 0 END),
[11] = SUM(CASE WHEN sa.FiscalWeek = 11 THEN sa.SalesExVAT ELSE 0 END),
[12] = SUM(CASE WHEN sa.FiscalWeek = 12 THEN sa.SalesExVAT ELSE 0 END),
[13] = SUM(CASE WHEN sa.FiscalWeek = 13 THEN sa.SalesExVAT ELSE 0 END),
[14] = SUM(CASE WHEN sa.FiscalWeek = 14 THEN sa.SalesExVAT ELSE 0 END),
[15] = SUM(CASE WHEN sa.FiscalWeek = 15 THEN sa.SalesExVAT ELSE 0 END),
[16] = SUM(CASE WHEN sa.FiscalWeek = 16 THEN sa.SalesExVAT ELSE 0 END),
[17] = SUM(CASE WHEN sa.FiscalWeek = 17 THEN sa.SalesExVAT ELSE 0 END),
[18] = SUM(CASE WHEN sa.FiscalWeek = 18 THEN sa.SalesExVAT ELSE 0 END),
[19] = SUM(CASE WHEN sa.FiscalWeek = 19 THEN sa.SalesExVAT ELSE 0 END),
[20] = SUM(CASE WHEN sa.FiscalWeek = 20 THEN sa.SalesExVAT ELSE 0 END),
[21] = SUM(CASE WHEN sa.FiscalWeek = 21 THEN sa.SalesExVAT ELSE 0 END),
[22] = SUM(CASE WHEN sa.FiscalWeek = 22 THEN sa.SalesExVAT ELSE 0 END),
[23] = SUM(CASE WHEN sa.FiscalWeek = 23 THEN sa.SalesExVAT ELSE 0 END),
[24] = SUM(CASE WHEN sa.FiscalWeek = 24 THEN sa.SalesExVAT ELSE 0 END),
[25] = SUM(CASE WHEN sa.FiscalWeek = 25 THEN sa.SalesExVAT ELSE 0 END),
[26] = SUM(CASE WHEN sa.FiscalWeek = 26 THEN sa.SalesExVAT ELSE 0 END),
[27] = SUM(CASE WHEN sa.FiscalWeek = 27 THEN sa.SalesExVAT ELSE 0 END),
[28] = SUM(CASE WHEN sa.FiscalWeek = 28 THEN sa.SalesExVAT ELSE 0 END),
[29] = SUM(CASE WHEN sa.FiscalWeek = 29 THEN sa.SalesExVAT ELSE 0 END),
[30] = SUM(CASE WHEN sa.FiscalWeek = 30 THEN sa.SalesExVAT ELSE 0 END),
[31] = SUM(CASE WHEN sa.FiscalWeek = 31 THEN sa.SalesExVAT ELSE 0 END),
[32] = SUM(CASE WHEN sa.FiscalWeek = 32 THEN sa.SalesExVAT ELSE 0 END),
[33] = SUM(CASE WHEN sa.FiscalWeek = 33 THEN sa.SalesExVAT ELSE 0 END),
[34] = SUM(CASE WHEN sa.FiscalWeek = 34 THEN sa.SalesExVAT ELSE 0 END),
[35] = SUM(CASE WHEN sa.FiscalWeek = 35 THEN sa.SalesExVAT ELSE 0 END),
[36] = SUM(CASE WHEN sa.FiscalWeek = 36 THEN sa.SalesExVAT ELSE 0 END),
[37] = SUM(CASE WHEN sa.FiscalWeek = 37 THEN sa.SalesExVAT ELSE 0 END),
[38] = SUM(CASE WHEN sa.FiscalWeek = 38 THEN sa.SalesExVAT ELSE 0 END),
[39] = SUM(CASE WHEN sa.FiscalWeek = 39 THEN sa.SalesExVAT ELSE 0 END),
[40] = SUM(CASE WHEN sa.FiscalWeek = 40 THEN sa.SalesExVAT ELSE 0 END),
[41] = SUM(CASE WHEN sa.FiscalWeek = 41 THEN sa.SalesExVAT ELSE 0 END),
[42] = SUM(CASE WHEN sa.FiscalWeek = 42 THEN sa.SalesExVAT ELSE 0 END),
[43] = SUM(CASE WHEN sa.FiscalWeek = 43 THEN sa.SalesExVAT ELSE 0 END),
[44] = SUM(CASE WHEN sa.FiscalWeek = 44 THEN sa.SalesExVAT ELSE 0 END),
[45] = SUM(CASE WHEN sa.FiscalWeek = 45 THEN sa.SalesExVAT ELSE 0 END),
[46] = SUM(CASE WHEN sa.FiscalWeek = 46 THEN sa.SalesExVAT ELSE 0 END),
[47] = SUM(CASE WHEN sa.FiscalWeek = 47 THEN sa.SalesExVAT ELSE 0 END),
[48] = SUM(CASE WHEN sa.FiscalWeek = 48 THEN sa.SalesExVAT ELSE 0 END),
[49] = SUM(CASE WHEN sa.FiscalWeek = 49 THEN sa.SalesExVAT ELSE 0 END),
[50] = SUM(CASE WHEN sa.FiscalWeek = 50 THEN sa.SalesExVAT ELSE 0 END),
[51] = SUM(CASE WHEN sa.FiscalWeek = 51 THEN sa.SalesExVAT ELSE 0 END),
[52] = SUM(CASE WHEN sa.FiscalWeek = 52 THEN sa.SalesExVAT ELSE 0 END)
FROM
dbo.SalesAggregateWeek sa
WHERE
sa.FiscalYear = 2016;

SQL query is taking more than 10 minutes

The following query is taking too much time (more than 10 minutes). Is there a way to make it faster?
select r.id,rs1.Id, rs2.Id
from Resource rs1 , Resource rs2 , ResourceTerritory rst1 ,
ResourceTerritory rst2 ,
ReleaseResource rr1 ,
ReleaseResource rr2 , Release r
where
rs1.Id=rst1.ResourceId and rs2.Id=rst2.ResourceId and rs1.Id=rr1.ResourceId and rs2.Id=rr2.ResourceId
and rr1.ReleaseId=rr2.ReleaseId
and rs1.Id<>rs2.id
and rs1.OwningTerritoryId=69 and rs2.OwningTerritoryId=200
and r.Id=rr1.ReleaseId and r.OwningTerritoryId=69 and rs1.IsLocked=0 and rs2.IsLocked=0
group by r.id,rs1.Id, rs2.Id
having SUM( case when rst1.TerritoryId = 62 then 1 else 0 end)>0 and
SUM( case when rst1.TerritoryId = 69 then 1 else 0 end)>0 and
SUM( case when rst1.TerritoryId = 200 then 1 else 0 end)>0 and
SUM( case when rst1.TerritoryId = 201 then 1 else 0 end)>0 and
SUM( case when rst2.TerritoryId = 69 then 1 else 0 end)>0 and
SUM( case when rst2.TerritoryId = 62 then 1 else 0 end)>0 and
SUM( case when rst2.TerritoryId = 200 then 1 else 0 end)>0 and
SUM( case when rst2.TerritoryId = 201 then 1 else 0 end)=0
Try something like this -
SELECT r.ID
,rs1.ID
,rs2.ID
FROM dbo.Release r
JOIN dbo.[Resource] rs1 ON r.ID = rr1.ReleaseId AND rs1.IsLocked = 0
JOIN dbo.ResourceTerritory rst1 ON rs1.ID = rst1.ResourceId
JOIN dbo.[Resource] rs2 ON rs2.IsLocked = 0
JOIN dbo.ResourceTerritory rst2 ON rs2.ID = rst2.ResourceId
JOIN dbo.ReleaseResource rr1 ON rs1.ID = rr1.ResourceId
JOIN dbo.ReleaseResource rr2 ON rr1.ReleaseId = rr2.ReleaseId
WHERE rs2.ID = rr2.ResourceId
AND rs1.ID <> rs2.ID
AND rs1.OwningTerritoryId = 69
AND rs2.OwningTerritoryId = 200
AND r.OwningTerritoryId = 69
AND rst1.TerritoryId IN (62, 69 , 200 , 201)
AND rst2.TerritoryId IN (62 , 69 , 200 , 201)
GROUP BY
r.ID
,rs1.ID
,rs2.ID
having SUM( case when rst1.TerritoryId = 62 then 1 else 0 end)>0 and
SUM( case when rst1.TerritoryId = 69 then 1 else 0 end)>0 and
SUM( case when rst1.TerritoryId = 200 then 1 else 0 end)>0 and
SUM( case when rst1.TerritoryId = 201 then 1 else 0 end)>0 and
SUM( case when rst2.TerritoryId = 69 then 1 else 0 end)>0 and
SUM( case when rst2.TerritoryId = 62 then 1 else 0 end)>0 and
SUM( case when rst2.TerritoryId = 200 then 1 else 0 end)>0 and
SUM( case when rst2.TerritoryId = 201 then 1 else 0 end)=0
Should be replaced by
WHERE
(rst1.TerritoryId = 62
OR rst1.TerritoryId = 69
OR rst1.TerritoryId = 200
OR rst1.TerritoryId = 201)
AND
(rst2.TerritoryId = 62
OR rst2.TerritoryId = 69
OR rst2.TerritoryId = 200
)
Do you have indexes on (e.g.) TerritoryId?
Also check: http://msdn.microsoft.com/en-us/library/ms345434.aspx
and run SQL Server Profiler (under Tools-menu)
And instead of the WHERE clause you can use the INNER JOIN clause

Pivoting on a field?

I use IBM DB2 SQL.
Here is my current query:
select
EXSHPE as "Shape",
EXDLVY as "Delivery",
Sum(Case When EXSURF = 'Print' Then EXRLTO Else 0 End) As Retail_Print,
Sum(Case When EXSURF = 'Pattern' Then EXRLTO Else 0 End) as Retail_Pattern,
Sum(Case When EXSURF = 'Solid' Then EXRLTO Else 0 End) As Retail_Solid,
Sum(Case When EXSURF = 'UnknownA' Then EXRLTO Else 0 End) as Retail_UnknownA,
Sum(Case When EXSURF = 'UnknownB' Then EXRLTO Else 0 End) As Retail_UnknownB,
Sum(Case When EXSURF = 'UnknownC' Then EXRLTO Else 0 End) as Retail_UnknownC,
Sum(Case When EXSURF = 'Print' Then EXWHLO Else 0 End) As Wholesale_Print,
Sum(Case When EXSURF = 'Pattern' Then EXWHLO Else 0 End) as Wholesale_Pattern,
Sum(Case When EXSURF = 'Solid' Then EXWHLO Else 0 End) As Wholesale_Solid,
Sum(Case When EXSURF = 'UnknownA' Then EXWHLO Else 0 End) as Wholesale_UnknownA,
Sum(Case When EXSURF = 'UnknownB' Then EXWHLO Else 0 End) As Wholesale_UnknownB,
Sum(Case When EXSURF = 'UnknownC' Then EXWHLO Else 0 End) as Wholesale_UnknownC,
Sum(Case When EXSURF = 'Print' Then EXUNTO Else 0 End) As Units_Print,
Sum(Case When EXSURF = 'Pattern' Then EXUNTO Else 0 End) as Units_Pattern,
Sum(Case When EXSURF = 'Solid' Then EXUNTO Else 0 End) As Units_Solid,
Sum(Case When EXSURF = 'UnknownA' Then EXUNTO Else 0 End) as Units_UnknownA,
Sum(Case When EXSURF = 'UnknownB' Then EXUNTO Else 0 End) As Units_UnknownB,
Sum(Case When EXSURF = 'UnknownC' Then EXUNTO Else 0 End) as Units_UnknownC,
Sum(Case When EXSURF = 'Print' Then EXAURA Else 0 End) As Actual_AUR_Print,
Sum(Case When EXSURF = 'Pattern' Then EXAURA Else 0 End) as Actual_AUR_Pattern,
Sum(Case When EXSURF = 'Solid' Then EXAURA Else 0 End) As Actual_AUR_Solid,
Sum(Case When EXSURF = 'UnknownA' Then EXAURA Else 0 End) as Actual_AUR_UnknownA,
Sum(Case When EXSURF = 'UnknownB' Then EXAURA Else 0 End) As Actual_AUR_UnknownB,
Sum(Case When EXSURF = 'UnknownC' Then EXAURA Else 0 End) as Actual_AUR_UnknownC,
Sum(Case When EXSURF = 'Print' Then EXMERA Else 0 End) As Merch_AUR_Print,
Sum(Case When EXSURF = 'Pattern' Then EXMERA Else 0 End) as Merch_AUR_Pattern,
Sum(Case When EXSURF = 'Solid' Then EXMERA Else 0 End) As Merch_AUR_Solid,
Sum(Case When EXSURF = 'UnknownA' Then EXMERA Else 0 End) as Merch_AUR_UnknownA,
Sum(Case When EXSURF = 'UnknownB' Then EXMERA Else 0 End) As Merch_AUR_UnknownB,
Sum(Case When EXSURF = 'UnknownC' Then EXMERA Else 0 End) as Merch_AUR_UnknownC
from EXOWMSPD
Where (EXCO || '/' || EXDIV) = ?
Group By
EXSHPE,
EXDLVY
Order By
EXSHPE DESC,
EXDLVY DESC
Database looks like this:
I need to pivot of Surface, but dynamically.
The issue is, I only know the first 3 surface descriptions. But I need to be ready for up to 6.
Is there a way I could pivot this dynamically to grab the first 6 surfaces.
Example,
RETAIL_DOLLARS_1 10.00
RETAIL_DOLLARS_2 20.00
RETAIL_DOLLARS_3 50.00
RETAIL_DOLLARS_4 0.00
RETAIL_DOLLARS_5 0.00
RETAIL_DOLLARS_6 0.00
In this example, data was found for 3 surfaces, the other 3 I want filled with 0s.
I'm using this to make a report and I'll hide columns which will have SURFACE_DESCRIPTION_X equal to "".
Is there a way to do this?
Thanks
If you would like to cube the data on the various dimensions, try the
GROUP BY CUBE
clause