根据最近的验证日期根据2周的支架检索销售记录计数
CREATE TABLE [dbo].[Sale](
[ID] [int] NOT NULL,
[SaleDate] [date] NOT NULL,
[CustomerRef] [varchar](20) NOT NULL
) ON [PRIMARY]
CREATE TABLE [dbo].[Verification](
[CustomerRef] [varchar](20) NOT NULL,
[VerificationDate] [date] NOT NULL
) ON [PRIMARY]
INSERT [dbo].[Sale] ([ID], [SaleDate], [CustomerRef]) VALUES (1, CAST(N'2022-02-01' AS Date), N'1')
GO
INSERT [dbo].[Sale] ([ID], [SaleDate], [CustomerRef]) VALUES (2, CAST(N'2022-02-02' AS Date), N'1')
GO
INSERT [dbo].[Sale] ([ID], [SaleDate], [CustomerRef]) VALUES (3, CAST(N'2022-02-03' AS Date), N'1')
GO
INSERT [dbo].[Sale] ([ID], [SaleDate], [CustomerRef]) VALUES (4, CAST(N'2022-02-13' AS Date), N'1')
GO
INSERT [dbo].[Sale] ([ID], [SaleDate], [CustomerRef]) VALUES (5, CAST(N'2022-02-14' AS Date), N'1')
GO
INSERT [dbo].[Sale] ([ID], [SaleDate], [CustomerRef]) VALUES (6, CAST(N'2022-02-15' AS Date), N'1')
GO
INSERT [dbo].[Sale] ([ID], [SaleDate], [CustomerRef]) VALUES (7, CAST(N'2022-02-16' AS Date), N'1')
GO
INSERT [dbo].[Sale] ([ID], [SaleDate], [CustomerRef]) VALUES (8, CAST(N'2022-03-08' AS Date), N'1')
GO
INSERT [dbo].[Sale] ([ID], [SaleDate], [CustomerRef]) VALUES (9, CAST(N'2022-03-08' AS Date), N'1')
GO
INSERT [dbo].[Sale] ([ID], [SaleDate], [CustomerRef]) VALUES (10, CAST(N'2022-03-10' AS Date), N'1')
GO
INSERT [dbo].[Sale] ([ID], [SaleDate], [CustomerRef]) VALUES (11, CAST(N'2022-03-11' AS Date), N'1')
GO
INSERT [dbo].[Sale] ([ID], [SaleDate], [CustomerRef]) VALUES (12, CAST(N'2022-03-12' AS Date), N'1')
GO
INSERT [dbo].[Sale] ([ID], [SaleDate], [CustomerRef]) VALUES (13, CAST(N'2022-03-13' AS Date), N'1')
GO
INSERT [dbo].[Sale] ([ID], [SaleDate], [CustomerRef]) VALUES (14, CAST(N'2022-02-20' AS Date), N'2')
GO
INSERT [dbo].[Sale] ([ID], [SaleDate], [CustomerRef]) VALUES (15, CAST(N'2022-03-14' AS Date), N'1')
GO
INSERT [dbo].[Sale] ([ID], [SaleDate], [CustomerRef]) VALUES (16, CAST(N'2022-02-10' AS Date), N'2')
GO
INSERT [dbo].[Sale] ([ID], [SaleDate], [CustomerRef]) VALUES (17, CAST(N'2022-02-11' AS Date), N'2')
GO
INSERT [dbo].[Sale] ([ID], [SaleDate], [CustomerRef]) VALUES (18, CAST(N'2022-02-12' AS Date), N'2')
GO
INSERT [dbo].[Sale] ([ID], [SaleDate], [CustomerRef]) VALUES (19, CAST(N'2022-03-18' AS Date), N'2')
GO
INSERT [dbo].[Sale] ([ID], [SaleDate], [CustomerRef]) VALUES (20, CAST(N'2022-03-19' AS Date), N'2')
GO
INSERT [dbo].[Sale] ([ID], [SaleDate], [CustomerRef]) VALUES (21, CAST(N'2022-03-20' AS Date), N'2')
GO
INSERT [dbo].[Sale] ([ID], [SaleDate], [CustomerRef]) VALUES (22, CAST(N'2022-02-15' AS Date), N'3')
GO
INSERT [dbo].[Sale] ([ID], [SaleDate], [CustomerRef]) VALUES (23, CAST(N'2022-02-16' AS Date), N'3')
GO
INSERT [dbo].[Sale] ([ID], [SaleDate], [CustomerRef]) VALUES (24, CAST(N'2022-02-20' AS Date), N'4')
GO
INSERT [dbo].[Sale] ([ID], [SaleDate], [CustomerRef]) VALUES (25, CAST(N'2022-02-21' AS Date), N'4')
GO
INSERT [dbo].[Verification] ([CustomerRef], [VerificationDate]) VALUES (N'1', CAST(N'2022-02-01' AS Date))
GO
INSERT [dbo].[Verification] ([CustomerRef], [VerificationDate]) VALUES (N'2', CAST(N'2022-02-10' AS Date))
GO
INSERT [dbo].[Verification] ([CustomerRef], [VerificationDate]) VALUES (N'3', CAST(N'2022-02-15' AS Date))
GO
INSERT [dbo].[Verification] ([CustomerRef], [VerificationDate]) VALUES (N'4', CAST(N'2022-02-20' AS Date))
GO
INSERT [dbo].[Verification] ([CustomerRef], [VerificationDate]) VALUES (N'1', CAST(N'2022-03-10' AS Date))
GO
INSERT [dbo].[Verification] ([CustomerRef], [VerificationDate]) VALUES (N'2', CAST(N'2022-03-20' AS Date))
GO
每个客户都有一个唯一的CustomerRef
。可以多次验证同一个人(customerref
),因此在验证
表中可能具有多个记录。
对于验证
表中的每一行,我想获得sales
的数量日期。
这是十字架应用查询:
SELECT *
FROM VERIFICATION A
--GET NEXT VERIFICATION DATE
CROSS APPLY
(SELECT MIN(VerificationDate) NextVerificationDate
FROM VERIFICATION B
WHERE A.CUSTOMERREF = B.CUSTOMERREF
AND B.VERIFICATIONDATE > A.VERIFICATIONDATE) X
--GET FIRST SALE DATE POST VERIFICATION DATE
CROSS APPLY
(SELECT MIN(SaleDate) FirstSaleDatePostVerificationDate
FROM SALE B
WHERE A.CUSTOMERREF = B.CUSTOMERREF
AND B.SALEDATE >= A.VERIFICATIONDATE) Y
--GET FIRST SALE DATE POST VERIFICATION DATE AND PRIOR TO NEXT VERIFICATION DATE
CROSS APPLY
(SELECT MIN(SaleDate) FirstSaleDatePostVerificationDateAndPriorToNextVerifiationDate
FROM SALE B
WHERE A.CUSTOMERREF = B.CUSTOMERREF
AND B.SALEDATE >= A.VERIFICATIONDATE
AND B.SALEDATE < ISNULL(X.NextVerificationDate,'20990101')) Z
--GET COUNT OF SALES IN 2 WEEKS FROM THE FIRST SALE DATE POST VERIFICATION DATE (AND PRIOR TO NEXT VERIFICATION DATE)
CROSS APPLY
(SELECT COUNT(*) COUNT
FROM SALE B
WHERE A.CUSTOMERREF = B.CUSTOMERREF
AND B.SALEDATE >= Z.FirstSaleDatePostVerificationDateAndPriorToNextVerifiationDate
AND SALEDATE < DATEADD(WEEK, 2, Z.FirstSaleDatePostVerificationDateAndPriorToNextVerifiationDate)) U
我相信这可以通过第1个计算主表进行操作,然后应用每个十字申请每行。有更好的方法吗?
例如 - 我尝试使用SQL LEAD
将十字架应用于1个十字架,但它给出了一个错误:
窗口函数只能出现在选择或顺序中。
SELECT *
FROM verification A
CROSS APPLY
(SELECT COUNT(*) COUNT
FROM SALE B
WHERE A.CUSTOMERREF = B.CUSTOMERREF
AND B.SALEDATE >= A.VERIFICATIONDATE
AND B.SALEDATE < LEAD(A.VERIFICATIONDATE) OVER
(PARTITION BY CUSTOMERREF ORDER BY VERIFICATIONDATE)) X
CREATE TABLE [dbo].[Sale](
[ID] [int] NOT NULL,
[SaleDate] [date] NOT NULL,
[CustomerRef] [varchar](20) NOT NULL
) ON [PRIMARY]
CREATE TABLE [dbo].[Verification](
[CustomerRef] [varchar](20) NOT NULL,
[VerificationDate] [date] NOT NULL
) ON [PRIMARY]
INSERT [dbo].[Sale] ([ID], [SaleDate], [CustomerRef]) VALUES (1, CAST(N'2022-02-01' AS Date), N'1')
GO
INSERT [dbo].[Sale] ([ID], [SaleDate], [CustomerRef]) VALUES (2, CAST(N'2022-02-02' AS Date), N'1')
GO
INSERT [dbo].[Sale] ([ID], [SaleDate], [CustomerRef]) VALUES (3, CAST(N'2022-02-03' AS Date), N'1')
GO
INSERT [dbo].[Sale] ([ID], [SaleDate], [CustomerRef]) VALUES (4, CAST(N'2022-02-13' AS Date), N'1')
GO
INSERT [dbo].[Sale] ([ID], [SaleDate], [CustomerRef]) VALUES (5, CAST(N'2022-02-14' AS Date), N'1')
GO
INSERT [dbo].[Sale] ([ID], [SaleDate], [CustomerRef]) VALUES (6, CAST(N'2022-02-15' AS Date), N'1')
GO
INSERT [dbo].[Sale] ([ID], [SaleDate], [CustomerRef]) VALUES (7, CAST(N'2022-02-16' AS Date), N'1')
GO
INSERT [dbo].[Sale] ([ID], [SaleDate], [CustomerRef]) VALUES (8, CAST(N'2022-03-08' AS Date), N'1')
GO
INSERT [dbo].[Sale] ([ID], [SaleDate], [CustomerRef]) VALUES (9, CAST(N'2022-03-08' AS Date), N'1')
GO
INSERT [dbo].[Sale] ([ID], [SaleDate], [CustomerRef]) VALUES (10, CAST(N'2022-03-10' AS Date), N'1')
GO
INSERT [dbo].[Sale] ([ID], [SaleDate], [CustomerRef]) VALUES (11, CAST(N'2022-03-11' AS Date), N'1')
GO
INSERT [dbo].[Sale] ([ID], [SaleDate], [CustomerRef]) VALUES (12, CAST(N'2022-03-12' AS Date), N'1')
GO
INSERT [dbo].[Sale] ([ID], [SaleDate], [CustomerRef]) VALUES (13, CAST(N'2022-03-13' AS Date), N'1')
GO
INSERT [dbo].[Sale] ([ID], [SaleDate], [CustomerRef]) VALUES (14, CAST(N'2022-02-20' AS Date), N'2')
GO
INSERT [dbo].[Sale] ([ID], [SaleDate], [CustomerRef]) VALUES (15, CAST(N'2022-03-14' AS Date), N'1')
GO
INSERT [dbo].[Sale] ([ID], [SaleDate], [CustomerRef]) VALUES (16, CAST(N'2022-02-10' AS Date), N'2')
GO
INSERT [dbo].[Sale] ([ID], [SaleDate], [CustomerRef]) VALUES (17, CAST(N'2022-02-11' AS Date), N'2')
GO
INSERT [dbo].[Sale] ([ID], [SaleDate], [CustomerRef]) VALUES (18, CAST(N'2022-02-12' AS Date), N'2')
GO
INSERT [dbo].[Sale] ([ID], [SaleDate], [CustomerRef]) VALUES (19, CAST(N'2022-03-18' AS Date), N'2')
GO
INSERT [dbo].[Sale] ([ID], [SaleDate], [CustomerRef]) VALUES (20, CAST(N'2022-03-19' AS Date), N'2')
GO
INSERT [dbo].[Sale] ([ID], [SaleDate], [CustomerRef]) VALUES (21, CAST(N'2022-03-20' AS Date), N'2')
GO
INSERT [dbo].[Sale] ([ID], [SaleDate], [CustomerRef]) VALUES (22, CAST(N'2022-02-15' AS Date), N'3')
GO
INSERT [dbo].[Sale] ([ID], [SaleDate], [CustomerRef]) VALUES (23, CAST(N'2022-02-16' AS Date), N'3')
GO
INSERT [dbo].[Sale] ([ID], [SaleDate], [CustomerRef]) VALUES (24, CAST(N'2022-02-20' AS Date), N'4')
GO
INSERT [dbo].[Sale] ([ID], [SaleDate], [CustomerRef]) VALUES (25, CAST(N'2022-02-21' AS Date), N'4')
GO
INSERT [dbo].[Verification] ([CustomerRef], [VerificationDate]) VALUES (N'1', CAST(N'2022-02-01' AS Date))
GO
INSERT [dbo].[Verification] ([CustomerRef], [VerificationDate]) VALUES (N'2', CAST(N'2022-02-10' AS Date))
GO
INSERT [dbo].[Verification] ([CustomerRef], [VerificationDate]) VALUES (N'3', CAST(N'2022-02-15' AS Date))
GO
INSERT [dbo].[Verification] ([CustomerRef], [VerificationDate]) VALUES (N'4', CAST(N'2022-02-20' AS Date))
GO
INSERT [dbo].[Verification] ([CustomerRef], [VerificationDate]) VALUES (N'1', CAST(N'2022-03-10' AS Date))
GO
INSERT [dbo].[Verification] ([CustomerRef], [VerificationDate]) VALUES (N'2', CAST(N'2022-03-20' AS Date))
GO
Each customer has a unique CustomerRef
. The same person (CustomerRef
) can be verified multiple times, so may have multiple records in the Verification
table.
For each row in the Verification
table, I want to get the number of Sales
that have happened within 2 weeks from the first Sale
after the verification date.
Here is the CROSS APPLY query:
SELECT *
FROM VERIFICATION A
--GET NEXT VERIFICATION DATE
CROSS APPLY
(SELECT MIN(VerificationDate) NextVerificationDate
FROM VERIFICATION B
WHERE A.CUSTOMERREF = B.CUSTOMERREF
AND B.VERIFICATIONDATE > A.VERIFICATIONDATE) X
--GET FIRST SALE DATE POST VERIFICATION DATE
CROSS APPLY
(SELECT MIN(SaleDate) FirstSaleDatePostVerificationDate
FROM SALE B
WHERE A.CUSTOMERREF = B.CUSTOMERREF
AND B.SALEDATE >= A.VERIFICATIONDATE) Y
--GET FIRST SALE DATE POST VERIFICATION DATE AND PRIOR TO NEXT VERIFICATION DATE
CROSS APPLY
(SELECT MIN(SaleDate) FirstSaleDatePostVerificationDateAndPriorToNextVerifiationDate
FROM SALE B
WHERE A.CUSTOMERREF = B.CUSTOMERREF
AND B.SALEDATE >= A.VERIFICATIONDATE
AND B.SALEDATE < ISNULL(X.NextVerificationDate,'20990101')) Z
--GET COUNT OF SALES IN 2 WEEKS FROM THE FIRST SALE DATE POST VERIFICATION DATE (AND PRIOR TO NEXT VERIFICATION DATE)
CROSS APPLY
(SELECT COUNT(*) COUNT
FROM SALE B
WHERE A.CUSTOMERREF = B.CUSTOMERREF
AND B.SALEDATE >= Z.FirstSaleDatePostVerificationDateAndPriorToNextVerifiationDate
AND SALEDATE < DATEADD(WEEK, 2, Z.FirstSaleDatePostVerificationDateAndPriorToNextVerifiationDate)) U
I believe this works by 1st computing the main table, and then applying each cross apply for each row. Is there a better way to do this?
For example - I tried clubbing both the CROSS APPLY's into 1 CROSS APPLY using the SQL LEAD
, but it gives an error:
Windowed functions can only appear in the SELECT or ORDER BY clauses.
SELECT *
FROM verification A
CROSS APPLY
(SELECT COUNT(*) COUNT
FROM SALE B
WHERE A.CUSTOMERREF = B.CUSTOMERREF
AND B.SALEDATE >= A.VERIFICATIONDATE
AND B.SALEDATE < LEAD(A.VERIFICATIONDATE) OVER
(PARTITION BY CUSTOMERREF ORDER BY VERIFICATIONDATE)) X
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您需要将
Lead
放入派生表中,以便在查询的其他部分中使用它,Lead
默认值。这将替换第一个应用
Apply
似乎是完全不必要的,可以删除。必须保留第三和第四。You need to put
LEAD
into a derived table in order to use it in other parts of the queryLEAD
a default. This will replace the firstAPPLY
APPLY
seems entirely unnecessary, and can be removed. The third and fourth must remain.db<>fiddle