Union Statement that can be changed to Case statement - tsql

Good Day Everyone!
well i have this kind of code and it kinda ugly,
a friend of mine told me i can implement Case Statements in here, but i do not know how or how would i implement, the code is long so if you could just help me to optimize my code i would appreciate it greatly!
PS. please be gentle to me, im new in T-sql :)
Thank yoU!
SELECT
SUM(CYJEWELRY) 'CY_Jewelry'
,SUM(CYAPPLICANCE) 'CY_Appliance'
,SUM(CYCELLPHONE) 'CY_Cellphone'
,SUM(PYJEWELRY) 'PY_Jewelry'
,SUM(PYAPPLIANCE) 'PY_Appliance'
,SUM(PYCELLPHONE) 'PY_Cellphone'
FROM
(
---TOTAL NUNG A FORMAT 0,0,0,0,0,0
--------------CURRENT YEAR JEWELRY
SELECT COUNT (*) AS CYJEWELRY,0 AS CYAPPLICANCE,0 AS CYCELLPHONE,0 AS PYJEWELRY,0 AS PYAPPLIANCE,0 AS PYCELLPHONE
FROM #TEMPTABLE1
WHERE (fld_StorageGroupID >= 3 and fld_StorageGroupID <= 14)
UNION
-----------CURRENT YEAR APPLIANCE
SELECT 0,COUNT(*),0,0,0,0
FROM #TEMPTABLE1
WHERE fld_StorageGroupID = 1
UNION
------------CURRENT YEAR CELLPHONE
SELECT 0,0,COUNT(*),0,0,0
FROM #TEMPTABLE1
WHERE fld_StorageGroupID = 2
UNION
---------------LAST YEAR JEWELRY
SELECT 0,0,0,COUNT(*),0,0
FROM #TEMPTABLE2
WHERE (fld_StorageGroupID >= 3 and fld_StorageGroupID <= 14)
UNION
-----------------------LAST YEAR APPLIANCE
SELECT 0,0,0,0,COUNT (*),0
FROM #TEMPTABLE2
WHERE fld_StorageGroupID = 1
UNION
-------------------------LAST YEAR CELLPHONE
SELECT 0,0,0,0,0,COUNT(*)
FROM #TEMPTABLE2
WHERE fld_StorageGroupID = 2
)A

Assuming your data is bit like this Sql Fiddle Example, try this for the sub query using SUM() and CASE.
SELECT SUM(CASE WHEN fld_StorageGroupID >= 3 and fld_StorageGroupID <= 14 ELSE 0 END) Col1And4,
SUM(CASE WHEN fld_StorageGroupID = 1 THEN 1 ELSE 0 END) Col2And5,
SUM(CASE WHEN fld_StorageGroupID = 2 THEN 1 ELSE 0 END) Col3And6
FROM #TEMPTABLE1
GROUP BY fld_StorageGroupID
Since you are applying the same filter for last 3 columns in the subquery, I have done only first 3 columns here.
EDIT:
I think this is better than above (Note: no need to use SUM() in the main query).
Fiddle Example with data
select col1_4 CY_Jewelry,
col2_5 CY_Appliance,
col3_6 CY_Cellphone,
col1_4 PY_Jewelry,
col2_5 PY_Appliance,
col3_6 PY_Cellphone
from (
select sum(case when id>= 3 and id <= 14 then 1 else 0 end) col1_4,
sum(case when id = 2 then 1 else 0 end) col2_5,
sum(case when id = 3 then 1 else 0 end) col3_6
from t
--group by id
) X

Related

Postgres: Extracting the IDs and names of people who are cheating the system

I have a table A with the following transaction data:
ID Name Type
1 Albert Rewards
2 Albert Visit
3 Ruddy Rewards
4 Ruddy Visit
5 Ruddy Purchase
6 Mario Rewards
7 Mario Visit
...
I want a table that only select the rows with names of people who used the "Rewards" and "Visit" type but didn't make a purchase, something like this:
ID Name Type
1 Albert Rewards
2 Albert Visit
6 Mario Rewards
7 Mario Visit
...
Any ideas?
The below query will count for every Visit/Rewards/Purchase how often they happened for a given name - and if the respective results are 1/1/0 then all records from the table with that name will be returned.
If fine-tuning is required (such as cases where the count of any of those > 1 etc.) that can be done by fiddling with the numbers in the 'having' clause. The same is true for adding additional categories to check against.
select *
from mytable a
where exists (select b.name,
sum(case when b.type='Rewards' then 1 else 0 end),
sum(case when b.type='Visit' then 1 else 0 end),
sum(case when b.type='Purchase' then 1 else 0 end)
from mytable b
where b.name=a.name
group by b.name
having sum(case when b.type='Rewards' then 1 else 0 end) = 1
and
sum(case when b.type='Visit' then 1 else 0 end) = 1
and
sum(case when b.type='Purchase' then 1 else 0 end) = 0);
For completion sake: SQLFiddle with 2 queries First query also works, but a little differently

order by with operation on select case query

I want to rank a table by multi-columns and sum of each point that is decided by value.
For example, I can get some columns and each points by below query.
select
(case when seller=true then 50 else 0 end) as sel,
(case when buyer=true then 40 else 0 end) as buy
from company;
but I can't order by this values by like this query
select
(case when seller=true then 50 else 0 end) as sel,
(case when buyer=true then 40 else 0 end) as buy
from company
order by (sel + by);
or this
select
(case when seller=true then 50 else 0 end) as sel,
(case when buyer=true then 40 else 0 end) as buy,
(sell, buy) as sm
from company
order by sm;
How can I do that?
Oh, sorry, I found the answer.
select * from
(select
(case when seller=true then 50 else 0 end) as sel,
(case when buyer=true then 40 else 0 end) as buy
from company) as tmp
order by (tmp.sel + tmp.buy);

