我有一个交易表,比如:
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
,但是每个incoming = TRUE
行只得到一个incoming = FALSE
行,没有重复项 最佳答案
您可以将行号分配给按id
列排序的true和false传入记录,然后对这些行号进行联接。这将根据您的预期输出匹配正确和错误记录。我在这里使用了一个通用的表表达式来提高可读性,并最小化我们需要执行的代码量。
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;
演示:
Rextester