SQL Select Adding a new row with difference between numbers - sql

I have this query that give the sum between years but I want to add a new row at the end of each TARMA that give the differences between the years.
Here is the query:
Select
VPC.Armazem as TARMA
,YEAR(VPC.DATA) as DataTotal
,SUM(CASE WHEN VP.COMBUSTIVEL = 1 THEN VPL.QTD ELSE 0 END) as ADITIVADA
,SUM(CASE WHEN VP.COMBUSTIVEL = 2 THEN VPL.QTD ELSE 0 END) as X98
,SUM(CASE WHEN VP.COMBUSTIVEL = 3 THEN VPL.QTD ELSE 0 END)as X95
,SUM(CASE WHEN VP.COMBUSTIVEL = 4 THEN VPL.QTD ELSE 0 END) as XGAS
,SUM(CASE WHEN VP.COMBUSTIVEL = 5 THEN VPL.QTD ELSE 0 END) as XGPL
,SUM(CASE WHEN VP.COMBUSTIVEL = 6 THEN VPL.QTD ELSE 0 END) as XAGR
,SUM(CASE WHEN VP.COMBUSTIVEL = 7 THEN VPL.QTD ELSE 0 END) as MISTURA
,SUM(CASE WHEN VP.COMBUSTIVEL = 9 THEN VPL.QTD ELSE 0 END) as XAQ
,SUM(CASE WHEN VP.COMBUSTIVEL = 10 THEN VPL.QTD ELSE 0 END) as ADIESEL
,SUM(CASE WHEN VP.COMBUSTIVEL = 11 THEN VPL.QTD ELSE 0 END) as ADBLUE
,SUM(CASE WHEN VP.COMBUSTIVEL = 12 THEN VPL.QTD ELSE 0 END) as O95
,SUM(CASE WHEN VP.COMBUSTIVEL = 13 THEN VPL.QTD ELSE 0 END) as O98
WHERE
(MONTH(VPC.DATA) >= MONTH('2015-09-01') AND MONTH(VPC.DATA) <= MONTH('2015-09-30'))
and (YEAR(VPC.DATA) >= YEAR('2014-09-01') AND YEAR(VPC.DATA) <= YEAR('2015-09-30'))
and VPT.armazem IN ('454','457')
and FACT_VD NOT IN ('A', 'I', 'G', 'M')
GROUP BY
YEAR(VPC.DATA)
,VPC.Armazem
ORDER BY
VPC.Armazem
,YEAR(VPC.DATA)
And here is the result without the difference:
[Result][1]
For example:
TARMA: 454 for X98
2014: 1849.14077
2015: 2571.47750
Difference: -722,33673
I'm using MS SQL.
Is it with a UNION?
How can I get the difference?

If you want to calculate the difference in a separate query and then just "add" the rows to your results, you can use the "UNION ALL" between your queries. "UNION ALL" will just combine the 2 result sets. Using just "UNION" will cause SQL Server to attempt to de-duplicate the rows in the 2 result sets.

Using your query as a subquery (without the order by), you can do something like this:
with cte as (
<your query here>
)
select cte.*,
(additava - lag(additava) over (partition by Armazem order by DataTotal) ) as additava_diff,
. . .
from cte;
Note: lag() requires SQL Server 2012+.
EDIT:
Prior to SQL Server 2012+, you could do:
with cte as (
<your query here>
)
select cte.*,
(additava - cte2.additava) as additava_diff,
. . .
from cte outer apply
(select top 1 cte.*
from cte cte2
where cte2.Armazem = cte.Armazem and cte2.DataTotal < cte.DataTotal
order by cte2.DataTotal
) cte2

