假设数据
(def results (jdbc/plan @datasource2 ["select * from cabs"]))
(into [] (map :name) results) => ["a", "b"]
(into [] (map identity) results) => gives an error - [..... missing `map` or `reduce` {row}]
转换为几段时间,这是从最小登机到最大登机的时间
我使用迭代来获得期望的结果,但想要优化查询(设置基准或CTE)以提高性能,
这就是我想要的
ID Date Mode
1 2019-09-20 09:28 IN
2 2019-09-20 19:00 IN
3 2019-09-20 19:00 IN
4 2019-09-20 19:00 IN
5 2019-09-20 19:01 IN
6 2019-09-20 19:01 IN
7 2019-09-20 19:01 Out
8 2019-09-20 20:28 IN
9 2019-09-20 20:35 IN
10 2019-09-20 20:50 Out
11 2019-09-20 20:55 Out
12 2019-09-20 21:30 IN
答案 0 :(得分:2)
这是一个基于空缺的问题。
首先,可以使用以下查询生成连续记录组:
SELECT [Mode], MIN(id) min_id, MAX(id) max_id, MIN([Date]) min_date, MAX([Date]) max_date
FROM (
SELECT
id,
[Date],
[Mode],
ROW_NUMBER() OVER(ORDER BY [Date]) rn1,
ROW_NUMBER() OVER(PARTITION BY [Mode] ORDER BY [Date]) rn2
FROM mytable
) x
GROUP BY [Mode], (rn1 - rn2)
这将产生:
Mode | min_id | max_id | min_date | max_date :--- | -----: | -----: | :--------------- | :--------------- IN | 1 | 6 | 2019-09-20 09:28 | 2019-09-20 19:01 Out | 7 | 7 | 2019-09-20 19:01 | 2019-09-20 19:01 IN | 8 | 9 | 2019-09-20 20:28 | 2019-09-20 20:35 Out | 10 | 11 | 2019-09-20 20:50 | 2019-09-20 20:55 IN | 12 | 12 | 2019-09-20 21:30 | 2019-09-20 21:30
然后,您可以将此查询转换为cte并对其进行自我联接以生成预期的结果集:
WITH cte AS (
SELECT [Mode], MIN(id) min_id, MAX(id) max_id, MIN([Date]) min_date, MAX([Date]) max_date
FROM (
SELECT
id,
[Date],
[Mode],
ROW_NUMBER() OVER(ORDER BY [Date]) rn1,
ROW_NUMBER() OVER(PARTITION BY [Mode] ORDER BY [Date]) rn2
FROM mytable
) x
GROUP BY [Mode], (rn1 - rn2)
)
SELECT c1.min_id IdIn, c1.min_date DateIN, c2.max_id IdOut, c2.max_date DateOut
FROM cte c1
INNER JOIN cte c2
ON c1.mode = 'IN'
AND c2.mode = 'Out'
AND c2.min_id = c1.max_id + 1
输出:
IdIn | DateIN | IdOut | DateOut ---: | :--------------- | ----: | :--------------- 1 | 2019-09-20 09:28 | 7 | 2019-09-20 19:01 8 | 2019-09-20 20:28 | 11 | 2019-09-20 20:55
答案 1 :(得分:0)
您可以使用CTE-
尝试以下选项您可以检查DEMO HERE
Warning message:
In system(cmd, wait = FALSE) : system call failed: Cannot allocate memory
答案 2 :(得分:0)
SQL Server 2008不再受支持的产品。所有受支持的SQL Server版本都支持lag()
和lead()
。
您可以轻松地将这些功能用于此目的。有一个简单的观察结果:
'IN'
(或不存在)时,您需要一条'OUT'
记录。'OUT'
(或不存在)时,您需要一条'IN'
记录过滤掉这些记录后,您只需获取每个'OUT'
记录和先前的'IN'
值即可得出最终结果:
select prev_id, prev_dt as date_in, id, dt as date_out
from (select io.*,
lag(dt) over (order by dt) as prev_dt,
lag(id) over (order by dt) as prev_id
from (select t.*,
lag(mode) over (order by dt) as prev_mode,
lead(mode) over (order by dt) as next_mode
from t
) io
where mode = 'IN' and (prev_mode is null or prev_mode = 'OUT') or
mode = 'OUT' and (next_mode is null or next_mode = 'IN')
) io
where mode = 'OUT';
Here是db <>小提琴。
之所以提供此功能,是因为仅使用lag()
/ lead()
而不使用任何聚合或join
可能会比其他方法具有更好的性能。