Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQLite long to wide formats?

Tags:

sql

sqlite

rdbms

I wonder if there is a canonical way to convert data from long to wide format in SQLite (is that operation usually in the domain of relational databases?). I tried to follow this example for MySQL but I guess SQLite does not have the same IF construct... Thanks!

like image 475
hatmatrix Avatar asked Mar 15 '10 02:03

hatmatrix


People also ask

Does SQLite support long?

SQLite does not support built-in date and time storage classes. However, you can use the TEXT, INT, or REAL to store date and time values.

How big is too big for SQLite?

SQLite database files have a maximum size of about 140 TB. On a phone, the size of the storage (a few GB) will limit your database file size, while the memory size will limit how much data you can retrieve from a query. Furthermore, Android cursors have a limit of 1 MB for the results.

Is SQLite faster than text file?

Better performanceReading and writing from an SQLite database is often faster than reading and writing individual files from disk. See 35% Faster Than The Filesystem and Internal Versus External BLOBs.

What data types are supported by SQLite?

SQLite only has four primitive data types: INTEGER, REAL, TEXT, and BLOB. APIs that return database values as an object will only ever return one of these four types.


1 Answers

IF is a non-standard MySQL extension. It's better to always use CASE which is standard SQL and works in all compliant databases, including SQLite and MySQL (and MSSQL, Oracle, Postgres, Access, Sybase... and on and on).

Here's an example of how to do the same query with 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;

Here's another way to represent the same query using joins. I think this is probably more efficient, but it assumes there's only one record for each key value within each group (the CASE version does too, but will not result in extra rows if that's not true, just less-than-predictable results).

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;

And for the record, here's the DDL and test data I was using:

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');
like image 83
Samuel Neff Avatar answered Nov 06 '22 03:11

Samuel Neff