I got it:
;with dados as (
Select
VPC.Armazem as TARMA
,YEAR(VPC.DATA) as DataTotal1
,SUM(CASE WHEN VP.COMBUSTIVEL = 1 THEN VPL.QTD ELSE 0 END) as SomaADITIVADA
,SUM(CASE WHEN VP.COMBUSTIVEL = 2 THEN VPL.QTD ELSE 0 END) as SomaX98
,SUM(CASE WHEN VP.COMBUSTIVEL = 3 THEN VPL.QTD ELSE 0 END)as SomaX95
,SUM(CASE WHEN VP.COMBUSTIVEL = 4 THEN VPL.QTD ELSE 0 END) as SomaXGAS
,SUM(CASE WHEN VP.COMBUSTIVEL = 5 THEN VPL.QTD ELSE 0 END) as SomaXGPL
,SUM(CASE WHEN VP.COMBUSTIVEL = 6 THEN VPL.QTD ELSE 0 END) as SomaXAGR
,SUM(CASE WHEN VP.COMBUSTIVEL = 7 THEN VPL.QTD ELSE 0 END) as SomaMISTURA
,SUM(CASE WHEN VP.COMBUSTIVEL = 9 THEN VPL.QTD ELSE 0 END) as SomaXAQ
,SUM(CASE WHEN VP.COMBUSTIVEL = 10 THEN VPL.QTD ELSE 0 END) as SomaADIESEL
,SUM(CASE WHEN VP.COMBUSTIVEL = 11 THEN VPL.QTD ELSE 0 END) as SomaADBLUE
,SUM(CASE WHEN VP.COMBUSTIVEL = 12 THEN VPL.QTD ELSE 0 END) as SomaO95
,SUM(CASE WHEN VP.COMBUSTIVEL = 13 THEN VPL.QTD ELSE 0 END) as SomaO98
,row_number() over (partition by VPC.Armazem order by YEAR(VPC.DATA) ASC) as NAno
WHERE
(MONTH(VPC.DATA) >= MONTH('2015-09-01') AND MONTH(VPC.DATA) <= MONTH('2015-09-30'))
and (YEAR(VPC.DATA) >= YEAR('2014-09-01') AND YEAR(VPC.DATA) <= YEAR('2015-09-30'))
and VPT.armazem IN ('454','457')
and FACT_VD NOT IN ('A', 'I', 'G', 'M')
GROUP BY
YEAR(VPC.DATA)
,VPC.Armazem
)
SELECT
anosDetalhados.TARMA as TARMA
,anosDetalhados.DataTotal1 as DataTotal
,SUM(anosDetalhados.SomaADITIVADA) as ADITIVADA
,SUM(anosDetalhados.SomaX98) as X98
,SUM(anosDetalhados.SomaX95) as X95
,SUM(anosDetalhados.SomaXGAS) as XGAS
,SUM(anosDetalhados.SomaXGPL) as XGPL
,SUM(anosDetalhados.SomaXAGR) as XAGR
,SUM(anosDetalhados.SomaMISTURA) as MISTURA
,SUM(anosDetalhados.SomaXAQ) as XAQ
,SUM(anosDetalhados.SomaADIESEL) as ADIESEL
,SUM(anosDetalhados.SomaADBLUE) as ADBLUE
,SUM(anosDetalhados.SomaO95) as O95
,SUM(anosDetalhados.SomaO98) as O98
FROM dados as anosDetalhados (nolock)
GROUP BY
anosDetalhados.DataTotal1
,anosDetalhados.TARMA
UNION ALL
SELECT
ano1.TARMA as TARMA
,NULL as DataTotal
,SUM(coalesce(ano1.SomaADITIVADA-ano2.SomaADITIVADA, 0)) as ADITIVADA
,SUM(coalesce(ano1.SomaX98-ano2.SomaX98, 0)) as X98
,SUM(coalesce(ano1.SomaX95-ano2.SomaX95, 0)) as X95
,SUM(coalesce(ano1.SomaXGAS-ano2.SomaXGAS, 0)) as XGAS
,SUM(coalesce(ano1.SomaXGPL-ano2.SomaXGPL, 0)) as XGPL
,SUM(coalesce(ano1.SomaXAGR-ano2.SomaXAGR, 0)) as XAGR
,SUM(coalesce(ano1.SomaMISTURA-ano2.SomaMISTURA, 0)) as MISTURA
,SUM(coalesce(ano1.SomaXAQ-ano2.SomaXAQ, 0)) as XAQ
,SUM(coalesce(ano1.SomaADIESEL-ano2.SomaADIESEL, 0)) as ADIESEL
,SUM(coalesce(ano1.SomaADBLUE-ano2.SomaADBLUE, 0)) as ADBLUE
,SUM(coalesce(ano1.SomaO95-ano2.SomaO95, 0)) as O95
,SUM(coalesce(ano1.SomaO98-ano2.SomaO98, 0)) as O98
FROM dados as ano1 (nolock)
LEFT JOIN dados as ano2 on ano1.TARMA=ano2.TARMA and ano1.NAno > ano2.NAno
GROUP BY
ano1.TARMA
ORDER BY
TARMA
,anosDetalhados.DataTotal1 ASC

