Reputation: 477
I have invoices for an employee within a store within a region. I'm trying to get the next invoice date for the same employee but at a different store in the same region. Also a second query in a different store and region.
I am trying to figure out a way to do a LEAD(invoice_date,1) OVER (PARTITION BY employee_id ORDER BY invoice_date)
WHERE employee = employee but market <> market
. Then a second time WHERE employee = employee and market = market but store <> store.
With this requirement, I can use LEAD with partition for the same employee, store, and region, but am not sure how to conditionally partition by employee but only for region <> region and then a second time for store <> store. How can I condition the LEAD like this?
DROP TABLE [tmp].[store]
CREATE TABLE [tmp].[store](
[salonpk] int NOT null IDENTITY(1,1),
[storename] varchar(20) NOT NULL,
[market] varchar(20) NOT NULL,
[store_id] int null
) ON [PRIMARY]
GO
DROP TABLE [tmp].[invoices]
CREATE TABLE [tmp].[invoices](
[invoicepk] int NOT null IDENTITY(1,1),
[employee_id] int null,
[store_id] int null,
[inm_invoicedate] datetime null
) ON [PRIMARY]
GO
DROP TABLE [tmp].[employee]
CREATE TABLE [tmp].[employee](
[employeepk] int NOT null IDENTITY(1,1),
[employee_id] int null,
[store_id] int null,
[role] varchar(10) NOT NULL,
[active] bit NOT NULL,
[termdate] datetime NULL,
[fname] VARCHAR(20) null,
[lname] VARCHAR(20) NULL
) ON [PRIMARY]
GO
DROP TABLE [tmp].[employeemaster]
CREATE TABLE [tmp].[employeemaster](
[employeemasterpk] int NOT null IDENTITY(1,1),
[masteremployee_id] int not null,
[employee_id] int null,
[store_id] int null,
) ON [PRIMARY]
GO
INSERT INTO [tmp].[employee]
SELECT 1,1,'manager',1,NULL,'steve','johnson' UNION ALL
SELECT 2,2,'stylist',1,'1/1/1899','steve','johnson' UNION ALL
SELECT 3,3,'manager',0,'8/1/2017','steve','johnson' UNION ALL
SELECT 4,1,'stylist',1,NULL,'adam','thomas' UNION ALL
SELECT 5,2,'stylist',0,'6/1/2017','adam','thomas' UNION ALL
SELECT 6,1,'gm',1,NULL,'susan','smith' UNION ALL
SELECT 7,3,'gm',1,NULL,'susan','smith' UNION ALL
SELECT 8,1,'stylist',1,NULL,'craig','allen' UNION ALL
SELECT 9,2,'stylist',0,'5/1/2018','craig','allen' UNION ALL
SELECT 10,1,'stylist',0,'2/1/2018','nelson','brian' UNION ALL
SELECT 11,4,'stylist',1,NULL,'nelson','brian' UNION ALL
SELECT 12,1,'stylist',0,'2/1/2018','alex','canner' UNION ALL
SELECT 13,4,'stylist',1,NULL,'alex','canner' UNION ALL
SELECT 14,3,'stylist',1,NULL,'alex','canner'
INSERT INTO [tmp].[employeemaster]
SELECT 1,1,1 UNION ALL
SELECT 1,2,2 UNION ALL
SELECT 1,3,3 UNION ALL
SELECT 2,4,1 UNION ALL
SELECT 2,5,2 UNION ALL
SELECT 3,6,1 UNION ALL
SELECT 3,7,3 UNION ALL
SELECT 4,8,1 UNION ALL
SELECT 4,9,2 UNION ALL
SELECT 5,10,1 UNION ALL
SELECT 5,11,4 UNION ALL
SELECT 6,12,1 UNION ALL
SELECT 6,13,4 UNION ALL
SELECT 6,14,3
INSERT INTO [tmp].[store]
SELECT 'Down Town Store', 'South', 1 UNION ALL
SELECT 'South City Store','South', 4 UNION ALL
SELECT 'East Side Store','East', 2 UNION ALL
SELECT 'East Way Store','East', 3
INSERT INTO [tmp].[invoices]
SELECT 1,1,'2017/2/16' UNION ALL
SELECT 1,1,'2018/1/1' UNION ALL
SELECT 1,1,'2018/1/5' UNION ALL
SELECT 1,1,'2018/2/1' UNION ALL
SELECT 1,1,'2018/2/10' UNION ALL
SELECT 1,1,'2018/2/11' UNION ALL
SELECT 1,1,'2018/2/12' UNION ALL
SELECT 2,2,'2018/2/15' UNION ALL
SELECT 2,2,'2018/2/16' UNION ALL
SELECT 2,2,'2018/2/17' UNION ALL
SELECT 2,2,'2018/2/18' UNION ALL
SELECT 2,2,'2018/2/19' UNION ALL
SELECT 1,1,'2018/3/15' UNION ALL
SELECT 3,3,'2018/3/25' UNION ALL
SELECT 4,1,'2018/1/5' UNION ALL
SELECT 4,1,'2018/1/25' UNION ALL
SELECT 5,2,'2018/1/27' UNION ALL
SELECT 4,1,'2018/2/1' UNION ALL
SELECT 4,1,'2018/2/15' UNION ALL
SELECT 4,1,'2018/2/15' UNION ALL
SELECT 4,1,'2018/3/20' UNION ALL
SELECT 5,2,'2018/3/22' UNION ALL
SELECT 6,1,'2018/1/11' UNION ALL
SELECT 6,1,'2018/3/15' UNION ALL
SELECT 6,1,'2018/4/21' UNION ALL
SELECT 6,1,'2018/4/22' UNION ALL
SELECT 7,3,'2018/5/15' UNION ALL
SELECT 6,1,'2018/6/21' UNION ALL
SELECT 6,1,'2018/7/01' UNION ALL
SELECT 8,1,'2017/5/15' UNION ALL
SELECT 9,2,'2018/5/16' UNION ALL
SELECT 9,2,'2018/5/17' UNION ALL
SELECT 10,1,'2018/6/1' UNION ALL
SELECT 10,1,'2018/1/12' UNION ALL
SELECT 10,1,'2018/8/24' UNION ALL
SELECT 11,4,'2018/6/2'
Here's what I'm trying to do, but change the next invoice to be from a different store in the same market for the same employee.
;WITH CTE AS
(
SELECT
eg.[masteremployee_id]
, s.[market]
, i.[invoicepk]
, i.[inm_invoicedate]
,LEAD(i.inm_invoicedate, 1,i.inm_invoicedate) OVER (PARTITION BY eg.masteremployee_id ORDER BY i.inm_invoicedate ASC) AS NextInvoice
FROM [tmp].[invoices] AS i
INNER JOIN [tmp].[employeemaster] AS eg
ON i.[employee_id] = eg.[employee_id]
AND i.[store_id] = eg.[store_id]
INNER JOIN [tmp].[store] AS s
ON i.[store_id] = s.[store_id]
GROUP BY
eg.[masteremployee_id]
, s.[market]
, i.[invoicepk]
, i.[inm_invoicedate]
)
SELECT
*
FROM CTE
ORDER BY [masteremployee_id], [market], [inm_invoicedate]
Desired Results:
masteremployee_id market invoicepk inm_invoicedate NextInvoiceInOtherMarket
1 South 1 2/16/2017 2/15/2018
1 South 2 1/1/2018 2/15/2018
1 South 3 1/5/2018 2/15/2018
1 South 4 2/1/2018 2/15/2018
1 South 5 2/10/2018 2/15/2018
1 South 6 2/11/2018 2/15/2018
1 South 7 2/12/2018 2/15/2018
1 South 13 3/15/2018 3/25/2018
1 East 8 2/15/2018 3/15/2018
1 East 9 2/16/2018 3/15/2018
1 East 10 2/17/2018 3/15/2018
1 East 11 2/18/2018 3/15/2018
1 East 12 2/19/2018 3/15/2018
1 East 14 3/25/2018 NULL
2 South 15 1/5/2018 1/27/2018
2 South 16 1/25/2018 1/27/2018
2 South 18 2/1/2018 3/22/2018
2 South 19 2/15/2018 3/22/2018
2 South 20 2/15/2018 3/22/2018
2 South 21 3/20/2018 3/22/2018
2 East 17 1/27/2018 2/1/2018
2 East 22 3/22/2018 NULL
3 South 23 1/11/2018 NULL
3 South 24 3/15/2018 NULL
3 South 25 4/21/2018 NULL
3 South 26 4/22/2018 NULL
3 South 28 6/21/2018 5/15/2018
3 South 29 7/1/2018 5/15/2018
3 East 27 5/15/2018 6/21/2018
4 South 30 5/15/2017 5/16/2018
4 East 31 5/16/2018 NULL
4 East 32 5/17/2018 NULL
5 South 34 1/12/2018 NULL
5 South 33 6/1/2018 NULL
5 South 36 6/2/2018 NULL
5 South 35 8/24/2018 NULL
Code I'm trying to replace with LEAD
;WITH CTE AS
(
SELECT
eg.[masteremployee_id]
, s.[market]
, i.[invoicepk]
, i.[inm_invoicedate]
, MIN(OTHERDOS.[inm_invoicedate]) AS NextInvoice
, DATEDIFF(day, i.[inm_invoicedate], MIN(OTHERDOS.[inm_invoicedate])) AS DateDiff
FROM [tmp].[invoices] AS i
INNER JOIN [tmp].[employeeglobal] AS eg
ON i.[employee_id] = eg.[employee_id]
AND i.[store_id] = eg.[store_id]
INNER JOIN [tmp].[store] AS s
ON i.[store_id] = s.[store_id]
INNER JOIN
(
SELECT
[inm_invoicedate]
, eg.[masteremployee_id]
, s.[market]
FROM [tmp].[invoices] AS i
INNER JOIN [tmp].[employeeglobal] AS eg
ON i.[employee_id] = eg.[employee_id]
AND i.[store_id] = eg.[store_id]
INNER JOIN [tmp].[store] AS s
ON i.[store_id] = s.[store_id]
) AS OTHERDOS
ON eg.[masteremployee_id] = OTHERDOS.[masteremployee_id]
WHERE s.[market] <> OTHERDOS.[market]
AND i.[inm_invoicedate] <= OTHERDOS.[inm_invoicedate] --should this go away?
GROUP BY
eg.[masteremployee_id]
, s.[market]
, i.[invoicepk]
, i.[inm_invoicedate]
)
SELECT
*
FROM CTE
ORDER BY [masteremployee_id], [market] DESC, [inm_invoicedate]
Upvotes: 1
Views: 55
Reputation: 1269693
Offhand, I can't think of a way to skip to the invoice in another store using window functions. You can use APPLY
instead:
WITH CTE AS (
SELECT eg.[masteremployee_id], s.[market], i.[invoicepk], i.[inm_invoicedate]
FROM [tmp].[invoices] i INNER JOIN
[tmp].[employeemaster] eg
ON i.[employee_id] = eg.[employee_id] AND
i.[store_id] = eg.[store_id] INNER JOIN
[tmp].[store] s
ON i.[store_id] = s.[store_id]
GROUP BY eg.[masteremployee_id], s.[market], i.[invoicepk], i.[inm_invoicedate]
)
SELECT cte.*, ctenext.inm_invoicedate
FROM CTE OUTER APPLY
(SELECT TOP (1) ctenext.*
FROM CTE ctenext
WHERE ctenext.masteremployee_id = cte.masteremployee_id AND
ctenext.store <> cte.store AND -- not sure if this is the right column
ctenext.inm_invoicedate > inm_invoicedate
ORDER BY ctenext.inm_invoicedate DESC
) ctenext
ORDER BY [masteremployee_id], [market], [inm_invoicedate];
Upvotes: 1