选择具有最长日期和其他条件的行
Posted
技术标签:
【中文标题】选择具有最长日期和其他条件的行【英文标题】:Select the row with the maximum date and other criteria 【发布时间】:2018-06-26 07:02:20 【问题描述】:我知道以前有人问过这个问题,并且我查看了很多解决方案,但我无法调整任何解决方案来适应我的问题。 我想返回每个公司的行和具有最大日期的 complianceTypeID。
此查询显示我的数据。
SELECT [ComplianceItemID]
,[CorporationID]
,[Date]
,[ComplianceTypeID]
FROM [Compliance].[dbo].[ViewComplianceItem]
Where CorporationID = '869'
返回这个结果
ComplianceItemID CorporationID Date ComplianceTypeID
55761 869 2018-06-20 1
56840 869 2022-11-07 2
57919 869 1900-01-01 3
58998 869 1900-01-01 4
60077 869 1900-01-01 5
61156 869 1900-01-01 6
62235 869 1900-01-01 7
63316 869 2018-06-25 8
63322 869 2018-06-26 1
我只想返回每个 ComplianceTypeID 中日期最高的行
我稍后将参数化查询而不是固定的 CoprorationID。
我希望看到返回 8 行,应排除第 1 行,因为还有另一个 ComplianceTypeID 1 具有较新的日期。
我已经尝试过了,但只返回了 5 行,日期均为 '1900-01-01'
SELECT
VC1.ComplianceItemID,
VC1.CorporationID,
VC1.[Date],
VC1.ComplianceTypeID
FROM ViewComplianceItem VC1
Left Join ViewComplianceItem VC2
On VC1.ComplianceTypeID = VC2.ComplianceTypeID
AND VC1.[Date] > VC2.[Date]
Where VC2.[Date] is null
AND VC1.CorporationID = '869'
结果
ComplianceItemID CorporationID Date ComplianceTypeID
57919 869 1900-01-01 3
58998 869 1900-01-01 4
60077 869 1900-01-01 5
61156 869 1900-01-01 6
62235 869 1900-01-01 7
似乎还有许多其他方法可以解决这个问题。 我只需要一个有效的 :) 我已经绞尽脑汁半天了,没有进步。
感谢您的帮助 大卫
【问题讨论】:
【参考方案1】:这通常使用窗口函数来处理。
create procedure my proc (@corpID int)
as
begin
;WITH CTE AS(
SELECT
[ComplianceItemID]
,[CorporationID]
,[Date]
,[ComplianceTypeID]
,RN = row_number() over (partition by ComplianceTypeID order by [Date] desc)
FROM [Compliance].[dbo].[ViewComplianceItem]
WHERE CorporationID = @corpID)
SELECT
[ComplianceItemID]
,[CorporationID]
,[Date]
,[ComplianceTypeID]
FROM CTE
WHERE RN = 1
end
您也可以不进行参数化,或忽略 WHERE
子句,并将其添加到 PARTITION BY
以恢复您的逻辑,适用于每个公司。
WITH CTE AS(
SELECT
[ComplianceItemID]
,[CorporationID]
,[Date]
,[ComplianceTypeID]
,RN = row_number() over (partition by CorporationID, ComplianceTypeID order by [Date] desc)
FROM [Compliance].[dbo].[ViewComplianceItem])
SELECT
[ComplianceItemID]
,[CorporationID]
,[Date]
,[ComplianceTypeID]
FROM CTE
WHERE RN = 1
最后,这也可以使用派生表和MAX
聚合来处理:
SELECT
t1.[ComplianceItemID]
,t1.[CorporationID]
,t1.[Date]
,t1.[ComplianceTypeID]
FROM [Compliance].[dbo].[ViewComplianceItem] t1
INNER JOIN (SELECT CorporationID, ComplianceItemID, MAX([Date]) dt
FROM [Compliance].[dbo].[ViewComplianceItem]
GROUP BY CorporationID, ComplianceItemID) t2 on
t2.CorporationID = t1.CorporationID
and t2.ComplianceItemID = t1.ComplianceItemID
and t2.dt = t1.[Date]
【讨论】:
@scismon,感谢您的详细回复,使用派生表的第三个选项不起作用。它仍然返回所有 9 行。前两个示例有效,但它们引入了几个我不理解的新概念。如何参数化它以便我可以选择一个公司 ID? 我想我找到了让它发挥作用的方法。我用你的 sql 创建了一个视图。我应该能够创建一个从视图中读取数据的参数化查询。不是最优雅的解决方案,但我认为它会起作用。我不确定您是否建议我使用您的 sql 创建函数?明天我会对此进行测试,并在它起作用后将您的答案标记为正确:) 我进行了编辑,向您展示如何使用 proc 进行操作。 在看到您的更新之前,我最终选择了第二个。我创建了一个视图,然后使用 SQL 从我的 c# 程序调用该视图,其中包括 where 语句和公司 ID 的参数。它完全按照我的需要工作。我是一个自学 SQL 的人,所以一旦它起作用,我往往会停止寻找。但是,我将尝试更多地了解您的解决方案是如何工作的。非常感谢您的帮助。以上是关于选择具有最长日期和其他条件的行的主要内容,如果未能解决你的问题,请参考以下文章
Oracle SQL 选择具有开始和结束日期的行,如果某些重叠合并行