Related

Full outer join with "case when" and subquery

I have a full outer join query with case when and sub query in oracle. What I am trying to accomplish is aggregating current year data and previous year data from the same table in order to compare them. However my FULL OUTER JOIN is acting as an inner join not returning the null values from both the current year and the previous year.
Here is my code:
SELECT
SQ1.CHANNEL,
SQ1.SHORT,
SQ1.NAME,
SQ1.RDC,
SQ1.CY_APPROVED_COUNT,
SQ2.PY_APPROVED_COUNT,
SQ1.CY_APPROVED_VOLUME,
SQ2.PY_APPROVED_VOLUME,
SQ1.CY_DECLINED_COUNT,
SQ2.PY_DECLINED_COUNT,
SQ1.CY_DECLINED_VOLUME,
SQ2.PY_DECLINED_VOLUME,
SQ1.CY_RETURNED_COUNT,
SQ2.PY_RETURNED_COUNT,
SQ1.CY_RETURNED_VOLUME,
SQ2.PY_RETURNED_VOLUME
FROM ( SELECT
CHANNEL,
SHORT,
NAME,
RDC,
SUM (CASE WHEN STATUS = 'Approved' THEN APP_COUNTS ELSE 0 END) AS CY_APPROVED_COUNT,
SUM (CASE WHEN STATUS = 'Approved' THEN PROJ_VOL ELSE 0 END) AS CY_APPROVED_VOLUME,
SUM (CASE WHEN STATUS = 'Declined' THEN APP_COUNTS ELSE 0 END) AS CY_DECLINED_COUNT,
SUM (CASE WHEN STATUS = 'Declined' THEN PROJ_VOL ELSE 0 END) AS CY_DECLINED_VOLUME,
SUM (CASE WHEN STATUS = 'Returned' THEN APP_COUNTS ELSE 0 END) AS CY_RETURNED_COUNT,
SUM (CASE WHEN STATUS = 'Returned' THEN PROJ_VOL ELSE 0 END) AS CY_RETURNED_VOLUME
FROM WFRT_MSP_SP_MTD
WHERE PERIOD >= TO_DATE('2016/02/01', 'yyyy/mm/dd')
AND PERIOD <= TO_DATE('2016/02/13','yyyy/mm/dd')
AND CHANNEL = 'MSP'
AND RDC = 'BASE'
GROUP BY
CHANNEL,
SHORT,
NAME,
RDC
) SQ1
-- NOT CORRECTLY SHOWING NULL VALUES
FULL OUTER JOIN
( SELECT
CHANNEL,
SHORT,
NAME,
RDC,
SUM (CASE WHEN STATUS = 'Approved' THEN APP_COUNTS ELSE 0 END) AS PY_APPROVED_COUNT,
SUM (CASE WHEN STATUS = 'Approved' THEN PROJ_VOL ELSE 0 END) AS PY_APPROVED_VOLUME,
SUM (CASE WHEN STATUS = 'Declined' THEN APP_COUNTS ELSE 0 END) AS PY_DECLINED_COUNT,
SUM (CASE WHEN STATUS = 'Declined' THEN PROJ_VOL ELSE 0 END) AS PY_DECLINED_VOLUME,
SUM (CASE WHEN STATUS = 'Returned' THEN APP_COUNTS ELSE 0 END) AS PY_RETURNED_COUNT,
SUM (CASE WHEN STATUS = 'Returned' THEN PROJ_VOL ELSE 0 END) AS PY_RETURNED_VOLUME
FROM WFRT_MSP_SP_MTD
WHERE PERIOD >= TO_DATE('2015/02/01', 'yyyy/mm/dd')
AND PERIOD <= TO_DATE('2015/02/13','yyyy/mm/dd')
AND CHANNEL = 'MSP'
AND RDC = 'BASE'
GROUP BY
CHANNEL,
SHORT,
NAME,
RDC
) SQ2
ON sq1.short = sq2.short
;
Please help if you can.
Just use conditional aggregation:
SELECT CHANNEL, SHORT, NAME, RDC,
SUM(CASE WHEN this_year = 1 AND STATUS = 'Approved' THEN APP_COUNTS ELSE 0 END) AS CY_APPROVED_COUNT,
SUM(CASE WHEN this_year = 1 AND STATUS = 'Approved' THEN PROJ_VOL ELSE 0 END) AS cY_APPROVED_VOLUME,
SUM(CASE WHEN this_year = 1 AND STATUS = 'Declined' THEN APP_COUNTS ELSE 0 END) AS CY_DECLINED_COUNT,
SUM(CASE WHEN this_year = 1 AND STATUS = 'Declined' THEN PROJ_VOL ELSE 0 END) AS CY_DECLINED_VOLUME,
SUM(CASE WHEN this_year = 1 AND STATUS = 'Returned' THEN APP_COUNTS ELSE 0 END) AS CY_RETURNED_COUNT,
SUM(CASE WHEN this_year = 1 AND STATUS = 'Returned' THEN PROJ_VOL ELSE 0 END) AS CY_RETURNED_VOLUME,
SUM(CASE WHEN prev_year = 1 AND STATUS = 'Approved' THEN APP_COUNTS ELSE 0 END) AS PY_APPROVED_COUNT,
SUM(CASE WHEN prev_year = 1 AND STATUS = 'Approved' THEN PROJ_VOL ELSE 0 END) AS PY_APPROVED_VOLUME,
SUM(CASE WHEN prev_year = 1 AND STATUS = 'Declined' THEN APP_COUNTS ELSE 0 END) AS PY_DECLINED_COUNT,
SUM(CASE WHEN prev_year = 1 AND STATUS = 'Declined' THEN PROJ_VOL ELSE 0 END) AS PY_DECLINED_VOLUME,
SUM(CASE WHEN prev_year = 1 AND STATUS = 'Returned' THEN APP_COUNTS ELSE 0 END) AS PY_RETURNED_COUNT,
SUM(CASE WHEN prev_year = 1 AND STATUS = 'Returned' THEN PROJ_VOL ELSE 0 END) AS PY_RETURNED_VOLUME
FROM (SELECT msm.*,
(CASE WHEN PERIOD >= DATE '2015-02-01' AND
PERIOD <= '2015-02-13'
THEN 1 ELSE 0
END) as prev_year,
(CASE WHEN PERIOD >= DATE '2016-02-01' AND
PERIOD <= '2016-02-13'
THEN 1 ELSE 0
END) as this_year
FROM WFRT_MSP_SP_MTD msm
) msm
WHERE CHANNEL = 'MSP' AND RDC = 'BASE'
GROUP BY CHANNEL, SHORT, NAME, RDC;

