Creating a view with columns based on where clauses - sql

With the help of SO I've been picking up a little SQL today.
I created a view like this:
CREATE VIEW RDMAVWSANDBOX.VwNIM001usersAndDlCount AS
SELECT VwNIMEventFct.NIM_USER_ID, COUNT(VwNIMEventFct.NIM_EVENT_TYPE_ID) AS DownloadCount
FROM RDMAVWSANDBOX.VwNIMEventFct
WHERE NIM_EVENT_TYPE_ID = 884
GROUP BY NIM_USER_ID
And that works fine.
Except, the column NIM_EVENT_TYPE_ID has say 5 variations: 880,881,883,884,885.
In the query above I created a view with the count of 884. The results look like:
NIM_USER_ID | DownloadCount
Because 884 represents a download.
But if I wanted to create a view like this:
NIM_USER_ID | DownloadCount(based884) | SomeOtherEventCount(based880) | SomeOtherEventCount1(Bases 883) | Etc
Is there a way to do that and create it all in the one view?
Put another way, I'd like the count of each instance of 880-885 for each NIM_USER_ID

CREATE VIEW RDMAVWSANDBOX.VwNIM001usersAndDlCount AS
SELECT VwNIMEventFct.NIM_USER_ID
,SUM(CASE WHEN NIM_EVENT_TYPE_ID = 884 then 1 else 0 end) AS DownloadCount
,SUM(CASE WHEN NIM_EVENT_TYPE_ID = 885 then 1 else 0 end) AS Something
,SUM(CASE WHEN NIM_EVENT_TYPE_ID = 886 then 1 else 0 end) AS Something
,SUM(CASE WHEN NIM_EVENT_TYPE_ID = 887 then 1 else 0 end) AS Something
FROM RDMAVWSANDBOX.VwNIMEventFct
GROUP BY NIM_USER_ID
How about this one?

Maybe this is what you want?
CREATE VIEW RDMAVWSANDBOX.VwNIM001usersAndDlCount AS
SELECT
VwNIMEventFct.NIM_USER_ID,
SUM(CASE WHEN NIM_EVENT_TYPE_ID = 880 THEN 1 ELSE 0 END) AS [Count for 880],
SUM(CASE WHEN NIM_EVENT_TYPE_ID = 881 THEN 1 ELSE 0 END) AS [Count for 881],
SUM(CASE WHEN NIM_EVENT_TYPE_ID = 882 THEN 1 ELSE 0 END) AS [Count for 882],
SUM(CASE WHEN NIM_EVENT_TYPE_ID = 883 THEN 1 ELSE 0 END) AS [Count for 883],
SUM(CASE WHEN NIM_EVENT_TYPE_ID = 884 THEN 1 ELSE 0 END) AS [Count for 884],
SUM(CASE WHEN NIM_EVENT_TYPE_ID = 885 THEN 1 ELSE 0 END) AS [Count for 885]
FROM RDMAVWSANDBOX.VwNIMEventFct
GROUP BY NIM_USER_ID
You would have to change the column names and the displayed order to suit your needs, but the example should give you an idea.

Related

how to make pivot more than one column value sql

I have this table
country weeek quantity 1 quantity 2 quantity 3
0 1 sa 3235 365 123
1 1 su 6698 32135 1234
2 1 mo 1565 5689 12345
Desired output:
country sa_q1 su_q1 mo_q1 sa_q2 su_q2 mo_q2 sa_q3 su_q3 mo_q3
0 1 3235 6698 1565 365 32135 5689 123 1234 12345
Just use conditional aggregation:
select country,
sum(case when week = 'sa' then quantity1 else 0 end) as sa1,
sum(case when week = 'su' then quantity1 else 0 end) as su1,
sum(case when week = 'mo' then quantity1 else 0 end) as mo1,
sum(case when week = 'sa' then quantity2 else 0 end) as sa2,
sum(case when week = 'su' then quantity2 else 0 end) as su2,
sum(case when week = 'mo' then quantity2 else 0 end) as mo2,
sum(case when week = 'sa' then quantity3 else 0 end) as sa3,
sum(case when week = 'su' then quantity3 else 0 end) as su3,
sum(case when week = 'mo' then quantity3 else 0 end) as mo3
from t
group by country;

SQL Grand Total last ROW

