帮助进行跨多个列的复杂自引用查询
我在处理复杂的(对我来说无论如何)查询时遇到困难。
我正在查询的表有 3 列,ClientID (int Not Null)、ProductID (int Not Null) 和 ExpiryDate (smalldatetime nullable)
给定两个客户端 ID Master 和 Consolidated,我需要执行以下业务逻辑来返回单个数据集:
选择具有较大值的 ClientID 过期产品的失效日期 两个 clientID 的日期都不为空
选择过期时间为空的 ClientID 一次到期的产品的日期 null 且另一个不为 null
选择产品的 MasterID 其中两个到期日期均为空或 两个到期日期相同。
我已经尝试过以下方法,但陷入困境...
Create Table #ProductSub (ClientID int NOT NULL,
ProductID int NOT NULL,
ExpiryDate smalldatetime)
/* In real life there is a Clustered Primary Key On ClientID and ProductID
Load Up Some Test Data */
Insert into #ProductSub Values (1, 100, null)
Insert into #ProductSub Values (2, 100, null)
Insert into #ProductSub Values (1, 101, null)
Insert into #ProductSub Values (2, 102, null)
Insert into #ProductSub Values (1, 200, null)
Insert into #ProductSub Values (2, 200, '2009-01-01')
Insert into #ProductSub Values (1, 300, '2009-01-01')
Insert into #ProductSub Values (2, 300, null)
Insert into #ProductSub Values (1, 400, '2009-01-01')
Insert into #ProductSub Values (2, 400, '2008-01-01')
Insert into #ProductSub Values (1, 500, '2008-01-01')
Insert into #ProductSub Values (2, 500, '2009-01-01')
Insert into #ProductSub Values (1, 600, '2009-01-01')
Insert into #ProductSub Values (2, 600, '2009-01-01')
--Select * from #ProductSub
Declare @MasterClient int,
@ConsolClient int
Select @MasterClient = 1, @ConsolClient = 2
Select * from #ProductSub t1
/* Use Master Client ID When Expiry Date is Null) */
Where (ClientID = @MasterClient and ExpiryDate is null)
/* Use Consol ClientID if Expiry Date is null nut Expiry Date for Master Client ID is not */
OR (ClientID = @ConsolClient and ExpiryDate is null and ProductID not in (
Select ProductID from #ProductSub t2
Where (ClientID = @MasterClient and ExpiryDate is null))
)
OR -- OH NO my head exploded
/* OR EXISTS (Select 1
from #ProductSub t3
)*/
Drop Table #ProductSub
/********** Expected Output ************************
ClientID ProductID ExpiryDate
1 100 NULL
1 101 NULL
2 102 NULL
1 200 NULL
2 300 NULL
1 400 2009-01-01 00:00:00
2 500 2009-01-01 00:00:00
1 600 2009-01-01 00:00:00
任何和所有帮助都非常感谢
编辑:虽然听起来像这样,但这不是家庭作业,而是一个现实生活中的问题,我希望找到一个现实生活解决方案,我可以自己做这件事,但我所有的解决方案都通向临时表。需要指出的是,生产环境是SQLServer 7!
I am having difficulties with a complicated (for me any way) query.
The table I'm querying has 3 colums, ClientID (int Not Null), ProductID (int Not Null) and ExpiryDate (smalldatetime nullable)
Given two client ID's Master and Consolidated I need to perform the following business logic to return a single data set:
Select the ClientID with the greater
expiry date for a product where expiry
dates for both clientIDs are not nullSelect the ClientID with a null expiry
date for a product where one expiry is
null and the other not nullSelect the MasterID for a product
where both expiry dates are null or
both expiry dates are the same.
I have tried the following, but get stuck...
Create Table #ProductSub (ClientID int NOT NULL,
ProductID int NOT NULL,
ExpiryDate smalldatetime)
/* In real life there is a Clustered Primary Key On ClientID and ProductID
Load Up Some Test Data */
Insert into #ProductSub Values (1, 100, null)
Insert into #ProductSub Values (2, 100, null)
Insert into #ProductSub Values (1, 101, null)
Insert into #ProductSub Values (2, 102, null)
Insert into #ProductSub Values (1, 200, null)
Insert into #ProductSub Values (2, 200, '2009-01-01')
Insert into #ProductSub Values (1, 300, '2009-01-01')
Insert into #ProductSub Values (2, 300, null)
Insert into #ProductSub Values (1, 400, '2009-01-01')
Insert into #ProductSub Values (2, 400, '2008-01-01')
Insert into #ProductSub Values (1, 500, '2008-01-01')
Insert into #ProductSub Values (2, 500, '2009-01-01')
Insert into #ProductSub Values (1, 600, '2009-01-01')
Insert into #ProductSub Values (2, 600, '2009-01-01')
--Select * from #ProductSub
Declare @MasterClient int,
@ConsolClient int
Select @MasterClient = 1, @ConsolClient = 2
Select * from #ProductSub t1
/* Use Master Client ID When Expiry Date is Null) */
Where (ClientID = @MasterClient and ExpiryDate is null)
/* Use Consol ClientID if Expiry Date is null nut Expiry Date for Master Client ID is not */
OR (ClientID = @ConsolClient and ExpiryDate is null and ProductID not in (
Select ProductID from #ProductSub t2
Where (ClientID = @MasterClient and ExpiryDate is null))
)
OR -- OH NO my head exploded
/* OR EXISTS (Select 1
from #ProductSub t3
)*/
Drop Table #ProductSub
/********** Expected Output ************************
ClientID ProductID ExpiryDate
1 100 NULL
1 101 NULL
2 102 NULL
1 200 NULL
2 300 NULL
1 400 2009-01-01 00:00:00
2 500 2009-01-01 00:00:00
1 600 2009-01-01 00:00:00
Any and all help greatly appreciated
EDIT: Although it sounds like it, this is not homework but a real life problem I am hoping to find a real life solution to, I could do this myself, but all my solutions are leading down the path to temp tables. I should point out the production environment is SQLServer 7!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在这里,我已将条件移至子查询。子查询连接 Consol 和 Master 的行,因此您可以访问这两行中的列。条件仍然有点复杂,因为任何一行都可能丢失。
Here I've moved the conditions to a subquery. The subquery joins the rows for Consol and Master, so you can access columns from both rows. The condition is still a little complex because either row can be missing.
问题尚不清楚,但据我解释,可能是这样的:
如果您需要行数据,则将其选择到变量中并执行单独的 SELECT 操作?
The question isn't clear, but as I interpret it, perhaps something like:
If you need the row data, then select that into a variable and do a separate
SELECT
?