这就是它目前的工作方式,首先选择查询返回参数列表。
SELECT character_id, foe_id, location_id, date_time, damage, points FROM events ORDER BY date_time DESC LIMIT 100
现在迭代100次来完成数据,例如第一个返回character_id = 12695,location_id = 818,foe_id = 33997,date_time = '2024-05-02 23:00:00'。
SELECT *, A1+B1-C1-D1-E1-F1+G1+H1 AS A2 FROM
(SELECT * FROM
(SELECT id_, cnt_7, date_diff_7 , NTH_VALUE (A0,1) OVER() AS A1, NTH_VALUE (A0,2) OVER() AS B1, NTH_VALUE (B0,1) OVER() AS C1, NTH_VALUE (B0,2) OVER() AS D1 FROM
(SELECT damage AS A0, points AS B0, RootQuery_7.id as id_, count(*) over() as cnt_7, max(date_diff) over() as date_diff_7 FROM
(SELECT *, extract(day from date_time - lag(date_time) over (ORDER BY date_time)) as date_diff FROM events WHERE character_id = 12695 AND status = 1 AND location_id = 818 AND date_time < '2024-05-02 23:00:00' ORDER BY date_time DESC LIMIT 10 OFFSET 0)
AS RootQuery_7)
AS BaseQuery7 LIMIT 1) wnd_1
JOIN (SELECT id_, cnt_8, date_diff_8 , NTH_VALUE (D0,2) OVER() AS H1, NTH_VALUE (C0,1) OVER() AS E1, NTH_VALUE (C0,2) OVER() AS F1, NTH_VALUE (D0,1) OVER() AS G1 FROM
(SELECT damage AS C0, points AS D0, RootQuery_8.id as id_, count(*) over() as cnt_8, max(date_diff) over() as date_diff_8 FROM
(SELECT *, extract(day from date_time - lag(date_time) over (ORDER BY date_time)) as date_diff FROM events WHERE foe_id = 33997 AND status = 1 AND location_id = 818 AND date_time < '2024-05-02 23:00:00' ORDER BY date_time DESC LIMIT 15 OFFSET 0)
AS RootQuery_8)
AS BaseQuery8 LIMIT 1) wnd_2
ON wnd_1.id_ <> 0 WHERE cnt_7 >= 10 AND date_diff_7 <= 150 AND cnt_8 >= 10 AND date_diff_8 <= 150) AS layer_1
它可以工作,但效率太低且速度太慢,请不要介意检索数据的真实性,因为它只是一个示例。
我想做的是从像这样的单个查询中获取结果列表
(SELECT character_id, foe_id, location_id, date_time, damage, points FROM events ORDER BY date_time DESC LIMIT 100) ref_
JOIN
SELECT *, A1+B1-C1-D1-E1-F1+G1+H1 AS A2 FROM
(SELECT * FROM
(SELECT id_, cnt_7, date_diff_7 , NTH_VALUE (A0,1) OVER() AS A1, NTH_VALUE (A0,2) OVER() AS B1, NTH_VALUE (B0,1) OVER() AS C1, NTH_VALUE (B0,2) OVER() AS D1 FROM
(SELECT damage AS A0, points AS B0, RootQuery_7.id as id_, count(*) over() as cnt_7, max(date_diff) over() as date_diff_7 FROM
(SELECT *, extract(day from date_time - lag(date_time) over (ORDER BY date_time)) as date_diff FROM events WHERE character_id = ref_.character_id AND status = 1 AND location_id = ref_.location_id AND date_time < location_id = ref_.date_time ORDER BY date_time DESC LIMIT 10 OFFSET 0)te_time
AS RootQuery_7)
AS BaseQuery7 LIMIT 1) wnd_1
JOIN (SELECT id_, cnt_8, date_diff_8 , NTH_VALUE (D0,2) OVER() AS H1, NTH_VALUE (C0,1) OVER() AS E1, NTH_VALUE (C0,2) OVER() AS F1, NTH_VALUE (D0,1) OVER() AS G1 FROM
(SELECT damage AS C0, points AS D0, RootQuery_8.id as id_, count(*) over() as cnt_8, max(date_diff) over() as date_diff_8 FROM
(SELECT *, extract(day from date_time - lag(date_time) over (ORDER BY date_time)) as date_diff FROM events WHERE foe_id = ref_.foe_id AND status = 1 AND location_id = ref_.location_id AND date_time < location_id = ref_.date_time ORDER BY date_time DESC LIMIT 15 OFFSET 0)
AS RootQuery_8)
AS BaseQuery8 LIMIT 1) wnd_2
ON wnd_1.id_ <> 0 WHERE cnt_7 >= 10 AND date_diff_7 <= 150 AND cnt_8 >= 10 AND date_diff_8 <= 150) AS layer_1
ON ...
但是第一个查询结果的结果不能在第二个查询的最深层 select 中使用
TLDR:使用
LATERAL
连接。
LATERAL
连接允许右侧的表达式引用左侧 FROM
项中的列。参见:
您的查询可能如下所示:
SELECT *, A1+B1-C1-D1-E1-F1+G1+H1 AS A2
FROM (
SELECT character_id, foe_id, location_id, date_time, damage, points FROM events ORDER BY date_time DESC LIMIT 100
) prime
JOIN LATERAL ( -- !
SELECT id_, cnt_7, date_diff_7
, nth_value(A0,1) OVER () AS A1, nth_value(A0,2) OVER () AS B1, nth_value(B0,1) OVER () AS C1, nth_value(B0,2) OVER () AS D1
FROM (
SELECT damage AS A0, points AS B0, RootQuery_7.id AS id_, count(*) OVER () AS cnt_7, max(date_diff) OVER () AS date_diff_7
FROM (
SELECT *, extract(day FROM e.date_time - lag(e.date_time) OVER (ORDER BY e.date_time)) AS date_diff
FROM events e
WHERE e.status = 1
AND e.character_id = prime.character_id -- LATERAL reference
AND e.location_id = prime.location_id -- LATERAL reference
AND e.date_time < prime.date_time -- LATERAL reference
ORDER BY e.date_time DESC
LIMIT 10
OFFSET 0
) AS RootQuery_7
) AS BaseQuery7
LIMIT 1
) wnd_1 ON wnd_1.id_ <> 0
CROSS JOIN LATERAL ( -- !
SELECT id_, cnt_8, date_diff_8 , nth_value(D0,2) OVER () AS H1, nth_value(C0,1) OVER () AS E1, nth_value(C0,2) OVER () AS F1, nth_value(D0,1) OVER () AS G1
FROM (
SELECT damage AS C0, points AS D0, RootQuery_8.id AS id_, count(*) OVER () AS cnt_8, max(date_diff) OVER () AS date_diff_8
FROM (
SELECT *, extract(day from date_time - lag(date_time) OVER (ORDER BY date_time)) AS date_diff
FROM events
WHERE status = 1
AND foe_id = prime.foe_id -- LATERAL reference
AND location_id = prime.location_id -- LATERAL reference
AND date_time < prime.date_time -- LATERAL reference
ORDER BY date_time DESC
LIMIT 15
OFFSET 0
) RootQuery_8
) BaseQuery8
LIMIT 1
) wnd_2
WHERE wnd_1.cnt_7 >= 10
AND wnd_1.date_diff_7 <= 150
AND wnd_2.cnt_8 >= 10
AND wnd_2.date_diff_8 <= 150;
当然可以进一步简化。但这超出了这个问题的范围。