将 SQLite 列转换为行

Posted

技术标签:

【中文标题】将 SQLite 列转换为行【英文标题】:Turn SQLite columns to rows 【发布时间】:2017-03-14 07:58:10 【问题描述】:

我正在尝试将返回具有多列的单行的查询转换为具有一列或多列的多行。例如,我的查询看起来像以下可视化:

SELECT _id, value1, value2, value3, value4 FROM table WHERE _id IS 1;

结果:

_id   value1   value2   value3   value4
----------------------------------------
1     10       11       12       13

我希望我的结果如下所示:

name    value
--------------
value1  10
value2  11
value3  12
value4  13

但我也可以使用这样的东西:

value
-----
10
11
12
13

目前我在 android 中使用 MatrixCursor 手动转换它,但理想的情况是光标已经处于可用状态。有没有办法修改我的查询以检索所需架构中的结果,或者使用临时表之类的东西来实现所需的最终状态?

此外,是否有一个通用术语来描述数据库中的此功能?

【问题讨论】:

如果您希望它是临时的,那么如果您需要名称和值,您可以轻松地将结果存储在列表或地图中。 ID 不能重复。它应该是独一无二的。因此,您不能为多行使用相同的 ID。 感谢 Darshan 的回复,我已经将结果存储在 MatrixCursor 中,但是在使用 CursorAdaptor 时会导致很多复杂性。最简单的方法是通过选择将数据按摩到首选布局中。我的 MatrixCursor 已经在工作了,我只是在寻找一个更优雅的解决方案。 @Vlad 这是一个很好的观点,我对保留 ID 不是很感兴趣,因为我已经知道该值(我正在查询它)。但重点是将每个结果的列添加为新行。 【参考方案1】:

没有可以自动执行此操作的内置机制。

如果您知道列,则可以构造一个单独处理每一列的查询:

SELECT _id, 'value1' AS name, value1 AS value FROM tab WHERE _id = 1
UNION ALL
SELECT _id, 'value2' AS name, value2 AS value FROM tab WHERE _id = 1
UNION ALL
SELECT _id, 'value3' AS name, value3 AS value FROM tab WHERE _id = 1
UNION ALL
SELECT _id, 'value4' AS name, value4 AS value FROM tab WHERE _id = 1;

这不一定比 MatrixCursor 更好。

【讨论】:

【参考方案2】:

为什么不在值表上只使用JOIN,然后在正确的列上使用CASE

SELECT original_table._id,
  CASE t.column1 WHEN 1 THEN 'value1' WHEN 2 THEN 'value2' WHEN 3 THEN 'value3' ELSE 'value4' END AS name, 
  CASE t.column1 WHEN 1 THEN  original_table.value1 WHEN 2 THEN  original_table.value2 WHEN 3 THEN  original_table.value3 ELSE  original_table.value4 END AS value
FROM (
  select 1 _id, 10 value1 , 11 value2 , "string value" value3 , 13 value4
  union all 
  select 2, 14,  "string value",null,17
) original_table
JOIN (VALUES(1),(2),(3),(4)) t
--ORDER BY _id, t.column1;

结果:

id  name    value
1   value1  10
1   value2  11
1   value3  string value
1   value4  13
2   value1  14
2   value2  string value
2   value3  null
2   value4  17

或者添加这个以避免空值:

 ON (t.column1=1 AND original_table.value1 IS NOT NULL) OR (t.column1=2 AND original_table.value2 IS NOT NULL) OR (t.column1=3 AND original_table.value3  IS NOT NULL) OR (t.column1=4 AND original_table.value4  IS NOT NULL) 

【讨论】:

以上是关于将 SQLite 列转换为行的主要内容,如果未能解决你的问题,请参考以下文章

sqlite:具有自动递增列的多列主键

SQLite python - 将值转换为变量

将月份列转换为行并聚合其下的其他列

在 Sqlite (Dbeaver) 中转换 Epoch 时间并解析出时间

熊猫将列转换为行[重复]

将数据从列转换为行[重复]