添加同一表中的列,而不添加“分组依据 [重复]

Add a column from the same table without adding in Group By [duplicate]

提问人:ar ia 提问时间:10/30/2023 最后编辑:marc_sar ia 更新时间:10/30/2023 访问量:55

问:

我有一个结构表,其中包含 5000 多个结构和 20 多列。为简单起见,我将只显示 3 个结构和 4 列。我称之为表 S。

结构 ID 结构名称 结构状态 结构长度
5 弗雷泽 打开 120
7 罗杰 Cr 打开 176
8 托比 打开 105

另一张表是关于对上述结构的检查。此表称为“表 I”,其中只有几列显示。

结构 ID 检验日期 结构指标 紧迫性
5 2003 年 5 月 27 日 2.16 3
5 2004 年 4 月 28 日 1.65 5
5 1999 年 8 月 16 日 3.15 5
5 2013 年 5 月 15- 2.54 2
5 1995 年 9 月 12 日 1.99 2
5 2012 年 12 月 8 日 2.13 3
7 10月 06, 2016 3.11 4
7 5月 05, 2022 1.77 2
7 6月 14, 2020 2.65 2
7 2013 年 5 月 18- 1.89 1
7 8月 21, 2023 2.02 1
8 2010 年 6 月 3 日 1.76 3
8 8月 28, 2022 3.32 5
8 10月 21, 2021 1.98 1

我想要的是每个结构只显示其最新的检查日期。我使用的代码确实得到了结果。

代码和结果如下所示;

SELECT 
    a.structure_id "Structure ID",
    func.description "Function",
    a.NAME,
    b.description "Structure Status",
    a.structure_length "Structure Length",
    i.inspection_date "Inspection Date",
FROM 
    STRUCTURE a    
LEFT JOIN
    STRUCTURE_STATUS b ON a.STRUCTURE_STATUS = b.STRUCTURE_STATUS
LEFT JOIN 
    structure_elec_dist ed ON a.structure_id = ed.structure_id
LEFT JOIN 
    hwy_elec_dis hwy ON ed.elect_dis_no = hwy.elect_dist_no
LEFT JOIN 
    structure_function func ON a.structure_function = func.structure_functio
LEFT JOIN 
    (SELECT structure_id, MAX(inspection_date) AS "latest date"
     FROM structure_inspection
     GROUP BY structure_id) i ON a.structure_id = i.structure_id

结果是:

结构 ID 功能 名字 结构状态 结构长度 最新日期
5 弗雷泽 打开 120 2012 年 12 月 8 日
7 罗杰 Cr 打开 176 8月 21, 2023
8 托比 打开 105 8月 28, 2022

不幸的是,当我打算包含表 I 中的其他列(例如“结构索引”和“紧迫性”)时,行数开始增加,因为我也必须将它们包含在我不想要的子句中。GROUP BY

我想要的结果是:

结构 ID 功能 名字 结构状态 结构 Len. 最新日期 结构。指数 紧迫性
5 弗雷泽 打开 120 2012 年 12 月 8 日 2.13 3
7 罗杰 Cr 打开 176 8月 21, 2023 2.02 1
8 托比 打开 105 8月 28, 2022 3.32 5

在过去的两天里,我一直在努力解决这个问题。我在 Stackoverflow 中查看了类似的问题,并尝试合并给出的解决方案,但没有成功。

如果我不能正确地提出这个问题,我深表歉意。如果其中有任何错误,请要求我更正。

您的帮助将不胜感激。

sql-server 分组

评论

1赞 Yitzhak Khabinsky 10/30/2023
在提出问题时,您需要提供一个最小的可重现示例:(1) DDL 和示例数据填充,即 CREATE 表和 INSERT T-SQL 语句。(2) 需要执行的操作,即逻辑和代码尝试在 T-SQL 中实现它。(3) 期望的输出,基于上面 #1 中的示例数据。(4) 您的 SQL Server 版本 (SELECT @@version;)。

答:

1赞 Yitzhak Khabinsky 10/30/2023 #1

请尝试以下基于窗口函数的解决方案。ROW_NUMBER()

这是一个两步过程:

  1. 我们的 CTE 根据每个结构的日期顺序对每个结构的检查进行排名 via 子句。PARTITION BY Structure_IDORDER BY Inspection_Date DESC
  2. SELECTafter CTE 应用子句过滤掉行 seq 值大于 1。WHERE seq = 1

SQL算法

-- DDL and sample data population, start
DECLARE @structure TABLE (Structure_ID INT PRIMARY KEY, Structure_Name VARCHAR(20), Structure_Status VARCHAR(20), Structure_Length INT);
INSERT @structure (Structure_ID, Structure_Name, Structure_Status, Structure_Length) VALUES
(5, 'Fraser',   'Open', 120),
(7, 'Roger Cr', 'Open', 176),
(8, 'Toby',     'Open', 105);

DECLARE @inspection TABLE (Structure_ID INT, Inspection_Date DATE, Structure_Index DECIMAL(4,2), Urgency INT);
INSERT @inspection (Structure_ID, Inspection_Date, Structure_Index, Urgency) VALUES
(5, '2003-05-27', 2.1, 3),
(5, '2004-04-28', 1.6, 5),
(5, '1999-08-16', 3.1, 5),
(5, '2013-05-15', 2.5, 2),
(5, '1995-09-12', 1.9, 2),
(5, '2012-12-08', 2.1, 3),
(7, '2016-10-06', 3.1, 4),
(7, '2022-05-05', 1.7, 2),
(7, '2020-06-14', 2.6, 2),
(7, '2013-05-18', 1.8, 1),
(7, '2023-08-21', 2.0, 1),
(8, '2010-06-03', 1.7, 3),
(8, '2022-08-28', 3.3, 5),
(8, '2021-10-21', 1.9, 1);
-- DDL and sample data population, end

WITH rs AS
(
    SELECT * 
        , seq = ROW_NUMBER() OVER (PARTITION BY Structure_ID ORDER BY Inspection_Date DESC)
    FROM @inspection
)
SELECT s.*
    , rs.inspection_Date, rs.Structure_Index, rs.Urgency
FROM @structure AS s
    INNER JOIN rs ON rs.Structure_ID = s.Structure_ID
WHERE seq = 1;

输出

Structure_ID Structure_Name Structure_Status Structure_Length inspection_Date Structure_Index 紧迫性
5 弗雷泽 打开 120 2013-05-15 2.50 2
7 罗杰 Cr 打开 176 2023-08-21 2.00 1
8 托比 打开 105 2022-08-28 3.30 5

评论

1赞 MatBailie 10/30/2023
请不要添加纯代码答案,而是记录为什么这与 GROUP BY 不同以及它是如何工作的。