SQL return last 30 records on the same year - sql

In my query I want to return only the records that saved in last 30 days within same year but my query returns all the records that happened in last 30 days from today's month and day regardless of the year. I don't know what the reason
I tried the condition in smaller query and it gives right result.
select top 10000
cb.billNo , MAX(cb.subCategoryID) subCategory ,
Max(cb.cateogryID) categoryID ,
MAX(tracking.date ) trackingDate,
Max(Station.Code) Dest,Max(cb.picesCount) PieceCount,
Max(case when cb.productCount > 1 then 1 else 0 end) isMultiProduct ,
Max(case when tt.ID = 1 and (cb. subCategoryID = 65 or cb.
subCategoryID
= 56) then 1 else 0 end) isReceived,
from CustomerBillss cb
join Tracking on cw.billNo = Tracking.billNo
join trackingtype tt on Tracking.TrackingTypeID = tt.ID
join Station on cb.destinationStationID = Station.ID
where
tracking.date > dateadd(dd,-30,cast(getdate() as date))
--(YEAR(tracking.Date) = YEAR(GETDATE()) AND
--tracking.Date >= DATEADD(day,-30,GETDATE()))
AND
cb. cateogryID in (1, 3)
AND Tracking.TrackingTypeID not in (8 , 4 ,20)
AND cb.subCategoryID != 30 or (
subCategoryID = 30 and cb.DestinationStationID = tracking.StationID)
group by cb.billNo;

Just uncomment the year filter in your select
select top 10000
cb.billNo , MAX(cb.subCategoryID) subCategory ,
Max(cb.cateogryID) categoryID ,
MAX(tracking.date ) trackingDate,
Max(Station.Code) Dest,Max(cb.picesCount) PieceCount,
Max(case when cb.productCount > 1 then 1 else 0 end) isMultiProduct ,
Max(case when tt.ID = 1 and (cb. subCategoryID = 65 or cb.
subCategoryID
= 56) then 1 else 0 end) isReceived,
from CustomerBillss cb
join Tracking on cw.billNo = Tracking.billNo
join trackingtype tt on Tracking.TrackingTypeID = tt.ID
join Station on cb.destinationStationID = Station.ID
where
tracking.date > dateadd(dd,-30,cast(getdate() as date))
(YEAR(tracking.Date) = YEAR(GETDATE()) AND
--tracking.Date >= DATEADD(day,-30,GETDATE()))
AND
cb. cateogryID in (1, 3)
AND Tracking.TrackingTypeID not in (8 , 4 ,20)
AND cb.subCategoryID != 30 or (
subCategoryID = 30 and cb.DestinationStationID = tracking.StationID)
group by cb.billNo;

Related

Inner Join Taking Forever To Run In Big Query