Is there a way I could get the grand total of each month. I've looked into Rollup but cant seem to figure it out.
Query I have is
SELECT t.city,f.fname,f.lname,
SUM(CASE datepart(month,ddate) WHEN 1 THEN 1 ELSE 0 END) AS 'January',
SUM(CASE datepart(month,ddate) WHEN 2 THEN 1 ELSE 0 END) AS 'February',
SUM(CASE datepart(month,ddate) WHEN 3 THEN 1 ELSE 0 END) AS 'March',
SUM(CASE datepart(month,ddate) WHEN 4 THEN 1 ELSE 0 END) AS 'April',
SUM(CASE datepart(month,ddate) WHEN 5 THEN 1 ELSE 0 END) AS 'May',
SUM(CASE datepart(month,ddate) WHEN 6 THEN 1 ELSE 0 END) AS 'June',
SUM(CASE datepart(month,ddate) WHEN 7 THEN 1 ELSE 0 END) AS 'July',
SUM(CASE datepart(month,ddate) WHEN 8 THEN 1 ELSE 0 END) AS 'August',
SUM(CASE datepart(month,ddate) WHEN 9 THEN 1 ELSE 0 END) AS 'September',
SUM(CASE datepart(month,ddate) WHEN 10 THEN 1 ELSE 0 END) AS 'October',
SUM(CASE datepart(month,ddate) WHEN 11 THEN 1 ELSE 0 END) AS 'November',
SUM(CASE datepart(month,ddate) WHEN 12 THEN 1 ELSE 0 END) AS 'December',
SUM(CASE datepart(year,ddate) WHEN 2014 THEN 1 ELSE 0 END) AS 'TOTAL'
from world T
INNER JOIN sales F ON T.ID=F.ID
where t.city = ROME
group by t.city,f.fname,f.lname
Output example
t.city, f.fname, f.lname January total
ROME John Doe 5 5
Grand Total 5 5
Did you try this?
group by GROUPING SETS((t.city, f.fname, f.lname), ())
To get Grand Total you'll need to change the select as well.
And, as a note: use single quotes only for string and date constants. Using them for column identifiers can lead to confusing and problems. Either drop the quotes altogether or use square braces or double quotes.
EDIT:
Without group by extensions or CTEs this is a pain. There is a trick to doing it with minimal modifications:
SELECT (case when which = 'normal' then t.city else 'Grand Total' end),
(case when which = 'normal' then f.fname end),
(case when which = 'normal' then f.lname end),
SUM(CASE datepart(month,ddate) WHEN 1 THEN 1 ELSE 0 END) AS 'January',
SUM(CASE datepart(month,ddate) WHEN 2 THEN 1 ELSE 0 END) AS 'February',
SUM(CASE datepart(month,ddate) WHEN 3 THEN 1 ELSE 0 END) AS 'March',
SUM(CASE datepart(month,ddate) WHEN 4 THEN 1 ELSE 0 END) AS 'April',
SUM(CASE datepart(month,ddate) WHEN 5 THEN 1 ELSE 0 END) AS 'May',
SUM(CASE datepart(month,ddate) WHEN 6 THEN 1 ELSE 0 END) AS 'June',
SUM(CASE datepart(month,ddate) WHEN 7 THEN 1 ELSE 0 END) AS 'July',
SUM(CASE datepart(month,ddate) WHEN 8 THEN 1 ELSE 0 END) AS 'August',
SUM(CASE datepart(month,ddate) WHEN 9 THEN 1 ELSE 0 END) AS 'September',
SUM(CASE datepart(month,ddate) WHEN 10 THEN 1 ELSE 0 END) AS 'October',
SUM(CASE datepart(month,ddate) WHEN 11 THEN 1 ELSE 0 END) AS 'November',
SUM(CASE datepart(month,ddate) WHEN 12 THEN 1 ELSE 0 END) AS 'December',
SUM(CASE datepart(year,ddate) WHEN 2014 THEN 1 ELSE 0 END) AS 'TOTAL'
from world T INNER JOIN
sales F
ON T.ID=F.ID cross join
(select 'normal' as which union all select 'total') as which
where t.city = ROME
group by (case when which = 'normal' then t.city else 'Grand Total' end),
(case when which = 'normal' then f.fname end),
(case when which = 'normal' then f.lname end);
(I'm not reformatting the rest of the query, but you should not use single quotes for column identifiers. Only use single quotes for string and date constants.)
Edit: Using GROUP BY ROLLUP(grouping columns) this will calculate the sum of the aggregated columns. By default it will return 'NULL' for all grouped columns but you can put an ISNULL wrapper around to get rid of it, or return a specific value.
SELECT ISNULL(t.city, 'Grand Total') AS [City],f.fname AS [Fname],f.lname AS [Lname],
SUM(CASE datepart(month,ddate) WHEN 1 THEN 1 ELSE 0 END) AS [January],
SUM(CASE datepart(month,ddate) WHEN 2 THEN 1 ELSE 0 END) AS [February],
SUM(CASE datepart(month,ddate) WHEN 3 THEN 1 ELSE 0 END) AS [March],
SUM(CASE datepart(month,ddate) WHEN 4 THEN 1 ELSE 0 END) AS [April],
SUM(CASE datepart(month,ddate) WHEN 5 THEN 1 ELSE 0 END) AS [May],
SUM(CASE datepart(month,ddate) WHEN 6 THEN 1 ELSE 0 END) AS [June],
SUM(CASE datepart(month,ddate) WHEN 7 THEN 1 ELSE 0 END) AS [July],
SUM(CASE datepart(month,ddate) WHEN 8 THEN 1 ELSE 0 END) AS [August],
SUM(CASE datepart(month,ddate) WHEN 9 THEN 1 ELSE 0 END) AS [September],
SUM(CASE datepart(month,ddate) WHEN 10 THEN 1 ELSE 0 END) AS [October],
SUM(CASE datepart(month,ddate) WHEN 11 THEN 1 ELSE 0 END) AS [November],
SUM(CASE datepart(month,ddate) WHEN 12 THEN 1 ELSE 0 END) AS [December],
SUM(CASE datepart(year,ddate) WHEN 2014 THEN 1 ELSE 0 END) AS [TOTAL]
FROM world T
INNER JOIN sales F ON T.ID=F.ID
WHERE t.city = ROME
GROUP BY ROLLUP(t.city,f.fname,f.lname)

Grouping by Month of TimeStamp

I am attempting to group by twice, once by an individual level field and then by the month of the timestamp field.
Little new to SQL but here's what I came up with after reading another SO post here: SQL query to group by month part of timestamp
SELECT
VwNIMUserDim.USER_EMAIL_ADDRESS,
VwNIMEventFct.NIM_USER_ID,
SUM(CASE WHEN NIM_EVENT_TYPE_ID = 880 THEN 1 ELSE 0 END) AS APP_OPEN,
SUM(CASE WHEN NIM_EVENT_TYPE_ID = 881 THEN 1 ELSE 0 END) AS AUTODL_SETTINGS_SAVE,
SUM(CASE WHEN NIM_EVENT_TYPE_ID = 882 THEN 1 ELSE 0 END) AS AUTO_QUERY_CONFIRM,
SUM(CASE WHEN NIM_EVENT_TYPE_ID = 883 THEN 1 ELSE 0 END) AS ISSUE_CLOSE,
SUM(CASE WHEN NIM_EVENT_TYPE_ID = 884 THEN 1 ELSE 0 END) AS ISSUE_DOWNLOAD,
SUM(CASE WHEN NIM_EVENT_TYPE_ID = 885 THEN 1 ELSE 0 END) AS ISSUE_DOWNLOAD_COMPLETE,
SUM(CASE WHEN NIM_EVENT_TYPE_ID = 886 THEN 1 ELSE 0 END) AS PICKER_SEND_PICKS
FROM RDMAVWSANDBOX.VwNIMEventFct
GROUP BY NIM_USER_ID, MONTH('EVENT_GMT_TIMESTAMP')
The error message returned by my SQL client, Teradata, says:
"SELECT FAILED Error 3706 Syntax error expected something in between ',' and the MONTH keyword.
This is my first time doing two things: Grouping By twice and using the Month function.
What am I doing wrong here? How do I group by email address users in each month?
There's no MONTH function in Teradata/Standard SQL, it's EXTRACT(YEAR/MONTH/DAY/HOUR/MINUTE/SECOND):
EXTRACT(MONTH FROM EVENT_GMT_TIMESTAMP)
Your query as written will result in a PRODUCT (Cartesian) JOIN between the VwNIMUserDIm and VwNIMEventFct tables (views). I have taken the liberty to modify the SQL based on your comments to the previous response:
SELECT
User_.USER_EMAIL_ADDRESS,
Event_.NIM_USER_ID,
Event_.EVENT_GMT_TIMESTAMP(FORMAT 'yyyy-mm')(char(7)) AS EVENT_MONTH,
SUM(CASE WHEN Event_.NIM_EVENT_TYPE_ID = 880 THEN 1 ELSE 0 END) AS APP_OPEN,
SUM(CASE WHEN Event_.NIM_EVENT_TYPE_ID = 881 THEN 1 ELSE 0 END) AS AUTODL_SETTINGS_SAVE,
SUM(CASE WHEN Event_.NIM_EVENT_TYPE_ID = 882 THEN 1 ELSE 0 END) AS AUTO_QUERY_CONFIRM,
SUM(CASE WHEN Event_.NIM_EVENT_TYPE_ID = 883 THEN 1 ELSE 0 END) AS ISSUE_CLOSE,
SUM(CASE WHEN Event_.NIM_EVENT_TYPE_ID = 884 THEN 1 ELSE 0 END) AS ISSUE_DOWNLOAD,
SUM(CASE WHEN Event_.NIM_EVENT_TYPE_ID = 885 THEN 1 ELSE 0 END) AS ISSUE_DOWNLOAD_COMPLETE,
SUM(CASE WHEN Event_.NIM_EVENT_TYPE_ID = 886 THEN 1 ELSE 0 END) AS PICKER_SEND_PICKS
FROM RDMAVWSANDBOX.VwNIMEventFct Event_
JOIN RDMAVWSANDBOX.VwNIMUserDim User_
ON Event_.NIM_USER_ID = User_.NIM_USER_ID
GROUP BY 1,2;
Possibly depending on database origin (MSSQL, mySQL, Oracle, DB2, Etc)
SELECT
VwNIMUserDim.USER_EMAIL_ADDRESS,
VwNIMEventFct.NIM_USER_ID,
MONTH(EVENT_GMT_TIMESTAMP),
SUM(CASE WHEN NIM_EVENT_TYPE_ID = 880 THEN 1 ELSE 0 END) AS APP_OPEN,
SUM(CASE WHEN NIM_EVENT_TYPE_ID = 881 THEN 1 ELSE 0 END) AS AUTODL_SETTINGS_SAVE,
SUM(CASE WHEN NIM_EVENT_TYPE_ID = 882 THEN 1 ELSE 0 END) AS AUTO_QUERY_CONFIRM,
SUM(CASE WHEN NIM_EVENT_TYPE_ID = 883 THEN 1 ELSE 0 END) AS ISSUE_CLOSE,
SUM(CASE WHEN NIM_EVENT_TYPE_ID = 884 THEN 1 ELSE 0 END) AS ISSUE_DOWNLOAD,
SUM(CASE WHEN NIM_EVENT_TYPE_ID = 885 THEN 1 ELSE 0 END) AS ISSUE_DOWNLOAD_COMPLETE,
SUM(CASE WHEN NIM_EVENT_TYPE_ID = 886 THEN 1 ELSE 0 END) AS PICKER_SEND_PICKS
FROM RDMAVWSANDBOX.VwNIMEventFct
GROUP BY NIM_USER_ID, MONTH(EVENT_GMT_TIMESTAMP)

date issue due to datediff function in between

I have following query:
SELECT
datediff(d, 0, sauda_date),
Scrip_Code,
SUM(CASE WHEN Buy_sell = 1 THEN Trade_Qty ELSE 0 END) AS BuyQty,
SUM(CASE WHEN Buy_sell = 1 THEN Market_Rate ELSE 0 END) AS BuyRate,
SUM(CASE WHEN Buy_sell = 1 THEN Trade_Qty * Market_Rate ELSE 0 END) AS BuyAmount,
SUM(CASE WHEN Buy_sell = 2 THEN Trade_Qty ELSE 0 END) AS SellQty,
SUM(CASE WHEN Buy_sell = 2 THEN Market_Rate ELSE 0 END) AS SellRate,
(CASE WHEN SUM(CASE WHEN Buy_sell = 1 THEN Trade_Qty ELSE 0 END) >
SUM(CASE WHEN Buy_sell = 2 THEN Trade_Qty ELSE 0 END) THEN 'BF'
ELSE 'BT' END ) as TradeType,
SUM(CASE WHEN Buy_sell = 2 THEN Trade_Qty * Market_Rate ELSE 0 END) AS SellAmount,
SUM(CASE WHEN Buy_sell = 1 THEN Trade_Qty ELSE 0 END) -
SUM(CASE WHEN Buy_sell = 2 THEN Trade_Qty ELSE 0 END) as NETQTY,
SUM(CASE WHEN Buy_sell = 1 THEN Trade_Qty * Market_Rate ELSE 0 END) -
SUM(CASE WHEN Buy_sell = 2 THEN Trade_Qty * Market_Rate ELSE 0 END)as NetAmt,
SUM(CASE WHEN Buy_sell = 2 THEN Trade_Qty * Market_Rate ELSE 0 END) -
SUM(CASE WHEN Buy_sell = 1 THEN Trade_Qty * Market_Rate ELSE 0 END) as PNLAmt
FROM tradeFile
where Inst_Type = 'FUTIDX'
OR Inst_Type='FUTSTK'
and Sauda_Date = convert(datetime,'1 Mar 2013')
group by Scrip_Code, ExpiryDate, datediff(d,0,sauda_date)
Result:
This query is for taking sum of Buy_Qty,Sell_Qty datewise.[With ref to this quest:not able to get individual date in query result
But as we can see datediff(d,0,sauda_date) column (i.e. first column) is giving me some result, but i wanted to add sauda_date also in this result as a date.
what changes i should make in this query.
I tried it by adding directly sauda_date in query but it gives me error.
Please guid me.
If you use a GROUP BY in your query then (in case of T-SQL) in the field's part of a query you can use only fields from GROUP BY or aggregate functions (SUM, COUNT,....). So you can't add just sauda_date. You should add it with aggregate function. For example MIN(sauda_date). OR you can add it to GROUP BY part.
Not sure with your result requirement..
simply adding sauda_date in select list should not give error if you includ it in group by list, i have tried belwo and its working.
Select datediff(d,0,f.Date),
sum(f.price),
f.OrderID,
f.Date
from test f
group by f.Date,OrderID,datediff(d,0,f.Date)
Else
you can use self join to get only sauda date joining main result on your key column

sum function not working properly

My database in SQL Server 2005:
My query is:
SELECT *
FROM TRADEFILE
WHERE CONVERT(DATETIME,SAUDA_DATE) LIKE 'MAR 1 2013%'
AND SCRIP_CODE='DLF' AND INST_TYPE LIKE 'FUT%'
This gives me result:
In this Buy=1 and Sell=2.
If we make sum of Buy Qty i.e. buy_sell=1 then it is 3000
and when we make sum for sell trade qty i.e. buy_sell=2 then it is 3000
But when I fire this query for getting same result as follows:
select
CONVERT(VARCHAR(11),sauda_date) AS sauda_date,
SUM(CASE
WHEN Buy_sell = 1 and scrip_code='DLF'
and Sauda_Date between convert(datetime,'01/03/2013')
and convert(datetime,'06/04/2013')
THEN Trade_Qty ELSE 0 END) AS BuyQty,
SUM(CASE
WHEN Buy_sell = 2 and scrip_code='DLF'
and Sauda_Date between convert(datetime,'01/03/2013')
and convert(datetime,'06/04/2013')
THEN Trade_Qty ELSE 0 END) AS SellQty ,
SUM(CASE
WHEN Buy_sell = 1 and scrip_code='DLF'
THEN Trade_Qty ELSE 0 END)
-SUM(CASE
WHEN Buy_sell = 2 and scrip_code='DLF'
THEN Trade_Qty ELSE 0 END) AS CarryForword
from tradefile
where scrip_code='DLF'
group by CONVERT(VARCHAR(11),sauda_date)
It gives me result as:
i.e. BuyQty=5000 and sellQty is 4000
while we have calculated it as 3000 and 3000 respectively.
How can it be different? is my sum() function working wrong??
Is my query is wrong?
The conditions are quite different so it is just plausible that the results are too.
Examples:
In your first query, you have a condition for PARTY_CODE. This is completely missing in the second query.
The same goes for INST_TYPE
The condition for SAUDA_DATE is very different. The first query only queries March, 1st, while the second queries everything between March, 1st and April, 6th.
I understood that first query you have given, has 3000 for buyin_qty and sell_qty.
In your second query which is having CASE statements misses some of your where condition from First query
AND PARTY_CODE='0L036'
AND INST_TYPE LIKE 'FUT%'
This should work:
select
CONVERT(VARCHAR(11),sauda_date) AS sauda_date,
SUM(CASE WHEN Buy_sell = 1 THEN Trade_Qty ELSE 0 END) AS BuyQty,
SUM(CASE WHEN Buy_sell = 2 THEN Trade_Qty ELSE 0 END) AS SellQty ,
SUM(CASE WHEN Buy_sell = 1 THEN Trade_Qty ELSE 0 END)
-SUM(CASE WHEN Buy_sell = 2 THEN Trade_Qty ELSE 0 END) AS CarryForword
from tradefile
where scrip_code='DLF'
group by CONVERT(VARCHAR(11),sauda_date)