SQL Server - Pivot: Counting/Reporting number of records insert in 100 Staging Tables - sql

We currently got 100 staging tables which are loaded everyday.
I'm struggling to write a query - which give me sort PIVOT result - showing number of records inserted into staging tables by Day.
Name of tables Day 1 Day 2 Day 3 Day 4 Day 5
--------------------------------------------------------------
AAAAA 100 50 30 60 90
Regards

You need a few different steps.
DATEDIFF(DAY, <timestamp>, getDate()) will get you the number of days ago for a record.
Using CASE inside a SUM, you can then do something like...
SELECT
'AAAA' AS TableName,
SUM(CASE WHEN DATEDIFF(DAY, <timestamp>, getDate()) = 1 THEN 1 ELSE 0 END) AS Day1,
SUM(CASE WHEN DATEDIFF(DAY, <timestamp>, getDate()) = 2 THEN 1 ELSE 0 END) AS Day2,
SUM(CASE WHEN DATEDIFF(DAY, <timestamp>, getDate()) = 3 THEN 1 ELSE 0 END) AS Day3,
SUM(CASE WHEN DATEDIFF(DAY, <timestamp>, getDate()) = 4 THEN 1 ELSE 0 END) AS Day4,
etc, etc
FROM
AAAA
UNION ALL
SELECT
'BBBB' AS TableName,
SUM(CASE WHEN DATEDIFF(DAY, <timestamp>, getDate()) = 1 THEN 1 ELSE 0 END) AS Day1,
SUM(CASE WHEN DATEDIFF(DAY, <timestamp>, getDate()) = 2 THEN 1 ELSE 0 END) AS Day2,
SUM(CASE WHEN DATEDIFF(DAY, <timestamp>, getDate()) = 3 THEN 1 ELSE 0 END) AS Day3,
SUM(CASE WHEN DATEDIFF(DAY, <timestamp>, getDate()) = 4 THEN 1 ELSE 0 END) AS Day4,
etc, etc
FROM
BBBB
UNION ALL
etc, etc
That does require the code repeating itself for every table you are querying. But I think you're stuck doing that in one way or another no matter what.
An alternative would be to put a trigger on each table, and as data is inserted/deleted, update a tracking table with the new details. That involves writing 100 triggers instead of 100 unions.
Without writing Dynamic SQL, I'm not aware of any other fundamentally different ways of doing this to aboid writing a snippet of code 100 times...

Related

Sum all the repeat event based on dates, aggregate by 7 days ,30 days >30 days

