我有一个交易表,如:
id | incoming | value | created_at
--------------------------------------------
1 | t | 1.88 | 2016-09-23 11:01:02
2 | t | 1.55 | 2016-09-23 11:02:02
3 | t | 0.73 | 2016-09-23 11:03:02
4 | t | 2.30 | 2016-09-23 11:04:02
5 | t | 0.82 | 2016-09-23 11:05:02
6 | t | 1.01 | 2016-09-23 11:06:02
7 | t | 2.33 | 2016-09-23 11:07:02
8 | f | 7.00 | 2016-09-23 11:08:02
9 | f | 1.20 | 2016-09-23 11:09:02
10 | f | 0.74 | 2016-09-23 11:10:02
11 | f | 1.53 | 2016-09-23 11:11:02
我能用一个查询得到这样的表而没有任何额外的数据库功能:
true_value | false_value | true_date | false_date
----------------------------------------------------------------------
1.88 | 7.00 | 2016-09-23 11:01:02 | 2016-09-23 11:08:02
1.55 | 1.20 | 2016-09-23 11:02:02 | 2016-09-23 11:09:02
0.73 | 0.74 | 2016-09-23 11:03:02 | 2016-09-23 11:10:02
2.30 | 1.53 | 2016-09-23 11:04:02 | 2016-09-23 11:11:02
0.82 | NULL | 2016-09-23 11:05:02 | NULL
1.01 | NULL | 2016-09-23 11:06:02 | NULL
2.33 | NULL | 2016-09-23 11:07:02 | NULL
就像在incoming = TRUE
到incoming = FALSE
的{{1}}之间联系表一样,但每个incoming = TRUE
行只有一行incoming = FALSE
行没有重复
答案 0 :(得分:1)
您可以将行号分配给由id
列排序的真假传入记录,然后加入这些行号。这将根据您的预期输出匹配真假记录。为了便于阅读,我在这里使用公用表表达式,并尽量减少执行此操作所需的代码量。
WITH cte AS (
SELECT id, incoming, value, created_at,
ROW_NUMBER() OVER (PARTITION BY incoming ORDER BY id) rn
FROM transaction
)
SELECT t1.value AS true_value,
t2.value AS false_value,
t1.created_at AS true_date,
t2.created_at AS false_date
FROM cte t1
LEFT JOIN cte t2
ON t1.rn = t2.rn AND
t2.incoming = 'f'
WHERE t1.incoming = 't'
ORDER BY t1.id;
在这里演示:
答案 1 :(得分:0)
上一篇文章是正确的,虽然不完全,因为它缺少对true / false的过滤器。这是一个包含两个CTE的示例,一个用于真值,另一个用于伪值,然后合并。
with
i as (select incoming, value, created_at, row_number() over (order by id asc) as RowNum from TRans where incoming = 't'),
o as (select incoming, value, created_at, row_number() over (order by id asc) as RowNum from TRans where incoming = 'f')
select i.value as true_value, o.value as false_value, i.created_at as true_date, o.created_at as false_Date
from i
left outer join o on i.RowNum = o.RowNum