sqlite - 根据字段值将 2 行中的相同字段组合成 2 列
Posted
技术标签:
【中文标题】sqlite - 根据字段值将 2 行中的相同字段组合成 2 列【英文标题】:sqlite - combine same field in 2 rows into 2 columns based on field value 【发布时间】:2021-02-01 02:26:44 【问题描述】:我有一个 sqlite 表,其中的数据类似于以下内容:
id | flag
----+-----
1 | 0
2 | 0
3 | 1
4 | 0
5 | 1
6 | 0
7 | 1
我希望得到如下所示的结果:
id1 | id2
----+-----
1 | null
2 | null
3 | 5
4 | null
6 | null
7 | null
为了解释,我试图“组合”每“对”记录的 id(按顺序),其中“flag == 1”。如果记录具有“标志 == 0”,则 id2 应该为 NULL。另请注意,由于我有奇数条记录,其中“flag == 1”(在此示例中),最后一个(id = 7)没有额外的记录配对,所以它也有一个 id2 字段为 NULL。
这是否可以通过纯 SQL(在本例中为 sqlite3)实现?我显然可以在主机应用程序中对结果进行后处理,但希望不必这样做。
*** 编辑 ***
正在添加请求的 MRE...
CREATE TABLE test (
id INTEGER NOT NULL PRIMARY KEY,
flag INTEGER NOT NULL );
INSERT INTO test(flag) VALUES(0),(0),(1),(0),(1),(0),(1);
【问题讨论】:
当然可以。请按照您使用的标签 wiki 中的描述提供 MRE ***.com/tags/sqlite/info,以便更轻松地回答。 谢谢。添加了 MRE。 【参考方案1】:您可以使用窗口函数MIN()
和ROW_NUMBER()
:
SELECT id id1, CASE WHEN flag THEN next END id2
FROM (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY flag ORDER BY id) rn,
MIN(CASE WHEN flag THEN id END) OVER (ORDER BY id ROWS BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING) next
FROM test
)
WHERE flag = 0 OR rn % 2 = 1
ORDER BY id1
请参阅demo。 结果:
id1 | id2 |
---|---|
1 | null |
2 | null |
3 | 5 |
4 | null |
6 | null |
7 | null |
【讨论】:
【参考方案2】:您可以使用自连接和 SUM()
窗口函数随着 id 值的增加而增加,同时通过使用模运算符 (%
) 来区分奇数和偶数值,例如
WITH t AS
(
SELECT *, SUM(flag) OVER (ORDER BY id) AS fl
FROM test
)
SELECT t1.id AS id1,
MAX(CASE WHEN t1.flag * t2.flag* abs(t2.fl % 2-1)=1 THEN t2.id END ) AS id2
FROM t AS t1
LEFT JOIN t AS t2
ON t1.fl + 1 = t2.fl
GROUP BY t1.id
Demo
【讨论】:
谢谢。但是,查看链接的演示,这不会产生预期的结果。当一个项目“配对”到第 2 列 (id2) 中时,它不应再出现在结果集中的其他位置(请参阅我的原始示例输出)。例如,在您的演示中,我看到3 | 5
正确配对在一起,但后来在结果集中看到 5 | null
。
不客气@JeffGodfrey,但我刚刚扩展了数据以显示更多对。对于原始案例删除最后两条记录such as
嗨,巴巴罗斯。我不认为这是问题所在。单个记录 ID 在结果集中不应出现多次。无论是否包含其他记录,我都会在结果集中看到两次记录 ID 5
。一次,与记录 3 配对,一次单独配对。也许我误解了什么?以上是关于sqlite - 根据字段值将 2 行中的相同字段组合成 2 列的主要内容,如果未能解决你的问题,请参考以下文章
根据 WooCommerce 中的自定义字段值将文本添加到订单摘要