我想知道在SQLite中是否存在将数据从长格式转换为宽格式的规范方法(该操作通常位于关系数据库的域中吗?)。我试图跟踪this example的MySQL,但我猜SQLite没有相同的IF构造......谢谢!
答案 0 :(得分:16)
IF
是一个非标准的MySQL扩展。最好始终使用标准SQL的CASE
,并且适用于所有兼容的数据库,包括SQLite和MySQL(以及MSSQL,Oracle,Postgres,Access,Sybase ......等等)。
以下是如何使用CASE
执行相同查询的示例:
SELECT Country,
MAX(CASE WHEN Key = 'President' THEN Value ELSE NULL END) President,
MAX(CASE WHEN Key = 'Currency' THEN Value ELSE NULL END) Currency
FROM Long
GROUP BY Country
ORDER BY Country;
这是使用连接表示相同查询的另一种方法。我认为这可能更有效,但它假设每个组中的每个键值只有一条记录(CASE
版本也是如此,但如果不是这样,则不会产生额外的行,只是小于 - 可预测的结果)。
SELECT
D.Country,
P.Value President,
C.Value Currency
FROM
(
SELECT DISTINCT Country
FROM Long
) D
INNER JOIN
( SELECT Country, Value
FROM Long
WHERE Key = 'President'
) P
ON
D.Country = P.Country
INNER JOIN
( SELECT Country, Value
FROM Long
WHERE Key = 'Currency'
) C
ON
D.Country = C.Country
ORDER BY
D.Country;
记录中,这是我正在使用的DDL和测试数据:
CREATE TABLE Long (ID INTEGER PRIMARY KEY AUTOINCREMENT, Country TEXT, Key TEXT, Value TEXT);
INSERT INTO Long VALUES (NULL, 'USA', 'President', 'Obama');
INSERT INTO Long VALUES (NULL, 'USA', 'Currency', 'Dollar');
INSERT INTO Long VALUES (NULL, 'China', 'President', 'Hu');
INSERT INTO Long VALUES (NULL, 'China', 'Currency', 'Yuan');
答案 1 :(得分:0)
作为对上述优秀答案的更新(作为可推广的解决方案),并参考 OP 中引用的 example,SQLite introduced 3.32.0 版中的 IIF()
函数:
iif(X,Y,Z)
如果 X 为真,iif(X,Y,Z)
函数返回值 Y,否则返回 Z。 iif(X,Y,Z)
函数在逻辑上等同于 CASE 表达式 CASE WHEN X THEN Y ELSE Z END
并生成相同的字节码。
使用已接受答案的 DDL,执行以下查询:
SELECT Country,
MAX( IIF(key='President', Value, NULL)) President,
MAX( IIF(key='Currency', Value, NULL)) Currency
FROM Long
GROUP BY Country;
... 应该重塑 long 格式:
┌────┬─────────┬───────────┬────────┐
│ ID │ Country │ Key │ Value │
├────┼─────────┼───────────┼────────┤
│ 1 │ USA │ President │ Obama │
│ 2 │ USA │ Currency │ Dollar │
│ 3 │ China │ President │ Hu │
│ 4 │ China │ Currency │ Yuan │
└────┴─────────┴───────────┴────────┘
...到宽格式:
┌─────────┬───────────┬──────────┐
│ Country │ President │ Currency │
├─────────┼───────────┼──────────┤
│ China │ Hu │ Yuan │
│ USA │ Obama │ Dollar │
└─────────┴───────────┴──────────┘
这里我们转置行和列。