How to use having condition in SQL query

SELECT
userid,
CASE
WHEN (COUNT(CASE
WHEN onlinesportsgamewagers != 0
THEN 1
ELSE null
END)
+ COUNT(CASE
WHEN depositmade_amt != 0
THEN 1
ELSE null
END)) >= 10
THEN "VIP"
ELSE "NON-VIP"
END as VIPcheck
FROM
player_activity
WHERE
userid = 2023410
GROUP BY
year(txndate), month(txndate)
This query determines the user's VIP status for each month.
Ultimately, I want to have a query that determines if the user achieved VIP status for at least 3 months (including the current month). For the time being, it's only user 2023410, but eventually I want to run this for the whole database.
Therefore my ultimate output would be:
User - VIPcheck (3 different months w/ active status)
(one row per userID)
HAVING COUNT(CASE WHEN (COUNT(CASE WHEN onlinesportsgamewagers != 0
THEN 1
ELSE null
END)
+ COUNT(CASE WHEN depositmade_amt != 0
THEN 1
ELSE null
END)) >= 10
THEN 1
ELSE 0
END)
Tried the above having statement, but it didn't work. Any suggestions?
If I understand correctly, this gets the VIP status for one user by month:
SELECT userid, year(txndate), month(txndate),
(CASE WHEN SUM(CASE WHEN onlinesportsgamewagers <> 0 THEN 1 ELSE 0 END) +
SUM(CASE WHEN depositmade_amt <> 0 THEN 1 ELSE 0 END) >= 10
THEN 'VIP'
ELSE 'NON-VIP'
END) as VIPcheck
FROM player_activity
GROUP BY userid, year(txndate), month(txndate);
Another aggregation will get what you want:
SELECT userid,
(CASE WHEN SUM(VIPcheck = 'VIP') >= 3 THEN 'SUPER-VIP'
WHEN SUM(VIPcheck = 'VIP') >= 1 THEN 'VIP'
ELSE 'HOI POLLOI'
END) as status
FROM (SELECT userid, year(txndate), month(txndate),
(CASE WHEN SUM(CASE WHEN onlinesportsgamewagers <> 0 THEN 1 ELSE 0 END) +
SUM(CASE WHEN depositmade_amt <> 0 THEN 1 ELSE 0 END) >= 10
THEN 'VIP'
ELSE 'NON-VIP'
END) as VIPcheck
FROM player_activity
GROUP BY userid, year(txndate), month(txndate)
) uym
GROUP BY userid;