I am trying to calculate repeat if there is a repeat event in 3,7,30 and >30 days.
In the image below the the yellow is the sql table,
the green is transformation needed, where I find out what is the first event for Event A and Event B. and then find out what is the gap between the first event of A and next events of A.
Finally I need to aggregate and achieve the blue table where data is aggregate for the unique events.
I have been trying to achieve this in SQL but I am stuck as I am not sure how to filter and loop.
Original data and Expected outcome image
DECLARE #reference_date DATE = '2022-08-02';
SELECT
Event,
MIN(Date) as First_date,
SUM(CASE WHEN DATEDIFF(day, #reference_date, Date) BETWEEN 1 AND 2
THEN 1 ELSE 0 END) as "Within_3_Days",
SUM(CASE WHEN DATEDIFF(day, #reference_date, Date) BETWEEN 1 AND 6
THEN 1 ELSE 0 END) as "Within_7_Days",
SUM(CASE WHEN DATEDIFF(day, #reference_date, Date) BETWEEN 1 AND 29
THEN 1 ELSE 0 END) as "Within_30_Days",
SUM(CASE WHEN DATEDIFF(day, #reference_date, Date)>=30
THEN 1 ELSE 0 END) as ">_30_Days"
FROM event e0
GROUP BY Event
output:
Event
First_date
Within_3_Days
Within_7_Days
Within_30_Days
>_30_Days
A
2022-08-01
0
1
2
1
B
2022-09-15
0
0
0
1
The #reference_date is used to reference the date needed to determine if a date is within x days.
DBFIDDLE
P.S. I use dates in the format YYYY-MM-DD, because that's the only way I am SURE about the ordering of the Day and the Month part.
EDIT:
When using the first date of an event to determine the 'within' columns, you can do:
SELECT
e0.Event,
MIN(e0.Date) as First_date,
SUM(CASE WHEN DATEDIFF(day, e1.Date, e0.Date) BETWEEN 1 AND 2
THEN 1 ELSE 0 END) as "Within_3_Days",
SUM(CASE WHEN DATEDIFF(day, e1.Date, e0.Date) BETWEEN 1 AND 6
THEN 1 ELSE 0 END) as "Within_7_Days",
SUM(CASE WHEN DATEDIFF(day, e1.Date, e0.Date) BETWEEN 1 AND 29
THEN 1 ELSE 0 END) as "Within_30_Days",
SUM(CASE WHEN DATEDIFF(day, e1.Date, e0.Date)>=30
THEN 1 ELSE 0 END) as ">_30_Days"
FROM event e0
INNER JOIN (SELECT Event,MIN(Date) as Date from event GROUP BY Event) e1 on e1.Event=e0.Event
GROUP BY e0.Event
see: DBFIDDLE2

Get data of 2 different dates in 2 different columns sql

I have a sql table having columns Name, VisitingDate, StayTime
I want a query which can give me data in which in 1 column I can get data of thismonthvisit and other column I can get data of lastmonthvisit and in 3rd column I can data of summation of StayTime of particular person .
Database Table : --
Name
VisitingDate
StayTime(in minutes)
A
2021-04-20
5
A
2021-04-21
15
A
2021-03-20
10
B
2021-03-20
5
Result Wanted : --
Name
Thismonthvisit
TotalStayTimeThismonth(in minutes)
LastmonthVisit
TotalStayTimelastmonth(in minutes)
A
2
20
1
10
B
0
0
1
5
Here is what you are looking for :
select name,
SUM(CASE WHEN FORMAT(VisitingDate, 'YYYYMM') = FORMAT(getdate(),'YYYYMM') THEN 1 ELSE 0 END) AS ThisMonthVisit,
SUM(CASE WHEN FORMAT(VisitingDate, 'YYYYMM') = FORMAT(getdate(),'YYYYMM') THEN StayTime ELSE 0 END) AS TotalStayTimeThisMonth,
SUM(CASE WHEN FORMAT(VisitingDate, 'YYYYMM') = FORMAT(dateadd(month, -1, getdate()),'YYYYMM') THEN 1 ELSE 0 END) AS LastMonthVisit,
SUM(CASE WHEN FORMAT(VisitingDate, 'YYYYMM') = FORMAT(dateadd(month, -1, getdate()),'YYYYMM') THEN StayTime ELSE 0 END) AS TotalStayTimeLastMonth
from MyTable
where FORMAT(VisitingDate, 'YYYYMM') > FORMAT(dateadd(month, -2, getdate()),'YYYYMM')
group by Name
SEE DEMO HERE
You can use aggregation:
select name,
sum(case when month(visitingdate) = month(getdate())
then 1 else 0
end) as cnt_thismonth,
sum(case when month(visitingdate) = month(getdate())
then staytime else 0
end) staytime_thismonth,
sum(case when month(visitingdate) <> month(getdate())
then 1 else 0
end) as cnt_lastmonth,
sum(case when month(visitingdate) <> month(getdate())
then staytime else 0
end) staytime_lastmonth
from t
where visitingdate >= dateadd(month, -1, datefromparts(year(getdate()), month(getdate()), 1))
group by name;

T-SQL pivot inventory aging by day range

Writing a T-SQL statement to display items in inventory broken out by day range (pivot).
For example from this inventory table:
ItemName
DateCreated
PO_ID
A
2020-10-07
0
B
2020-10-07
1
A
2020-10-22
2
A
2020-10-22
2
A
2020-10-22
2
B
2020-10-29
3
Would like to generate the bellow results (typically a pivot table), showing the number of pieces per ItemName per day range. The date used to calculate the # of days since DateCreated would be the day the report was ran or passed in as a parameter - in the example shown here, the date used is from '2020-11-07':
ItemName
0-10 days
11-20 days
21-30 days
>30 days
A
0
3
0
1
B
1
0
0
1
Not sure what would be the best way to write the statement to generate the above results?
I would use conditional aggregation:
select itemName,
sum(case when datediff(day, dateCreated, getdate()) <= 10 then 1 else 0 end) as days_0_10,
sum(case when datediff(day, dateCreated, getdate()) > 10 and
datediff(day, dateCreated, getdate()) <= 20
then 1 else 0 end) as days_11_20,
sum(case when datediff(day, dateCreated, getdate()) > 20 and
datediff(day, dateCreated, getdate()) <= 30
then 1 else 0 end) as days_21_30,
sum(case when datediff(day, dateCreated, getdate()) > 30 then 1 else 0 end) as days_31
from t
group by itemName
I would use something similar to the following query SQL Server:
SELECT *
FROM
(
SELECT [ItemName],[PO_ID],
CASE
WHEN DATEDIFF(day, DateCreated, getdate()) BETWEEN 0 AND 10 THEN '0-10 days'
WHEN DATEDIFF(day, DateCreated, getdate()) BETWEEN 11 AND 20 THEN '11-20 days'
WHEN DATEDIFF(day, DateCreated, getdate()) BETWEEN 21 AND 30 THEN '21-30 days'
ELSE '>30 days'
END AS PeriodCreated
FROM [TableName])
) src
pivot
(
COUNT(PO_ID)
FOR PeriodCreated in ([0-10 days], [11-20 days], [>30 days])
) piv

How to count different data on the basis of date for distinct users in SQL Server

I have the following schema :
Table T
|ITEM_ID| |USER_ID| | DUE_DATE |
1 1 2018-01-2
1 1 2018-01-2
1 1 2018-01-3
1 2 2018-01-2
2 1 2018-01-2
2 2 2018-01-2
What I want is to get the count of actions performed by a unique user on that particular day, one week.
This is the select query which I'm using however it does not takes care of the fact about unique user.
select ITEM_ID,
sum(case when cast(due_date as date) = cast(getdate() as date) then 1 else 0 end) as today,
sum(case when cast(due_date as date) >= cast(getdate() - 7 as date) then 1 else 0 end) as week,
sum(case when cast(due_date as date) >= dateadd(month, -1, cast(getdate() as date)) then 1 else 0 end) as month
from t
group by ITEM_ID;
How can I the select count of actions performed by a unique user on that particular day, one week.
For example : let's suppose today is 2018-01-2
So the expected result should be :
ITEM_ID, COUNT_TODAY, COUNT_TOMORROW
1 2 1
2 1 1
What I need is the unique user performing the transaction of that particular item type for that day.
That is in the above example, the user having id 1 performed the transaction of type 1 2 times on 2018-01-2. So it should be counted as 1 instead of 2.
How can I achieve this?
Is this what you want.
select USER_ID, ITEM_ID,
sum(case when cast(due_date as date) = cast(getdate() as date) then 1 else 0 end) as today,
sum(case when cast(due_date as date) >= cast(getdate() - 7 as date) then 1 else 0 end) as week,
sum(case when cast(due_date as date) >= dateadd(month, -1, cast(getdate() as date)) then 1 else 0 end) as month
from t
group by USER_ID, ITEM_ID;

Group by year in sql

I am trying to group by year but was not able to do.I can get the column count but not year wise. this is what i tried.
select t_contract ,
sum(CASE t_contract when '18' then 1 else 0 end) as XL,
sum(CASE t_contract when '01' then 1 else 0 end) as VC,
sum(CASE t_contract when '75' then 1 else 0 end) as AN,
sum(CASE t_contract when '48' then 1 else 0 end) as CS
from icps.dbo.tickets
WHERE
t_date_time_issued >= DATEADD(year, -6, GETDATE())
GROUP BY contract
.. but i want to add year .. where i have t_date_time _issued column.
My another query is I have a column called t_zone_name and I want to sum all the rows where t_zone_anme like '%ICeland%' an i tried this:
sum(CASE t_zone_name like '%ICeland%' then 1 else 0 end) as ICELAND
but I get an error on statement like... thanks in advance.
LIKE
YEAR XL VC AN CS total
2010 50 50 50 50 200
2011 5 5 5 5 20
Try the below query:
SELECT t_contract, YEAR(t_date_time_issued) As Yr, SUM(CASE WHEN t_zone_name like '%ICeland%' THEN 1 ELSE 0 END) AS ICELAND
SUM(CASE t_contract when '18' then 1 else 0 end) as XL,
SUM(CASE t_contract when '01' then 1 else 0 end) as VC,
SUM(CASE t_contract when '75' then 1 else 0 end) as AN,
SUM(CASE t_contract when '48' then 1 else 0 end) as CS
FROM icps.dbo.tickets
WHERE YEAR(t_date_time_issued) >= (YEAR(GetDate()) - 6)
GROUP BY t_contract, YEAR(t_date_time_issued)
You might need change the order of t_contract and YEAR(t_date_time_issued) depending on which grouping you want to apply first.
As suggested by #ray I have replaced DATEPART(yyyy, t_date_time_issued) >= DATEPART(yyyy, DATEADD(year, -6, GETDATE())) with year(t_date_time_issued) >= (year(GetDate()) - 6)
If you want to group by year, in sql server, you might
GROUP BY DATEDIFF(year,t_date_time_issued, GETDATE())
In other DB engine, usually has method to get year part, or use substring to get year part from a time string.