【问题标题】: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

似乎还有许多其他方法可以解决这个问题。 我只需要一个有效的 :) 我已经绞尽脑汁半天了,没有进步。

感谢您的帮助 大卫

【问题讨论】:

    标签: sql sql-server sql-server-2008-r2


    【解决方案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 的人,所以一旦它起作用,我往往会停止寻找。但是,我将尝试更多地了解您的解决方案是如何工作的。非常感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-21
    • 2019-01-23
    • 1970-01-01
    相关资源
    最近更新 更多