I have a query that is taking forever to do an inner join. It runs for 6 hours and then times out. The query is:
SELECT
a.*,
b.total_video,
b.total_initial_video,
b.total_discovery,
b.total_sub_video,
b.total_sub_initial_video,
b.total_sub_discovery,
FROM temp_table.source_stage_ a
INNER JOIN temp_table.source_stage2_ b
ON (a.day = b.day
AND a.state_desc = b.state_desc
AND a.package_desc = b.package_desc
AND a.brand = b.v1_brand
))
temp_table.source_stage_ is
create or replace table temp_table.source_stage_ as (
select *,
case
when cycle = 0
then 'Trial'
when cycle = 1
then '1 Month'
when cycle between 2 and 3
then '2 - 3 Months'
when cycle between 4 and 5
then '4 - 5 Months'
when cycle >= 6
then '6+ Months'
end as group,
from(
select
*,
case when active_days < 0 then 0 else cast( ceil( ( case when active_days < 1 then 1 else active_days end ) / 30 ) as int64 ) end cycle, from (
SELECT
t.activation_dt,
t.end_dt,
t.trial_start_dt,
t.start_dt,
date_diff(p.day_dt,coalesce(activation_dt,trial_start_dt,start_dt),DAY) as active_days,
date_diff(p.day_dt,coalesce(start_dt),DAY) as active_days,
p.day_dt,
state_desc,
package_desc,
v1_brand,
sc.scarp_group,
p.last_touch,
SUM(p.video_playback_ind) as video_start_cnt,
SUM(CASE WHEN cd_path_rank_nbr = 1 THEN p.video_playback_ind ELSE 0 END) as initial_video_start_cnt,
SUM(CASE WHEN p.video_playback_ind = 1 AND f.session_nbr IS NOT NULL THEN 1 ELSE 0 END) as discovery_start_cnt,
COUNT(DISTINCT(p.registration_id_nbr)) as sub_video_start_cnt,
COUNT(DISTINCT(CASE WHEN cd_path_rank_nbr = 1 THEN p.registration_id_nbr ELSE NULL END)) as sub_initial_video_start_cnt,
COUNT(DISTINCT(CASE WHEN f.session_nbr IS NOT NULL THEN p.registration_id_nbr ELSE NULL END)) as sub_discovery_start_cnt,
FROM table1 p
LEFT JOIN table2 f
ON p.day_dt = f.day_dt
AND p.session_nbr = f.session_nbr
AND f.day_dt = '2023-02-11'
LEFT JOIN table3 t
on (p.registration_id_nbr = t.user_id_cd
and p.day_dt between t.activation_dt and t.end_dt)
left join table4 as sc
on (p.registration_id_nbr is not null
and sc.user_id_cd is not null
and p.registration_id_nbr = sc.user_id_cd
and p.day_dt between sc.period_start_dt and sc.period_end_dt)
WHERE p.day_dt = '2023-02-11'
AND p.video_playback_ind = 1
AND p.report_suite_id NOT IN ('cb', 'ic', 'bs')
AND LOWER(p.state_desc) IN ("tr", "s", "di of")
AND lower(package_desc) IN ('cf', 'lc', 'lcp', 'cf-s', 'lc-s', 'lcp-s')
AND v1_brand LIKE 'pp_%'
GROUP BY 1,2,3,4,5,6,7,8,9,10,11,12
)))
temp_table.source_stage2_ is
create or replace table temp_table.source_stage2 as (
select *,
case
when tenure_cycle = 0
then 'Trial'
when tenure_cycle = 1
then '1 Month'
when tenure_cycle between 2 and 3
then '2 - 3 Months'
when tenure_cycle between 4 and 5
then '4 - 5 Months'
when tenure_cycle >= 6
then '6+ Months'
end as tenure_group,
from(
select
*,
case when paid_active_days < 0 then 0 else cast( ceil( ( case when paid_active_days < 1 then 1 else paid_active_days end ) / 30 ) as int64 ) end tenure_cycle, from (
SELECT
t.activation_dt,
t.end_dt,
t.trial_start_dt,
t.paid_start_dt,
date_diff(p.day_dt,coalesce(activation_dt,trial_start_dt,paid_start_dt),DAY) as active_days,
date_diff(p.day_dt,coalesce(paid_start_dt),DAY) as paid_active_days,
p.day_dt,
state_desc,
package_desc,
v1_brand_nm,
sc.scarp_group,
SUM(p.video_playback_ind) as total_video,
SUM(CASE WHEN cd_path_rank_nbr = 1 THEN p.video_playback_ind ELSE 0 END) as total_initial_video,
SUM(CASE WHEN p.video_playback_ind = 1 AND f.v88_player_session_nbr IS NOT NULL THEN 1 ELSE 0 END) as total_discovery,
COUNT(DISTINCT(p.v69_registration_id_nbr)) as total_sub_video,
COUNT(DISTINCT(CASE WHEN cd_path_rank_nbr = 1 THEN p.v69_registration_id_nbr ELSE NULL END)) as total_sub_initial_video,
COUNT(DISTINCT(CASE WHEN f.v88_player_session_nbr IS NOT NULL THEN p.v69_registration_id_nbr ELSE NULL END)) as total_sub_discovery,
FROM `table1` p
LEFT JOIN `table2` f
ON p.day_dt = f.day_dt
AND p.v88_player_session_nbr = f.v88_player_session_nbr
AND f.day_dt = '2023-02-11'
LEFT JOIN `table3` t
on (p.registration_id_nbr = t.cbs_reg_user_id_cd
and p.day_dt between t.activation_dt and t.end_dt)
left join `table4` as sc
on (p.registration_id_nbr is not null
and reg_user_id_cd is not null
and p.registration_id_nbr = reg_user_id_cd
and p.day_dt between sc.period_start_dt and sc.period_end_dt)
WHERE p.day_dt = '2023-02-11'
AND p.video_playback_ind = 1
AND p.report_suite_id NOT IN ('cb', 'ic', 'bs')
AND LOWER(p.state_desc) IN ("tr", "s", "di of")
AND lower(package_desc) IN ('cf', 'lc', 'lcp', 'cf-s', 'lc-s', 'lcp-s')
AND v1_brand_nm LIKE 'pp_%'
GROUP BY 1,2,3,4,5,6,7,8,9,10,11
)))
The last two queries, temp_table.source_stage_ and temp_table.source_stage2_ create temp tables and are the same except one column that is added to the first one

