Интересно, существует ли канонический способ преобразования данных из long в широкоформатный в SQLite (обычно ли это операция в области реляционных баз данных?). Я попытался выполнить этот пример для MySQL, но я думаю, что SQLite не имеет такой же конструкции IF... Спасибо!
Широкоформатные форматы SQLite?
Ответ 1
IF
- это нестандартное расширение MySQL. Лучше всегда использовать CASE
, который является стандартным SQL и работает во всех совместимых базах данных, включая 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');