Using field alias in MSQuery does not work with DB2

This query works in data studio, but fails to show alias in MS Query!
I have tried different types such as "",'',[] and even https://support.microsoft.com/en-us/kb/298955
SELECT 'TRANIN'AS NAME, SUM(CASE WHEN ALT3.TRANINDT BETWEEN 20150603 AND 20150601 THEN 1 else 0 END) AS CurrentMonth, SUM(CASE WHEN ALT3.TRANINDT BETWEEN 20150501 AND 20150531 THEN 1 else 0 END) AS LastMonth
FROM ALT3
MS broke MS query a long time ago...
I've tried to get it to work right, but nothing worked. I've pretty much given up.
Normally I just rename the column once the data is back in Excel.
But if you really want the name returned from MS query, this works:
WITH tbl AS (SELECT 'TRANIN'AS NAME
, SUM(CASE WHEN ALT3.TRANINDT BETWEEN 20150603 AND 20150601
THEN 1 else 0 END) AS CurrentMonth
, SUM(CASE WHEN ALT3.TRANINDT BETWEEN 20150501 AND 20150531
THEN 1 else 0 END) AS LastMonth
FROM ALT3)
SELECT * FROM TBL

how to combine multiple query into one single query

I have three queries as below and I need to combine them into one. Does any body know how to do that?
select COUNT(*) from dbo.VWAnswer where questionId =2 and answer =1
select COUNT(*) from dbo.VWAnswer where questionId =3 and answer =4
select COUNT(*) from dbo.VWAnswer where questionId =5 and answer =2
I want to find out total count of those people whose gender = 1 and Education = 4 and marital status = 2
Following is the table columns(With one ex) that i refer:
questionId questionText anwser AnserSheetID
1 Gender 1 1
2 Qualification 4 1
3 Marital Status 2 1
1 Gender 2 2
2 Qualification 1 2
3 Marital Status 2 2
1 Gender 1 3
2 Qualification 3 3
3 Marital Status 1 3
Basically, these are questions answered by different people whose answers are stored in this table.
So if we consider above table entries I should get 1 as total count based upon above 3 conditions i.e. gender = 1 and Education = 4 and marital status = 2
Can someone tell me what I need to do to get this to work?
If you want to combine your three count queries, you can try the below SQL to get it done.
select
sum(case when questionId =2 and anwser=1 then 1 else 0 end) as FCount,
sum(case when questionId =3 and anwser=4 then 1 else 0 end) as SCount,
sum(case when questionId =5 and anwser=2 then 1 else 0 end) as TCount
from dbo.VWAnswer
Update 1:
select
Sum(case when questionText='Gender' and anwser='1' then 1 else 0 end) as GenderCount,
Sum(case when questionText='Qualification' and anwser='4' then 1 else 0 end) as EducationCount,
Sum(case when questionText='Marital Status' and anwser='2' then 1 else 0 end) as MaritalCount
from VWAnswer
We can only get the counts based on the rows and every condition should apply in each row.
You might use a joined view meeting you conditions and select the count of the rows fitting your conditions.
Select COUNT(*) as cnt from
(
Select a.AnserSheetID
from VWAnswer a
Join VWAnswer b on a.AnserSheetID=b.AnserSheetID and b.questionId = 2 and b.anwser=4
Join VWAnswer c on a.AnserSheetID=c.AnserSheetID and c.questionId = 3 and c.anwser=2
where a.questionId=1 and a.anwser=1
) hlp

Remove group by field

I've got an issue while getting data from DB2. I want to summarise the invoice amounts by customer. In one field, (calculated - I've called this InvoicedThisYear) it works out what was invoiced this year and in another it works out what was invoiced in the previous year (calculated, I've called it InvoicedLastYear). However, as it is summariesed I've grouped it by the Cust, but it is also wanting the data grouped by the InvoiceYear, so I've had to include this in the grouping. My problem is in my results I now have zeros for the years where there is no data and duplicates, e.g.:
Cust InvoicedThisYear InvoiceLastYear
abc 0 100
abc 100 0
Ideally I would like to see
Cust InvoicedThisYear InvoicedLastYear
abc 100 100
Here is my code:
SELECT
Cust AS Customer,
(CASE WHEN InvoiceYear = Year(Current Date) THEN sum(InvoiceAmt)ELSE 0 END) as InvoicedThisYear,
(CASE WHEN InvoiceYear = year(Current Date)-1 THEN sum(InvoiceAmt)ELSE 0 END) as InvoicedLastYear
FROM
InvHead
GROUP BY
Cust,
InvoiceYear
HAVING
((CASE WHEN InvoiceYear = Year(Current Date) THEN sum(InvoiceAmt)ELSE 0 END)<>0)
OR
((CASE WHEN InvoiceYear = year(Current Date)-1 THEN sum(InvoiceAmt)ELSE 0 END)<>0)
ORDER BY
Cust
How do I get the desired result? The query will not run if I remove the groupby Invoice Year
As a size note, it works in MS Access without grouping by the Invoice Year!
Thanks,
Michael
You need to put the SUM() around the case statements:
SELECT
Cust AS Customer,
sum(CASE WHEN InvoiceYear = Year(Current Date) THEN InvoiceAmt ELSE 0 END) as InvoicedThisYear,
sum(CASE WHEN InvoiceYear = year(Current Date)-1 THEN InvoiceAmt ELSE 0 END) as InvoicedLastYear
FROM
InvHead
GROUP BY
Cust
ORDER BY
Cust