How could I adapt this query to work over multiple years?

This query pulls data from a VistaDB and produces info on the number of courses started in each month of the year from people in different countries.
Select c.CountryName As Country,
Count (case When Month( ch.CourseStarted ) = 1 Then 1 End) As Jan19,
Count (case when Month(ch.CourseStarted ) = 2 Then 1 End) as Feb19,
Count (case When Month(ch.CourseStarted ) = 3 Then 1 End) as Mar19,
Count (case When Month(ch.CourseStarted ) = 4 Then 1 End) as Apr19,
Count (case When Month(ch.CourseStarted ) = 5 Then 1 End) as May19,
Count (case When Month(ch.CourseStarted ) = 6 Then 1 End) as Jun19,
Count (case When Month(ch.CourseStarted ) = 7 Then 1 End) as Jul19,
Count (case When Month(ch.CourseStarted ) = 8 Then 1 End) as Aug19,
Count (case When Month(ch.CourseStarted ) = 9 Then 1 End) as Sep19,
Count (case When Month(ch.CourseStarted ) = 10 Then 1 End) as Oct19,
Count (case When Month(ch.CourseStarted ) = 11 Then 1 End)as Nov19,
Count (case When Month(ch.CourseStarted ) = 12 Then 1 End) as Dec19
From Country As c
Inner Join CourseHistory As ch On c.Oid = ch.Country
Where (ch.CourseStarted >= '2019-01-01' And
ch.CourseStarted <= '2019-12-31')
Group By c.CountryName
Order by c.CountryName;
My question is would it be possible to make this semi-dynamic so that if I were to make the final date in the where clause '2022-12-31' I could get a rafft of colums for each month of each year?

TSQL Pivot table rows to columns

