我有一个交易表,比如:

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 = TRUEincoming = 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

10-05 22:51