SQL 查询为其他列中的每个唯一条目返回最高和最低
Posted
技术标签:
【中文标题】SQL 查询为其他列中的每个唯一条目返回最高和最低【英文标题】:SQL Query to return Highest and Lowest for each Unique Entry in other column 【发布时间】:2018-05-08 23:57:58 【问题描述】:对不起,如果我的标题有点混乱,我不知道如何措辞。
我有一张代表巴士时刻表的表格。它对每次旅行的每个站点都有一个条目,以及到达和离开时间以及站点的顺序。例如:
Trip_ID Arrival Departure Stop_ID Stop_Seq
Trip1 06:00:00 06:00:30 465 1
Trip1 06:03:45 06:04:15 474 2
...
Trip1 06:53:15 06:53:45 169 27
Trip1 06:56:30 06:57:00 311 28
Trip2 07:02:00 07:02:30 534 1
Trip2 07:03:45 07:04:15 700 2
...
Trip2 07:41:50 07:42:20 164 35
Trip2 07:45:30 07:46:00 311 36
我的目标是编写一个查询,该查询将为每个独特的行程返回两个结果,即 Stop_Seq 最低的记录和 Stop_Seq 最高的记录(每次行程)。 例如:
Trip_ID Arrival Departure Stop_ID Stop_Seq
Trip1 06:00:00 06:00:30 465 1
Trip1 06:56:30 06:57:00 311 28
Trip2 07:02:00 07:02:30 534 1
Trip2 07:45:30 07:46:00 311 36
我尝试过执行以下操作,但我不太了解 Group By 逻辑。
SELECT trip_id,arrival,departure,stop_id,MIN(stop_seq),MAX(stop_seq)
FROM stop_times
GROUP BY trip_id;
不幸的是,我没有按时间分组并停止,这让我感到不安,但这行不通,我不想要所有时间,只想要第一个和最后一个。
您能提供的任何帮助将不胜感激! :)
【问题讨论】:
【参考方案1】:如果 Stop_Seq 是唯一的,那么您可以使用派生表。派生表从 stop_times 表中获取 Min 和 Max Stop_Seq。接收查询可以加入回来重新获取详细信息:
SELECT dT.Trip_ID
,ST.Arrival
,ST.Departure
,ST.Stop_ID
,dT.Stop_Seq
FROM (
SELECT Trip_ID, MIN(Stop_Seq) AS Stop_Seq FROM stop_times GROUP BY Trip_ID
UNION ALL
SELECT Trip_ID, MAX(Stop_Seq) FROM stop_times GROUP BY Trip_ID
) AS dT
INNER JOIN stop_times ST
ON dT.Trip_ID = ST.Trip_ID
AND dT.Stop_Seq = ST.Stop_Seq
ORDER BY Trip_ID
给出输出:
Trip_ID Arrival Departure Stop_ID Stop_Seq
Trip1 06:00:00 06:00:30 465 1
Trip1 06:56:30 06:57:00 311 28
Trip2 07:02:00 07:02:30 534 1
Trip2 07:45:30 07:46:00 311 36
完整代码如下:http://sqlfiddle.com/#!6/b9efc/1/0
它没有按预期工作的原因是 GROUP BY 删除了重复项,但 Arrival、Departure 和 Stop_ID 列中的值正在更改。这些变化的值破坏了 GROUP BY。
【讨论】:
【参考方案2】:以下查询将返回每个Trip
记录,其最低Stop_Seq
和最高Stop_Seq
。
SELECT *
FROM stop_times a
WHERE a.Stop_Seq=(
SELECT MAX(b.Stop_Seq)
FROM stop_times b
WHERE a.Trip_ID=b.Trip_ID
)
or
a.Stop_Seq=(
SELECT MIN(b.Stop_Seq)
FROM stop_times b
WHERE a.Trip_ID=b.Trip_ID
)
【讨论】:
这个对我来说效果最好。 @Zorko 解决方案不能很好地与 Access 配合使用,它不喜欢在内部联接语句中使用别名。谢谢@Abhilash!【参考方案3】:替代解决方案。使用子查询在两个单独的查询中计算每次行程的最低 stop_seq 和每次行程的最高 stop_seq。 使用 UNION 合并结果。
SELECT a.Trip_ID,a.Arrival, a.Departure, a.Stop_ID, a.Stop_Seq
FROM stop_times as a
WHERE a.Stop_Seq =
(
SELECT Min(b.Stop_Seq)
FROM stop_times as b
WHERE b.Trip_ID =a.Trip_ID
)
UNION SELECT a.Trip_ID,a.Arrival, a.Departure, a.Stop_ID, a.Stop_Seq
FROM stop_times as a
WHERE a.Stop_Seq =
(
SELECT Max(b.Stop_Seq)
FROM stop_times as b
WHERE b.Trip_ID =a.Trip_ID
);
【讨论】:
以上是关于SQL 查询为其他列中的每个唯一条目返回最高和最低的主要内容,如果未能解决你的问题,请参考以下文章
如果另一列中的值是唯一的,那么如何在SQL中放置一个显示1的列,如果它是重复的则为0?