I've got some data in a table that looks like the following. I'm trying to run a query that will get my data on a single row per requestId. I don't need the dates or the denial reason just the eprojman and apvStatus for each groupId
requestId - projMan1 - apvStatus1 - projMan2 - apvStatus2 - projMan3 - apvStatus3 etc.. for all 5 groupIds
requestId
groupId
entryDate
approvalDate
apvStatus
projMan
denialReason
1
1
2020-11-02
2019-07-25
APPROVED
rx1942
NULL
1
2
2020-11-02
2019-07-25
APPROVED
ma2674
NULL
1
3
2020-11-02
2019-07-25
APPROVED
cb9097
NULL
1
4
2020-11-02
2019-07-25
APPROVED
bj1763
NULL
1
5
2020-11-02
2019-07-25
APPROVED
tr5972
NULL
2
1
2020-11-02
NULL
NOT APPROVED
NULL
6
2
2
2020-11-02
NULL
PENDING
ma2674
NULL
2
3
2020-11-02
NULL
PENDING
cb9097
NULL
2
4
2020-11-02
NULL
PENDING
bj1763
NULL
2
5
2020-11-02
NULL
PENDING
tr5972
NULL
I've been trying to use a PIVOT table but all the examples I find involves summing data or something. I just pretty much want to take the 5 rows and turn it into 1 for each requestID
The only thing I've been able to come up with is to select from the same table 5 times for each groupID and union it but that's slower than heck. Got to be a better way
Thanks.
Current query:
select group1.requestId
, group1.apvStatus as apvStatus1
, group1.projMan as projMan1
, group2.apvStatus as apvStatus2
, group2.projMan as projMan2
, group3.apvStatus as apvStatus3
, group3.projMan as projMan3
,group4.apvStatus as apvStatus4
, group4.projMan as projMan4
,group5.apvStatus as apvStatus5
, group5.projMan as projMan5
,group1.denialReason
INTO #TEMPBAOrganized
from (
select requestId, apvStatus, projMan, denialReason from #TEMPBULKAPPROVAL where groupId = 1) group1
INNER JOIN
(select requestId, apvStatus, projMan, denialReason from #TEMPBULKAPPROVAL where groupId = 2) group2
on group1.requestId = group2.requestId
INNER JOIN
(select requestId, apvStatus, projMan from #TEMPBULKAPPROVAL where groupId = 3) group3
on group1.requestId = group3.requestId
INNER JOIN
(select requestId, apvStatus, projMan from #TEMPBULKAPPROVAL where groupId = 4) group4
on group1.requestId = group4.requestId
INNER JOIN
(select requestId, apvStatus, projMan from #TEMPBULKAPPROVAL where groupId = 5) group5
on group1.requestId = group5.requestId
For pivoting of multiple column, it is easier to use CASE expression with aggregate.
select t.requestId,
projMan1 = max(case when t.groupId = 1 then t.projMan end),
apvStatus1 = max(case when t.groupId = 1 then t.apvStatus end),
projMan2 = max(case when t.groupId = 2 then t.projMan end),
apvStatus2 = max(case when t.groupId = 2 then t.apvStatus end),
projMan3 = max(case when t.groupId = 3 then t.projMan end),
apvStatus3 = max(case when t.groupId = 3 then t.apvStatus end),
projMan4 = max(case when t.groupId = 4 then t.projMan end),
apvStatus4 = max(case when t.groupId = 4 then t.apvStatus end),
projMan5 = max(case when t.groupId = 5 then t.projMan end),
apvStatus5 = max(case when t.groupId = 5 then t.apvStatus end)
from #TEMPBULKAPPROVAL t
group by t.requestId
Note : max is also an aggregate function
You can do it with something like this:
SELECT
requestId,
approvalDate_1 = MAX(approvalDate_1),
approvalDate_2 = MAX(approvalDate_2),
approvalDate_3 = MAX(approvalDate_3),
approvalDate_4 = MAX(approvalDate_4),
approvalDate_5 = MAX(approvalDate_5),
projMan_1 = MAX(projMan_1),
projMan_2 = MAX(projMan_2),
projMan_3 = MAX(projMan_3),
projMan_4 = MAX(projMan_4),
projMan_5 = MAX(projMan_5)
FROM
(
SELECT
requestId,
groupId,
approvalDate,
projMan,
'approvalDate_' + CAST( groupId AS VARCHAR(2)) AS approvalDatePivot,
'projMan_' + CAST( groupId AS VARCHAR(2)) AS projManPivot
FROM
#tbl
) T
PIVOT (
MAX(approvalDate) FOR approvalDatePivot IN ([approvalDate_1],[approvalDate_2],[approvalDate_3],[approvalDate_4],[approvalDate_5])
) pvt_1
PIVOT (
MAX(projMan) FOR projManPivot IN ([projMan_1],[projMan_2],[projMan_3],[projMan_4],[projMan_5])
) pvt_2
GROUP BY requestId

Get COUNT with a condition from a joined table

I have a table SyncHistory:
SyncHistoryId SyncType SyncDateTime
-----------------------------------------------------
55 1 2017-11-28 09:30:51.810
56 1 2017-11-28 10:30:32.123
And then another table SyncDetails:
SyndDetailId SyncHistoryId ItemId ItemCreated ItemChanged
---------------------------------------------------------------------------
98 55 12345 1 0
99 55 23183 1 0
100 55 87687 0 1
101 55 23234 0 0
102 55 23222 0 0
103 56 9928 1 0
What I'm trying to do is create a query that gives me this:
Sync Data New Existing & Changed Existing & Not Changed
---------------------------------------------------------------------------
11/28/2017 9:30am 2 1 2
11/28/2017 10:30am 1 0 0
This is what I'm trying:
SELECT
sh.SyncHistoryId
, sh.SyncDateTime
, count(sd1.SyncDetailId) AS Created
, count(sd2.SyncDetailId) AS ExistingChanged
, count(sd3.SyncDetailId) AS ExistingNotChanged
FROM
SyncHistory sh
LEFT JOIN SyncDetails sd1 ON sh.SyncHistoryId = sd1.SyncHistoryId AND sd1.ItemCreated = 1 AND sd1.ItemChanged = 0
LEFT JOIN SyncDetails sd2 ON sh.SyncHistoryId = sd2.SyncHistoryId AND sd2.ItemCreated = 0 AND sd2.ItemChanged = 1
LEFT JOIN SyncDetails sd3 ON sh.SyncHistoryId = sd3.SyncHistoryId AND sd3.ItemCreated = 0 AND sd3.ItemChanged = 0
WHERE
sh.SyncType = 1
GROUP BY
sh.SyncHistoryId
, sh.SyncDateTime
ORDER BY
sh.SyncDateTime DESC
But, none of the resulting counts are accurate. I'm doing something wrong, but not sure what.
SELECT h.SyncDateTime,
SUM(case when d.ItemCreated = 1 then 1 else 0 end) as New,
SUM(case when d.ItemChanged = 1 then 1 else 0 end) as [Existing & Changed],
SUM(case when d.ItemCreated = 0 and d.ItemChanged = 0 then 1 else 0 end) as [Existing & Not Changed]
FROM SyncHistory h
INNER JOIN SyncDetails d ON h.SyncHistoryId = d.SyncHistoryId
GROUP BY h.SyncDateTime
You only need to JOIN to the details table once. You can get your counts from that through aggregation:
SELECT
CONVERT(VARCHAR(16), SH.SyncDateTime, 120) AS SyncTime,
SUM(CASE WHEN SD.ItemCreated = 1 AND SD.ItemChanged = 0 THEN 1 ELSE 0 END) AS New,
SUM(CASE WHEN SD.ItemCreated = 0 AND SD.ItemChanged = 1 THEN 1 ELSE 0 END) AS ExistingAndChanged,
SUM(CASE WHEN SD.ItemCreated = 0 AND SD.ItemChanged = 0 THEN 1 ELSE 0 END) AS ExistingAndNotChanged
FROM
SyncHistory SH
LEFT OUTER JOIN SyncDetails SD ON SD.SyncHistoryID = SH.SyncHistoryID
GROUP BY
CONVERT(VARCHAR(16), SH.SyncDateTime, 120)
You weren't clear on how the grouping/datetime should be determined. What I have is by the minute. If it's supposed to be by the hour on the 1/2 hour mark or something else then you'll need to change that part of the query in the GROUP BY and the first column of the SELECT.
Another solution. I hope it will work - no CASE, no subquery:
SELECT
sh.SyncHistoryId
,sh.SyncDateTime
,COUNT( NULLIF( sd.ItemCreated, 0 ) ) AS Created
,COUNT( NULLIF( sd.ItemCreated, 1 ) + NULLIF( sd1.ItemChanged, 0 ) ) AS ExistingChanged
,COUNT( NULLIF( sd.ItemCreated, 1 ) + NULLIF( sd1.ItemChanged, 1 ) ) AS ExistingNotChanged
FROM
SyncHistory sh JOIN SyncDetails sd ON sh.SyncHistoryId = sd.SyncHistoryId
WHERE
sh.SyncType = 1
GROUP BY
sh.SyncHistoryId
,sh.SyncDateTime
ORDER BY
sh.SyncDateTime DESC
I hope subquery is not forbidden:
SELECT
sh.SyncHistoryId
,sh.SyncDateTime
,(SELECT COUNT(*) FROM SyncDetails sd WHERE sh.SyncHistoryId = sd.SyncHistoryId AND sd.ItemCreated = 1 AND sd1.ItemChanged = 0) AS Created
,(SELECT COUNT(*) FROM SyncDetails sd WHERE sh.SyncHistoryId = sd.SyncHistoryId AND sd.ItemCreated = 0 AND sd1.ItemChanged = 1) AS ExistingChanged
,(SELECT COUNT(*) FROM SyncDetails sd WHERE sh.SyncHistoryId = sd.SyncHistoryId AND sd.ItemCreated = 0 AND sd1.ItemChanged = 0) AS ExistingNotChanged
FROM
SyncHistory sh
WHERE
sh.SyncType = 1
ORDER BY
sh.SyncDateTime DESC

Full Join on two queries

I'm trying to do a full join on two SQL queries, below:
1st Query:
SELECT
ID
,SUM(CASE WHEN reason = 4 THEN 0 ELSE quantity*price END) AS TValue
,COUNT(*) AS CountAll
FROM table1
WHERE Date>=#StartDate AND Date<=#EndDate
GROUP BY ID
2nd Query:
SELECT
ID
,SUM(CASE WHEN reason = 1 THEN 1 ELSE 0 END) AS New
,SUM(CASE WHEN reason = 6 THEN 1 ELSE 0 END) AS Amend
,SUM(CASE WHEN reason = 5 THEN 1 ELSE 0 END) AS Cancel
FROM Table2
WHERE Date2 >=#StartDate AND Date2<= #EndDate
GROUP BY ID
Result from query1
ID CountAll TValue
-------------------------
id1 24 1020
id2 13 2030
id3 4 120
Result from query 2:
ID New Amend Cancel
--------------------------------
id1 12 4 6
id2 7 6 1
id4 2 1 2
Needed output:
ID TValue CountAll New Amend Cancel Total(countall+new+amend+cancel)
----------------------------------------------------------------------------------------
Id1 1020 24 12 4 6 46
Id2 2030 13 7 6 1 27
id3 120 4 0 0 0 4
Id4 0 0 2 1 2 5
I'll post my current solution if requested, but it is pretty far from working.
I've been doing a bit of research and I think I need to either make a union to join the ID'S, or just do a Full Join. (Second day ever doing sql)
Try this,
SELECT *
FROM
(
SELECT ID ,
SUM(CASE WHEN reason = 4 THEN 0 ELSE quantity*price END) AS TValue,
COUNT(*) AS CountAll
FROM table1
WHERE Date>=#StartDate AND Date<=#EndDate
GROUP BY ID
) a FULL JOIN
(
SELECT ID ,
SUM(CASE WHEN reason = 1 THEN 1 ELSE 0 END) AS New ,
SUM(CASE WHEN reason = 6 THEN 1 ELSE 0 END) AS Amend ,
SUM(CASE WHEN reason = 5 THEN 1 ELSE 0 END) AS Cancel
FROM Table2
WHERE Date2 >=#StartDate AND Date2<= #EndDate
GROUP BY ID
) b ON a.ID = b.ID
I would write something like below:
select decode (a.id, null, b.id, a.id) as ID, a.TValue, CountAll, b.new, b.Amend, b.cancel
from (SELECT ID ,SUM(CASE WHEN reason = 4 THEN 0 ELSE quantity*price END)
AS TValue ,COUNT(*) AS CountAll
FROM table1
WHERE Date>=#StartDate AND Date<=#EndDate GROUP BY ID
) a FULL OUTER JOIN
(SELECT ID , SUM(CASE WHEN reason = 1 THEN 1 ELSE 0 END)
AS New ,SUM(CASE WHEN reason = 6
THEN 1 ELSE 0 END) AS Amend ,
SUM(CASE WHEN reason = 5 THEN 1 ELSE 0 END) AS Cancel
FROM Table2 WHERE Date2 >=#StartDate AND Date2<= #EndDate GROUP BY ID
) b
on a.id = b.id
have you tried this...
select isnull (a.id,b.id) as ID, a.TValue, CountAll, b.new, b.Amend, b.cancel
from (SELECT ID ,SUM(CASE WHEN reason = 4 THEN 0 ELSE quantity*price END) AS TValue ,COUNT(*) AS CountAll
FROM table1
WHERE Date>=#StartDate AND Date<=#EndDate GROUP BY ID ) a
FULL OUTER JOIN (SELECT ID , SUM(CASE WHEN reason = 1 THEN 1 ELSE 0 END) AS New ,SUM(CASE WHEN reason = 6 THEN 1 ELSE 0 END) AS Amend , SUM(CASE WHEN reason = 5 THEN 1 ELSE 0 END) AS Cancel
FROM Table2 WHERE Date2 >=#StartDate AND Date2<= #EndDate GROUP BY ID ) b on a.id = b.id