【问题标题】:SQL for grouping results in same line用于在同一行中分组结果的 SQL
【发布时间】:2019-12-05 15:47:52
【问题描述】:

我有这个表数据结构(PostgreSQL顺便说一句,只需将一些记录粘贴到excel中即可显示):

我需要像这样聚合结果:

我的“进入”条件是高速公路 98、英里 94 和南路或高速公路 55、英里 214 和东路。

我的“离开”条件是98号高速公路,北路或55号高速公路,214英里和西路,必须输入!

我的做法:

SELECT plate, highway FROM (
SELECT DISTINCT plate, highway FROM plates
    WHERE plate IN (
        SELECT DISTINCT plate FROM plates
            WHERE (
                rodovia = 98 AND way = 'South' AND miles = 94 OR 
                rodovia = 55 AND miles = 214 AND way = 'East'
            ) GROUP BY plate
    ) AND ( 
        highway = 98 AND way = 'North' OR highway = 55 AND miles = 214 AND way = 'West'
    ) GROUP by plate, highway
) t GROUP BY plate, highway

但是我不知道如何将“进入”和“离开”分组在同一行,也不知道查询是否正确

有人吗?

【问题讨论】:

  • 我对你的结果感到困惑。我看不出与您提供的数据的关系。
  • 是的,我知道,就像我说我不知道​​该怎么做
  • 你能解释一下逻辑吗?你的问题看起来很有趣。我猜你需要一个递归 CTE 来根据你的逻辑走图。
  • @TheImpaler 是的,我有一张大桌子,上面有很多在高速公路上行驶的车牌。我需要根据我之前提到的条件对这些盘子进行分组。 “进入”条件是当这个车牌进入我需要的高速公路的某个部分时,所以“离开”

标签: sql postgresql pivot


【解决方案1】:

如果您创建两个不同的 CTE,一个用于进入,一个用于离开,您可以轻松地包含进入和离开高速公路的参数。然后最后将两者连接并执行计算以获得周期。

    WITH ENTER_COND AS
    (
    SELECT DISTINCT 
        plate,
        MIN(time) AS enter_time,
        highway AS enter_highway
    FROM plates
    WHERE (highway = 98 AND miles = 94 AND way = 'South')
         OR (highway = 55 AND miles = 217 AND way = 'East')
    GROUP BY
        plate,
        highway
    )
,LEAVE_COND AS
    (
    SELECT DISTINCT 
        plate,
        MAX(time) AS leave_time,
        highway AS leave_highway
    FROM plates
    WHERE (highway = 98 AND miles = 94 AND way = 'North')
         OR (highway = 55 AND miles = 217 AND way = 'West')
    GROUP BY
        plate,
        highway
    )
SELECT
    e.plate,
    e.enter_time,
    e.enter_highway,
    l.leave_time,
    l.leave_highway,
    (l.leave_time - e.enter_time) AS period
FROM ENTER_COND e
JOIN LEAVE_COND l
    ON e.plate = l.plate
GROUP BY
    e.plate,
    e.enter_time,
    e.enter_highway,
    l.leave_time,
    l.leave_highway
;

我希望这会有所帮助。

【讨论】:

  • Yes 帮了我很多,但是在我的预期结果上关注“PLATE 1”,第一行和第二行的输入与使用您提供的查询相同。有办法获取下一个输入记录吗?
  • @c0nf1ck,我在您的标准列表中看到您在第一种情况下没有里程。但是,如果它不应该在那里会改变您的结果,那么如果它应该有英里,则需要将滞后函数添加到 leave_cond cte。因此,而不是 MAX(time) AS leave_time,它需要是 MAX(LAG(TIME,1) OVER (PARTITION BY Highway, Miles, Meters, Way, Plate ORDER BY time,highway, miles, metres, way, plate) ) 作为请假时间。
  • 滞后函数告诉它抓取“TIME”中的下一个值。所以如果你有一个 1 ,那就是下一行,一个 2 将是下一行。 LAG() OVER 被称为开窗,如果你不了解sql中的开窗函数,请准备好你的头脑:)
  • 感谢您的帮助。现在遇到这个问题:聚合函数调用不能包含窗口函数调用
【解决方案2】:
select  enter.plate, 
        enter.time enter_time, 
        enter.highway enter_highway, 
        leave.time leave_time, 
        leave.highway leave_highway, 
        DATEDIFF(SS, enter.time, leave.time) period
from    (select plate, highway, time from highway h1 where time = (select min(time) from highway h2 where h1.plate = h2.plate)) enter
        join (select plate, highway, time from highway h1 where time = (select max(time) from highway h2 where h1.plate = h2.plate)) leave on enter.plate = leave.plate

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-12
    • 2021-10-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多