Combinations of Products as single count

I need to count combinations of products within transactions differently to other products and I'm struggling with how to do this within a single select statement from SQL 2008. This would then become a data set to manipulate in Reporting Services
raw data looks like this
txn, prod, units
1, a, 2
1, c, 1
2, a, 1
2, b, 1
2, c, 1
3, a, 2
3, b, 1
4, a, 3
4, c, 2
So a+b should = one if in same trans number, however a or b should equal one if not paired. So a=1 and b=1 but a+b=1, a+b+a=2, a+b+a+b=2 given the example data here is my desired result with an explanation of why
txn 1 is 3 units -- 2a + c
txn 2 is 2 units -- (a+b) + c
txn 3 is 2 units -- (a+b) + a
txn 4 is 5 units -- 3a + 2c
My query is more complex than this and includes other aggregates so I would like to group by transaction which I can't do as I need to manipulate at a lower grain
Update Progress :
Possible solution, I've generated columns based on the products I'm measuring. This allows me to group on Txn as I am now aggregating that field. Unsure if there's a better way to do it as it does take a little while
CASE WHEN SUM(CASE WHEN Prod='a' then 1 else 0 end)-
SUM(CASE WHEN Prod='b' then 1 else 0 end)=0
THEN SUM(CASE WHEN Prod='a' then 1 else 0 end)
ELSE 0 END AS MixProd
, CASE WHEN SUM(CASE WHEN Prod='a' then 1 else 0 end)-
SUM(CASE WHEN Prod='b' then 1 else 0 end)!=0
THEN ABS(SUM(CASE WHEN Prod='a' then 1 else 0 end)-
SUM(CASE WHEN Prod='b' then 1 else 0 end))
ELSE 0 END AS NotMixProd
I will then need to sort out the current unit aggregate to remove the extras but this certainly gives me a start
Update Progress 2 :
This failed to handle 0 correctly where a or b was 0 it would still give a value for mix because a-b was not zero. I reverted to an earlier draft that I lost and expanded as per below
, CASE WHEN SUM(CASE WHEN Prod='a' then 1 else 0 end) = 0 THEN 0
WHEN SUM(CASE WHEN Prod='b' then 1 else 0 end) = 0 THEN 0
WHEN SUM(CASE WHEN Prod='a' then 1 else 0 end)-
SUM(CASE WHEN Prod='b' then 1 else 0 end)=0
THEN SUM(CASE WHEN Prod='a' then 1 else 0 end)
ELSE ABS(SUM(CASE WHEN Prod='a' then 1 else 0 end)-
SUM(CASE WHEN Prod='b' then 1 else 0 end))
END AS MixProd
, CASE WHEN SUM(CASE WHEN Prod='a' then 1 else 0 end)-
SUM(CASE WHEN Prod='b' then 1 else 0 end)!=0
THEN ABS(SUM(CASE WHEN Prod='a' then 1 else 0 end)-
SUM(CASE WHEN Prod='b' then 1 else 0 end))
ELSE 0 END AS NotMixProd
UPDATE: This should work in SQL Server 2008 (based on LAG solution from here).
Here is the demo: http://rextester.com/GNI23706
WITH CTE AS
(
select txn, prod, units,
row_number() over (partition by txn order by prod) rn,
(row_number() over (partition by txn order by prod))/2 rndiv2,
(row_number() over (partition by txn order by prod)+1)/2 rnplus1div2,
count(*) over (partition by txn) partitioncount
from test_data
)
select
txn,
sum(case when prev_prod = 'a' and prod = 'b' and prev_units >= units then 0
when prev_prod = 'a' and prod = 'b' and prev_units < units then units - prev_units
else units
end) units
from
(
select
txn,
prod,
units,
CASE WHEN rn%2=1
THEN MAX(CASE WHEN rn%2=0 THEN prod END) OVER (PARTITION BY txn,rndiv2)
ELSE MAX(CASE WHEN rn%2=1 THEN prod END) OVER (PARTITION BY txn,rnplus1div2)
END AS prev_prod,
CASE WHEN rn%2=1
THEN MAX(CASE WHEN rn%2=0 THEN units END) OVER (PARTITION BY txn,rndiv2)
ELSE MAX(CASE WHEN rn%2=1 THEN units END) OVER (PARTITION BY txn,rnplus1div2)
END AS prev_units
from cte
) temp
group by txn
For SQL Server 2012+, use LAG:
select
txn,
sum(
case when prev_prod = 'a' and prod = 'b' and prev_units >= units then 0
when prev_prod = 'a' and prod = 'b' and prev_units < units then units - prev_units
else units
end) units
from
(
select
txn,
prod,
units,
lag(prod) over (partition by txn order by prod) prev_prod,
lag(units) over (partition by txn order by prod) prev_units
from test_data
) temp
group by txn
I decided in the end that a temp table was the best way to go, because I couldn't group on a collation. So I eventually tweaked the code above as it was failing to pick up the spare items correctly
SUM(Units) AS OldUnits
SUM(Units) -
(CASE WHEN
SUM(CASE WHEN Prod='a' THEN 1 ELSE 0 END) = 0 THEN 0 WHEN
SUM(CASE WHEN Prod='b' THEN 1 ELSE 0 END) = 0 THEN 0 WHEN
SUM(CASE WHEN Prod='a' THEN 1 ELSE 0 END) -
SUM(CASE WHEN Prod='b' THEN 1 ELSE 0 END) = 0 THEN
SUM(CASE WHEN Prod='a' THEN 1 ELSE 0 END) WHEN
(SUM(CASE WHEN Prod='a' THEN 1 ELSE 0 END) -
SUM(CASE WHEN Prod='b' THEN 1 ELSE 0 END)) < 0 THEN
SUM(CASE WHEN Prod='a' THEN 1 ELSE 0 END) ELSE
SUM(CASE WHEN Prod='b' THEN 1 ELSE 0 END) END) AS NewUnits
This was stored in a temptable that I could then collate on Trans as the next step. Works fine for my purposes and helped me overcome a mild irrational fear I have of temptables

