提问人:ar ia 提问时间:10/30/2023 最后编辑:marc_sar ia 更新时间:10/30/2023 访问量:55
添加同一表中的列,而不添加“分组依据 [重复]
Add a column from the same table without adding in Group By [duplicate]
问:
我有一个结构表,其中包含 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 中查看了类似的问题,并尝试合并给出的解决方案,但没有成功。
如果我不能正确地提出这个问题,我深表歉意。如果其中有任何错误,请要求我更正。
您的帮助将不胜感激。
答:
1赞
Yitzhak Khabinsky
10/30/2023
#1
请尝试以下基于窗口函数的解决方案。ROW_NUMBER()
这是一个两步过程:
- 我们的 CTE 根据每个结构的日期顺序对每个结构的检查进行排名 via 子句。
PARTITION BY Structure_ID
ORDER BY Inspection_Date DESC
SELECT
after 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 不同以及它是如何工作的。
上一个:SQL - 跨列的分组依据值
评论