Grouping by Month of TimeStamp - sql

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)

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;

Sum case statement

The below SQL is returning 'Cannot perform an aggregate function on an expression containing an aggregate or a subquery.', can anyone help?
SELECT
sum(case when Frequency = 'Monthly' then ISNULL(SUM(Amount),0.0) else 0 end) +
sum(case when Frequency = '4 Weekly' then ISNULL(SUM(Amount),0.0) / 2 else 0 end) +
sum(case when Frequency = 'Fortnightly' then ISNULL(SUM(Amount),0.0) / 3 else 0 end) +
sum(case when Frequency = 'Weekly' then ISNULL(SUM(Amount),0.0) / 5 else 0 end)
FROM TableWHERE Id = 1
If you want conditional aggregation, you only want one sum():
SELECT sum(case when Frequency = 'Monthly' then Amount else 0 end) +
sum(case when Frequency = '4 Weekly' then Amount / 2 else 0 end) +
sum(case when Frequency = 'Fortnightly' then Amount / 3 else 0 end) +
sum(case when Frequency = 'Weekly' then Amount,0.0) / 5 else 0 end)
FROM Table
WHERE Id = 1;
I think you want to do something like
sum(case when Frequency = 'Monthly' then ISNULL(Amount,0.0) else 0 end)
SELECT
sum(case when Frequency = 'Monthly' then ISNULL(Amount,0.0) else 0 end) +
sum(case when Frequency = '4 Weekly' then ISNULL(Amount,0.0) / 2 else 0 end) +
sum(case when Frequency = 'Fortnightly' then ISNULL(Amount,0.0) / 3 else 0 end) +
sum(case when Frequency = 'Weekly' then ISNULL(Amount,0.0) / 5 else 0 end)
FROM Table
WHERE Id = 1

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)

Creating a view with columns based on where clauses

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.

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