Msg 156, Level 15, State 1, Line 22 Incorrect syntax near the keyword 'having'

SELECT
CCDMS_Company.CompanyID, CCDMS_Company.CompanyName,
CCDMS_Container.ContainerID, CCDMS_Container.Price,
SUM(CASE WHEN CCDMS_Container.ContainerSize = 1
THEN 1 ELSE 0 END) AS size1,
SUM(CASE WHEN CCDMS_Container.ContainerSize = 2
THEN 1 ELSE 0 END) AS size2,
SUM(CASE WHEN CCDMS_Container.ContainerSize = 3
THEN 1 ELSE 0 END) AS size3,
SUM(CASE WHEN CCDMS_Container.ContainerSize = 4
THEN 1 ELSE 0 END) AS size4,
SUM(CASE WHEN CCDMS_Container.ContainerSize = 5
THEN 1 ELSE 0 END) AS size5
FROM
CCDMS_Company
INNER JOIN
CCDMS_Container ON CCDMS_Container.Co_ID = CCDMS_Company.CompanyID
AND CCDMS_Company.CityID = 1
GROUP BY
CCDMS_Company.CompanyID, CCDMS_Company.CompanyName,
CCDMS_Container.ContainerID, CCDMS_Container.Price
HAVING
size1 >=2
AND size2 >= 1
AND size3 >= 1
AND size4 >= 0
AND size5 >= 1 ;
This is my query and I keep getting this error even when I use where .
I don't know what to do .
Msg 156, Level 15, State 1, Line 22
Incorrect syntax near the keyword 'having'.
You can not use alias in having. Use below instead, or use CTE for simplicity
select CCDMS_Company.CompanyID , CCDMS_Company.CompanyName ,
CCDMS_Container.ContainerID ,CCDMS_Container.Price ,
sum(case when CCDMS_Container.ContainerSize=1
then 1 else 0 end)as size1,
sum(case when CCDMS_Container.ContainerSize=2
then 1 else 0 end)as size2,
sum(case when CCDMS_Container.ContainerSize=3
then 1 else 0 end)as size3,
sum(case when CCDMS_Container.ContainerSize=4
then 1 else 0 end)as size4,
sum(case when CCDMS_Container.ContainerSize=5
then 1 else 0 end)as size5
from
CCDMS_Company
inner join
CCDMS_Container
on CCDMS_Container.Co_ID = CCDMS_Company.CompanyID
and
CCDMS_Company.CityID = 1
group by
CCDMS_Company.CompanyID,CCDMS_Company.CompanyName,CCDMS_Container.ContainerID,CCDMS_Container.Price
having
sum(case when CCDMS_Container.ContainerSize=1 then 1 else 0 end) >=2
and sum(case when CCDMS_Container.ContainerSize=2 then 1 else 0 end) >= 1
and sum(case when CCDMS_Container.ContainerSize=3 then 1 else 0 end) >= 1
and sum(case when CCDMS_Container.ContainerSize=4 then 1 else 0 end) >= 0
and sum(case when CCDMS_Container.ContainerSize=5 then 1 else 0 end) >= 1
You can't reference the aliases from your select statement in the having statement. Try rebuilding your query using a subquery to filter it.

