【问题标题】:SQL Select First column and for each row select unique ID and the last dateSQL 选择第一列并为每一行选择唯一 ID 和最后日期
【发布时间】:2015-01-18 02:44:39
【问题描述】:

今天早上我遇到了一个问题,我尝试了很多解决方案,但都没有给我预期的结果。

我有一张像这样的表:

+----+----------+-------+
| ID | COL2     | DATE  | 
+----+----------+-------+
|  1 | 1        |  2001 | 
|  1 | 2        |  2002 | 
|  1 | 3        |  2003 | 
|  1 | 4        |  2004 | 
|  2 | 1        |  2001 | 
|  2 | 2        |  2002 | 
|  2 | 3        |  2003 | 
|  2 | 4        |  2004 | 
+----+----------+-------+

我有一个查询,它返回如下结果: 我有唯一的 ID,对于这个 ID,我想获取 ID 的最后日期

+----+----------+-------+
| ID | COL2     | DATE  | 
+----+----------+-------+
|  1 | 4        |  2004 | 
|  2 | 4        |  2004 | 
+----+----------+-------+

但我不知道该怎么做。 我试过加入,交叉申请..

如果你有什么想法,

谢谢

克莱门特法亚德

【问题讨论】:

  • 你尝试过的。添加您尝试过的选择语句。添加您的预期输出。

标签: sql sql-server join unique cross-apply


【解决方案1】:
declare @t table (ID INT,Col2 INT,Date INT)
insert into @t(ID,Col2,Date)values (1,1,2001)
insert into @t(ID,Col2,Date)values (1,2,2001)
insert into @t(ID,Col2,Date)values (1,3,2001)
insert into @t(ID,Col2,Date)values (1,4,2001)
insert into @t(ID,Col2,Date)values (2,1,2002)
insert into @t(ID,Col2,Date)values (2,2,2002)
insert into @t(ID,Col2,Date)values (2,3,2002)
insert into @t(ID,Col2,Date)values (2,4,2002)

;with cte as(
    select
        *,
        rn = row_number() over(partition by ID order by Col2 desc)
    from @t

)
select
    ID,
    Col2,
    Date
from cte
where
    rn = 1

【讨论】:

  • 非常感谢您对我的帮助:D
  • 既然用户不会给你投票,我给你+1 - 这是要走的路。
【解决方案2】:
SELECT ID,MAX(Col2),MAX(Date) FROM tableName GROUP BY ID

【讨论】:

    【解决方案3】:

    如果 col2 和 date 总是组合中的最高值,则可以尝试

    SELECT ID, MAX(COL2), MAX(DATE)
    FROM Table1
    GROUP BY ID
    

    但这不是很好。 另一种方法是子查询:

    SELECT yourtable.ID, sub1.COL2, sub1.DATE
    FROM yourtable 
    INNER JOIN -- try with CROSS APPLY for performance AND without ON 1=1
    (SELECT TOP 1 COL2, DATE
     FROM yourtable sub2
     WHERE sub2.ID = topquery.ID
     ORDER BY COL2, DATE) sub1 ON 1=1
    

    【讨论】:

      【解决方案4】:

      你没有告诉你的桌子的名字是什么,所以我假设它下面是tbl

      SELECT m.ID, m.COL2, m.DATE
      FROM tbl m
        LEFT JOIN tbl o ON m.ID = o.ID AND m.DATE < o.DATE
      WHERE o.DATE is NULL
      ORDER BY m.ID ASC
      

      说明: 左边的查询使用ID 列将表tbl 与自身(别名o,对于“其他”)连接起来,别名为m(对于“max”);条件m.DATE &lt; o.DATE 会将m 中的所有行与o 中在DATE 中具有更大值的行组合起来。对于来自m 的给定值ID,具有最大值DATE 的行在o 中没有对(没有大于最大值的值)。由于LEFT JOIN,这一行将与NULLs 的行合并。 WHERE 子句只为o.DATE 选择具有NULL 的这些行(即它们的最大值为m.DATE)。

      查看SQL Antipatterns: Avoiding the Pitfalls of Database Programming 书籍以了解其他 SQL 提示。

      【讨论】:

        【解决方案5】:

        为此,您必须排除 COL2 您的查询应如下所示

        SELECT ID, MAX(DATE) 
        FROM table_name 
        GROUP BY ID 
        

        上述查询为每个 ID 生成最大日期。 使用该查询使用 COL2 是没有意义的,除非您想要每个 ID 和 COL2 的最大日期 在这种情况下,您可以运行:

        选择 ID、COL2、MAX(日期) 按 ID 分组,COL2;

        当您使用聚合函数(如 max())时,您必须始终按 select 语句中的所有其他列进行分组。

        我认为您正面临这个问题是因为您的桌子设计存在一些根本缺陷。通常 ID 应该是一个主键(它是唯一的)。在此表中,您有重复的 ID。我不了解表格背后的业务逻辑,但对我来说似乎有一些缺陷。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-11-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多