Please help me to generate the following query. Say I have customer table and order table.
Customer Table
CustID CustName
1 AA
2 BB
3 CC
4 DD
Order Table
OrderID OrderDate CustID
100 01-JAN-2000 1
101 05-FEB-2000 1
102 10-MAR-2000 1
103 01-NOV-2000 2
104 05-APR-2001 2
105 07-MAR-2002 2
106 01-JUL-2003 1
107 01-SEP-2004 4
108 01-APR-2005 4
109 01-MAY-2006 3
110 05-MAY-2007 1
111 07-JUN-2007 1
112 06-JUL-2007 1
I want to find out the customers who have made orders on three successive months. (Query using SQL server 2005 and 2008 is allowed).
The desired output is:
CustName Year OrderDate
AA 2000 01-JAN-2000
AA 2000 05-FEB-2000
AA 2000 10-MAR-2000
AA 2007 05-MAY-2007
AA 2007 07-JUN-2007
AA 2007 06-JUL-2007
SQL Query to Get Last 3 Months Records in SQL Server In SQL Server, you can use the DATEADD () function to get last 3 months (or n months) records. I have used this function in one of my previous posts where I have shown how easily you can get previous month records from the current month.
I am using -3 to get the last 3 months records or data. You can use -5, -4 or any number, depending upon your requirement. 👉 How easily can you find the First and Last day (in words) of a given month using a single SQL query?
The function DATEADD () takes 3 parameters. The first parameter is the M, which denotes a month. You can replace the M with the MONTH. Like this, The second parameter is the increment (an integer value or a number). I am using -3 to get the last 3 months records or data. You can use -5, -4 or any number, depending upon your requirement.
As you can see, regardless whether there is a gap between dates (two dates are not consecutive), their row numbers will still be consecutive. We can do this with the ROW_NUMBER () window function, very easily:
Edit: Got rid or the MAX() OVER (PARTITION BY ...)
as that seemed to kill performance.
;WITH cte AS (
SELECT CustID ,
OrderDate,
DATEPART(YEAR, OrderDate)*12 + DATEPART(MONTH, OrderDate) AS YM
FROM Orders
),
cte1 AS (
SELECT CustID ,
OrderDate,
YM,
YM - DENSE_RANK() OVER (PARTITION BY CustID ORDER BY YM) AS G
FROM cte
),
cte2 As
(
SELECT CustID ,
MIN(OrderDate) AS Mn,
MAX(OrderDate) AS Mx
FROM cte1
GROUP BY CustID, G
HAVING MAX(YM)-MIN(YM) >=2
)
SELECT c.CustName, o.OrderDate, YEAR(o.OrderDate) AS YEAR
FROM Customers AS c INNER JOIN
Orders AS o ON c.CustID = o.CustID
INNER JOIN cte2 c2 ON c2.CustID = o.CustID and o.OrderDate between Mn and Mx
order by c.CustName, o.OrderDate
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With