Sum data for many different results for same field

I am trying to find a better way to write this sql server code 2008. It works and data is accurate. Reason i ask is that i will be asked to do this for several other reports going forward and want to reduce the amount of code to upkeep going forward.
How can i take a field where i sum for the yes/no/- (dash) in each field without doing an individual sum as i have in code. Each table is a month of detail data which i sum using in a CTE. i changed the table name for each month and Union All to put data together. Is there a better way to do this. This is a small sample of code. Thanks for the help.
WITH H AS (
SELECT 'August' AS Month_Name
, SUM(CASE WHEN G.FFS = '-' THEN 1 ELSE 0 END) AS FFS_Dash
, SUM(CASE WHEN G.FFS = 'Yes' THEN 1 ELSE 0 END) AS FFS_Yes
, SUM(CASE WHEN G.FFS = 'No' THEN 1 ELSE 0 END) AS FFS_No
, SUM(CASE WHEN G.DNA = '-' THEN 1 ELSE 0 END) AS DNA_Dash
, SUM(CASE WHEN G.DNA = 'Yes' THEN 1 ELSE 0 END) AS DNA_Yes
, SUM(CASE WHEN G.DNA = 'No' THEN 1 ELSE 0 END) AS DNA_No
FROM table08 G )
, G AS (
SELECT 'July' AS Month_Name
, SUM(CASE WHEN G.FFS = '-' THEN 1 ELSE 0 END) AS FFS_Dash
, SUM(CASE WHEN G.FFS = 'Yes' THEN 1 ELSE 0 END) AS FFS_Yes
, SUM(CASE WHEN G.FFS = 'No' THEN 1 ELSE 0 END) AS FFS_No
, SUM(CASE WHEN G.DNA = '-' THEN 1 ELSE 0 END) AS DNA_Dash
, SUM(CASE WHEN G.DNA = 'Yes' THEN 1 ELSE 0 END) AS DNA_Yes
, SUM(CASE WHEN G.DNA = 'No' THEN 1 ELSE 0 END) AS DNA_No
FROM table07 G )
select * from H
UNION ALL
select * from G
How about:
SELECT Month_Name,
SUM(CASE WHEN G.FFS = '-' THEN 1 ELSE 0 END) AS FFS_Dash,
SUM(CASE WHEN G.FFS = 'Yes' THEN 1 ELSE 0 END) AS FFS_Yes,
SUM(CASE WHEN G.FFS = 'No' THEN 1 ELSE 0 END) AS FFS_No,
SUM(CASE WHEN G.DNA = '-' THEN 1 ELSE 0 END) AS DNA_Dash,
SUM(CASE WHEN G.DNA = 'Yes' THEN 1 ELSE 0 END) AS DNA_Yes,
SUM(CASE WHEN G.DNA = 'No' THEN 1 ELSE 0 END) AS DNA_No
FROM ((select 'July' as Month_Name, G.*
from table07 G
) union all
(select 'August', H.*
from table08 H
)
) gh
GROUP BY Month_Name;
However, having tables with the same structure is usually a sign of poor database design. You should have a single table with a column representing the month.