I need to get Quantity of items in orders the next 12 months, like this:
ItemNumber
August 22
September 22
October 22
November 22
etc..
item1
10
13
12
130
..
item2
20
23
22
230
..
I can do like this for one month and repeat, but think there is a better way to do it.
SELECT I.ItemNumber, ThisMonth.Quantity AS This, NextMonth.Quantity AS Next *
FROM Items I
LEFT JOIN (
SELECT Quantity,Itemno
FROM [Orders]
WHERE MONTH([Shipment Date]) = MONTH(GETDATE()) AND YEAR([Shipment Date]) = YEAR(GETDATE())
) AS ThisMonth ON ThisMonth.Itemno = I.Itemnumber
LEFT JOIN (
SELECT Quantity,Itemno
FROM [Orders]
WHERE MONTH([Shipment Date]) = MONTH(DATEADD(month,+1,GETDATE())) AND YEAR([Shipment Date]) = YEAR(GETDATE())
) AS NextMonth ON NextMonth.Itemno = I.Itemnumber
Can you help? :)
UPDATED WITH MY TABLE DATA BELOW
ITEMS:
ItemNumber
item1
item2
ORDERS:
ItemNo
Shipment Date
Quantity
item1
2022-08-02
10
item1
2022-09-02
13
item1
2022-10-02
12
item1
2022-11-02
130
item2
2022-08-02
20
item3
2022-09-02
23
item4
2022-10-02
22
item5
2022-11-02
230
You haven't supplied sample data, but it looks like you need conditional aggregation (aka a pivot). It's generally easier, if a bit more verbose, to do this with SUM(CASE rather than using the PIVOT operator.
SELECT
i.ItemNumber,
SUM(CASE WHEN EOMONTH(i.[Shipment Date]) = EOMONTH(GETDATE()) THEN i.Quantity END) AS CurrentMonth,
SUM(CASE WHEN EOMONTH(i.[Shipment Date]) = EOMONTH(GETDATE(), 1) THEN i.Quantity END) AS Month1,
SUM(CASE WHEN EOMONTH(i.[Shipment Date]) = EOMONTH(GETDATE(), 2) THEN i.Quantity END) AS Month2,
SUM(CASE WHEN EOMONTH(i.[Shipment Date]) = EOMONTH(GETDATE(), 3) THEN i.Quantity END) AS Month3,
SUM(CASE WHEN EOMONTH(i.[Shipment Date]) = EOMONTH(GETDATE(), 4) THEN i.Quantity END) AS Month4,
SUM(CASE WHEN EOMONTH(i.[Shipment Date]) = EOMONTH(GETDATE(), 5) THEN i.Quantity END) AS Month5,
SUM(CASE WHEN EOMONTH(i.[Shipment Date]) = EOMONTH(GETDATE(), 6) THEN i.Quantity END) AS Month6,
SUM(CASE WHEN EOMONTH(i.[Shipment Date]) = EOMONTH(GETDATE(), 7) THEN i.Quantity END) AS Month7,
SUM(CASE WHEN EOMONTH(i.[Shipment Date]) = EOMONTH(GETDATE(), 8) THEN i.Quantity END) AS Month8,
SUM(CASE WHEN EOMONTH(i.[Shipment Date]) = EOMONTH(GETDATE(), 9) THEN i.Quantity END) AS Month9,
SUM(CASE WHEN EOMONTH(i.[Shipment Date]) = EOMONTH(GETDATE(), 10) THEN i.Quantity END) AS Month10,
SUM(CASE WHEN EOMONTH(i.[Shipment Date]) = EOMONTH(GETDATE(), 11) THEN i.Quantity END) AS Month11,
FROM Items i
GROUP BY
i.ItemNumber;
A possible option, using the PIVOT relational operator:
Sample data:
SELECT *
INTO Items
FROM (VALUES
('item1', CONVERT(date, '20220802'), 10),
('item1', CONVERT(date, '20220902'), 13),
('item1', CONVERT(date, '20221002'), 12),
('item1', CONVERT(date, '20221102'), 130),
('item2', CONVERT(date, '20220802'), 20),
('item3', CONVERT(date, '20220902'), 23),
('item4', CONVERT(date, '20221002'), 22),
('item5', CONVERT(date, '20221102'), 230)
) t (ItemNo, ShipmentDate, Quantity)
Statement:
SELECT *
FROM (
SELECT ItemNo, Quantity, DATEDIFF(month, EOMONTH(GETDATE()), EOMONTH(ShipmentDate)) AS NextMonth
FROM Items
) t
PIVOT (
SUM(Quantity)
FOR NextMonth IN ([0], [1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11])
) p
Result:
ItemNo
0
1
2
3
4
5
6
7
8
9
10
11
item1
10
13
12
130
item2
20
item3
23
item4
22
item5
230
Related
How can I add row and column grand totals in the table below?
I want to get total and grand total by months.
However, I couldn't do that.
SELECT *
FROM(
SELECT
YEAR(DueDate) [Year],
CASE MONTH(DueDate)
WHEN 1 THEN 'January'
WHEN 2 THEN 'February'
WHEN 3 THEN 'March'
WHEN 4 THEN 'April'
WHEN 5 THEN 'May'
WHEN 6 THEN 'June'
WHEN 7 THEN 'July'
WHEN 8 THEN 'August'
WHEN 9 THEN 'September'
WHEN 10 THEN 'October'
WHEN 11 THEN 'November'
WHEN 12 THEN 'December'
END as [Month],
ProductID,
OrderQty
FROM Production.WorkOrder
) WorkOrders
PIVOT
(
SUM(OrderQty)
FOR [Month] IN (
[January],[February],[March],[April],
[May],[June],[July],[August],
[September],[October],[November],[December]
)
) AS PivotTable
ORDER BY [Year], ProductID
Stuff like this is far easier using a conditional aggregate over the restrictive PIVOT operator.
Without sample data, nor expected results, this isn't tested, but you should be able to achieve what you're after with something like this:
SELECT CASE WHEN GROUPING(DATEPART(YEAR,DueDate)) = 0 THEN
CAST(DATEPART(YEAR,DueDate) AS varchar(50))
ELSE 'GrandTotal' END AS [Year],
SUM(CASE DATEPART(MONTH,DueDate) WHEN 1 THEN OrderQty END) AS January, --Don't use single quotes for alaises,
SUM(CASE DATEPART(MONTH,DueDate) WHEN 2 THEN OrderQty END) AS Feburary, --it can be very confusing to read.
SUM(CASE DATEPART(MONTH,DueDate) WHEN 3 THEN OrderQty END) AS March, --Single quotes are for literal strings.
SUM(CASE DATEPART(MONTH,DueDate) WHEN 4 THEN OrderQty END) AS April, --Using ' for alias only work in the SELECT too,
SUM(CASE DATEPART(MONTH,DueDate) WHEN 5 THEN OrderQty END) AS May, --something like ORDER BY 'January' would not
SUM(CASE DATEPART(MONTH,DueDate) WHEN 6 THEN OrderQty END) AS June, --order by data by the column aliases as 'January'.
SUM(CASE DATEPART(MONTH,DueDate) WHEN 7 THEN OrderQty END) AS July,
SUM(CASE DATEPART(MONTH,DueDate) WHEN 8 THEN OrderQty END) AS August,
SUM(CASE DATEPART(MONTH,DueDate) WHEN 9 THEN OrderQty END) AS September,
SUM(CASE DATEPART(MONTH,DueDate) WHEN 10 THEN OrderQty END) AS October,
SUM(CASE DATEPART(MONTH,DueDate) WHEN 11 THEN OrderQty END) AS November,
SUM(CASE DATEPART(MONTH,DueDate) WHEN 12 THEN OrderQty END) AS December,
SUM(OrderQty) AS GrandTotal,
ProductID
FROM Production.WorkOrder
GROUP BY GROUPING SETS(
(DATEPART(YEAR, DueDate), ProductID),
(DATEPART(YEAR, DueDate)),
()
);
Here is what my table looks like
ID | Date
------------
13 2013-03-21 00:00:00
13 2013-03-23 00:00:00
13 2013-03-24 00:00:00
25 2013-03-21 00:00:00
25 2013-03-22 00:00:00
25 2013-03-21 00:00:00
25 2013-03-23 00:00:00
25 2013-03-28 00:00:00
25 2013-03-21 00:00:00
82 2013-03-22 00:00:00
82 2013-03-22 00:00:00
I want it to output (combine sat & sun into 'weekend'). It'll combine all the Mondays, Tuesdays, Wednesdays, etc. and combine the values.
day | total
--------------
Friday 2
Thursday 3
Weekend 3
This is my query so far
SELECT
CASE
WHEN DATENAME(weekday, [date]) = 'Saturday' OR DATENAME(weekday, [date]) = 'Sunday' THEN 'Weekend'
ELSE DATENAME(weekday, [date])
END AS Day,
COUNT(DISTINCT [id]) AS score
FROM [table]
GROUP BY
CASE
WHEN DATENAME(weekday, [date]) = 'Saturday' OR DATENAME(weekday, [date]) = 'Sunday' THEN 'Weekend'
ELSE DATENAME(weekday, [date])
END
Currently I can get my query to output this, but it seems like it isn't adding both thursdays or sat + sun.
Day | total
--------------
Friday 2
Thursday 2
Weekend 2
Appears like what you are actually after is a distinct count of the ID and date combined. Seems like the easiest way, therefore, would be to concatenate the 2 values to make a new unique value and COUNT those DISTINCT values:
SELECT CASE WHEN DATENAME(WEEKDAY, V.[Date]) IN ('Saturday','Sunday') THEN 'Weekend' ELSE DATENAME(WEEKDAY, V.[Date]) END AS [Weekday],
COUNT(DISTINCT CONCAT(ID,[date]))
FROM (VALUES (13, CONVERT(datetime2(0),'2013-03-21T00:00:00')),
(13, CONVERT(datetime2(0),'2013-03-23T00:00:00')),
(13, CONVERT(datetime2(0),'2013-03-24T00:00:00')),
(25, CONVERT(datetime2(0),'2013-03-21T00:00:00')),
(25, CONVERT(datetime2(0),'2013-03-22T00:00:00')),
(25, CONVERT(datetime2(0),'2013-03-21T00:00:00')),
(25, CONVERT(datetime2(0),'2013-03-23T00:00:00')),
(25, CONVERT(datetime2(0),'2013-03-28T00:00:00')),
(25, CONVERT(datetime2(0),'2013-03-21T00:00:00')),
(82, CONVERT(datetime2(0),'2013-03-22T00:00:00')),
(82, CONVERT(datetime2(0),'2013-03-22T00:00:00'))) V (ID, [Date])
GROUP BY CASE WHEN DATENAME(WEEKDAY, V.[Date]) IN ('Saturday','Sunday') THEN 'Weekend' ELSE DATENAME(WEEKDAY, V.[Date]) END;
Try this!
select count(id)as Total,Day from
(
select id, case when Datename(weekday,dt1) IN('Saturday','Sunday') then 'Weekend' else Datename(weekday,dt1) end as 'Day' from tab
)x
group by Day
Demo here
select Day,Count(day) cnt from (
SELECT
CASE
WHEN DATENAME(weekday, [date]) = 'Saturday' OR DATENAME(weekday, [date]) = 'Sunday' THEN 'Weekend'
ELSE DATENAME(weekday, [date])
END AS Day
,[date]
FROM [Infinite_campus].[dbo].[AttendanceRecord]
) as t
group by Day
I try to count the no. of bills received between 30,60 and above 90 days.
Here is my T-SQL query:
SELECT
costcentreid,
'Current' = CASE
WHEN DATEDIFF(DAY, BillDate, Getdate()) < 30
THEN COUNT(PVNo)
END,
'30_days' = CASE
WHEN DATEDIFF(DAY, BillDate, Getdate()) BETWEEN 30 AND 60
THEN COUNT(PVNo)
END,
'60_days' = CASE
WHEN DATEDIFF(DAY, BillDate, Getdate()) BETWEEN 60 AND 90
THEN COUNT(PVNo)
END,
'90_plus' = CASE
WHEN DATEDIFF(DAY, BillDate, Getdate()) > 90
THEN COUNT(PVNo)
END
FROM
SPRGMMS..PVRegister
GROUP BY
CostCentreId
When I run this, I get an error:
Msg 8120, Level 16, State 1, Line 2
Column '[DB]..PVRegister.BillDate' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
Kindly help
You need the aggregation outside
SELECT
costcentreid,
COUNT(CASE
WHEN DATEDIFF(DAY, BillDate, Getdate()) < 30
THEN PVNo
END) as 'Current',
COUNT(CASE
WHEN DATEDIFF(DAY, BillDate, Getdate()) BETWEEN 30 AND 60
THEN PVNo
END) as '30_days',
COUNT(CASE
WHEN DATEDIFF(DAY, BillDate, Getdate()) BETWEEN 60 AND 90
THEN PVNo
END) as '60_days',
COUNT(CASE
WHEN DATEDIFF(DAY, BillDate, Getdate()) > 90
THEN PVNo
END) as '90_plus'
FROM
SPRGMMS..PVRegister
GROUP BY CostCentreId
SELECT
costcentreid,
SUM(CASE WHEN d = 1 THEN 1 ELSE 0 END) AS '30_days'
SUM(CASE WHEN d = 2 THEN 1 ELSE 0 END) AS '60_days',
SUM(CASE WHEN d = 3 THEN 1 ELSE 0 END) AS '90_days',
FROM (
SELECT PVNo, costcentreid, DATEDIFF(DAY, BillDate, Getdate())) / 30 AS d FROM SPRGMMS..PVRegister
) T
WHERE d <= 3
GROUP BY costcentreid
I have a query that returns a score on whether or not 3 of the columns = 1 and then if the ProviderID exists in the 2nd table. I need to be able to return a score for each month for 6 months using column Time_Stamp, not including current month. The below returns the score for last month. How can I include the remaining 5 months and ROW_NUMBER() them?
DECLARE #ProviderID int = '1717';
WITH cte as
(
SELECT TOP 1
a.ProviderID, Time_Stamp,
SUM(CASE WHEN [AdditionalReports] = '1' THEN 5 ELSE 0 END) as AdditionalReports,
SUM(CASE WHEN [UniqueReportRequests] = '1' THEN 15 ELSE 0 END) as UniqueReportsRequests,
SUM(CASE WHEN [SurveyCompleted] = '1' THEN 30 ELSE 0 END) as SurveyCompleted,
MAX(CASE WHEN b.ProviderID IS NULL THEN 0 ELSE 50 END) as SubscriptionExists
FROM
ProviderValueCard a
LEFT JOIN
SubscriptionsTV b ON a.ProviderID = b.ProviderID
WHERE
a.ProviderID = #ProviderID AND GroupID = 2
AND Time_Stamp BETWEEN DATEADD(mm, DATEDIFF(mm, 0, GETDATE()) - 1, 0) AND DATEADD(DAY, -(DAY(GETDATE())), GETDATE())
GROUP BY
Time_Stamp, a.ProviderID, event
ORDER BY
event DESC, Time_Stamp DESC
)
SELECT
ProviderID, Time_Stamp,
(AdditionalReports + UniqueReportsRequests + SurveyCompleted + SubscriptionExists) AS TotalScore
FROM
cte
Here is how to grab the first/last day of previous months:
2 months ago:
DATEADD(mm, DATEDIFF(mm, 0, GETDATE()) - 2, 0) as FirstD2monthsago,
DATEADD(DAY, -DAY(GETDATE()), DATEADD(MONTH, -1, GETDATE())) AS last_day_2_months_ago
3 months ago etc:
DATEADD(mm, DATEDIFF(mm, 0, GETDATE()) - 3, 0) as FirstD3monthsago,
DATEADD(DAY, -DAY(GETDATE()), DATEADD(MONTH, -2, GETDATE())) AS last_day_3_months_ago
Desired output
ProviderID Time_Stamp TotalScore Row_Number
----------- ----------------------- -----------
1717 2014-08-29 12:11:17.610 70 1
1717 2014-07-29 12:11:17.610 95 2
1717 2014-06-29 12:11:17.610 100 3
1717 2014-05-29 12:11:17.610 70 4
1717 2014-04-29 12:11:17.610 70 5
1717 6
DECLARE #ProviderID INT, #Now DATETIME, #Months INT
SELECT #ProviderID = 1717, #Now = GETDATE(), #Months = 5
WITH
date_range_cte AS (
SELECT 1 AS RowNum, DATEADD(mm,-1,#Now) AS StartDate, DATEADD(mm,0,#Now) AS EndDate
UNION ALL
SELECT d.RowNum + 1 AS RowNum, DATEADD(mm,(-d.RowNum - 1),#Now) AS StartDate, DATEADD(mm,-d.RowNum,#Now) AS EndDate
FROM date_range_cte d
WHERE d.RowNum + 1 <= #Months
),
main_cte AS (
SELECT
ROW_NUMBER() OVER (PARTITION BY a.ProviderID, d.RowNum, d.StartDate ORDER BY Time_Stamp DESC) AS ordinal_position,
a.ProviderID,
d.RowNum,
d.StartDate,
[AdditionalReports] * 5 AS AdditionalReports,
[UniqueReportRequests] * 15 AS UniqueReportsRequests,
[SurveyCompleted] * 30 as SurveyCompleted,
CASE WHEN b.ProviderID IS NULL THEN 0 ELSE 50 END as SubscriptionExists
FROM ProviderValueCard a
INNER JOIN date_range_cte d ON d.StartDate < Time_Stamp AND Time_Stamp <= d.EndDate
LEFT OUTER JOIN SubscriptionsTV b ON a.ProviderID = b.ProviderID
WHERE a.ProviderID = #ProviderID AND GroupID = 2
)
SELECT ProviderID, RowNum, StartDate, (AdditionalReports + UniqueReportsRequests + SurveyCompleted + SubscriptionExists) AS TotalScore
FROM main_cte
WHERE ordinal_position = 1
ORDER BY RowNum
Here's a couple of ways (psuedocode):
1 - Make a cte just like your existing one for each month you want to get. The only thing you need to change in each one is this line:
AND Time_Stamp BETWEEN DATEADD(mm, DATEDIFF(mm, 0, GETDATE()) - 1, 0) AND DATEADD(DAY, -(DAY(GETDATE())), GETDATE())
For 2 months ago, you would change it to this:
AND Time_Stamp BETWEEN DATEADD(mm, DATEDIFF(mm, 0, GETDATE()) - 2, 0) AND DATEADD(mm, DATEDIFF(mm, 0, GETDATE()) - 1, 0)
and so on for the other months back.
2 - Referring to the same line in your cte above, change it to a -6 to get data for the past 6 months. Then include a MONTH(TimeStamp) column in your select list and group by it to get one row per month for the past 6 months.
I have this query:
DECLARE #month INT
SET #month=1
SELECT
CLOI_ClientOrderItems.cl_Id,
NoOfInv = SUM(CASE WHEN DATEPART(mm, in_date_issued) <= #month
AND DATEPART(yyyy, in_date_issued) = 2014
THEN 1 ELSE 0 END),
MonthTotal = SUM(CASE WHEN DATEPART(mm, in_date_issued) <= #month
AND DATEPART(yyyy, in_date_issued) = 2014
THEN in_total ELSE 0 END),
Grandtotal = SUM(in_total),
RemainingAmount = SUM(in_total) - SUM(CASE
WHEN DATEPART(mm, in_date_issued) <= #month
THEN in_total ELSE 0 END)
FROM (SELECT
DISTINCT MasterOrderId, cl_Id
FROM
CLOI_ClientOrderItems) as CLOI_ClientOrderItems
INNER JOIN
IN_Invoices
ON
IN_Invoices.MasterOrderId = CLOI_ClientOrderItems.MasterOrderId
GROUP BY
CLOI_ClientOrderItems.cl_id
i want output like
noofinv |amt |clid | grandtotal | jan |feb |march |remainingamt
5 |7.00 |100000_Pri | 245.00 | 0.00 |238.00 |7.00 |238.00
12 |2510.12 |100001_pro | 181110.29 | 138891.92 |9708.25 |510.12 |178600.17
If I pass month number like 3, it should display it as like Jan Feb and March and its related records in the respective month.
Try this, where condition is useful for you.
select Datename(mm,in_date_issued) from IN_Invoices Where Datediff(yyyy,in_date_issued,3) = 2014 and Datediff(mm,in_date_issued,#monthParameter) <= 3
You can Try like This...
declare #MonthCount int=1
SELECT DATENAME(month, DATEADD(month, #MonthCount-1 ,
CAST('2014-01-01' AS datetime))) as Month_Name
OP:
Month_Name
January