.. role:: rfg .. role:: ulined Basic Queries ============= Source: https://www.sqlitetutorial.net Query data from tables ---------------------- General order ````````````` .. code-block:: sql FROM table_list JOIN table ON join_condition WHERE row_filter ORDER BY column LIMIT count OFFSET offset GROUP BY column HAVING group_filter; Basic ````` Select all items from a table .. raw:: html
    SELECT * FROM tableA;
    
Select all items from a table column .. code-block:: sql SELECT columnA FROM tableA; Select all items from several table columns .. code-block:: sql SELECT columnA, columnB FROM tableA; Rename resulting column names ````````````````````````````` Renaming column names of resulting matches .. raw:: html
    SELECT columnA AS foo, columnB AS bar FROM tableA;
    
Define value for additional columns ``````````````````````````````````` Each row will receive the value ‘MyValue’ in column ’Type’ .. raw:: html
    SELECT columnA, 'MyValue' AS Type FROM tableA;
    
No duplicates ````````````` Select items without duplicate values (single column) or combination (multiple columns) .. raw:: html
    SELECT DISTINCT columnA FROM tableA;
    
.. code-block:: sql SELECT DISCTINCT columnA, columnB FROM tableA; Order results by columnA primarily, secondarily by columnB .. code-block:: sql SELECT columnA, columnB FROM tableA ORDER BY columnA ASC, columnB ASC; Order results by column ID (here: columnB = 2, columnC = 3) .. code-block:: sql SELECT columnA, columnB, columnC FROM tableA ORDER BY 2 ASC, 3 ASC; Filter results `````````````` Basic syntax .. raw:: html
    SELECT column_list FROM table WHERE search_condition;
    
Comparison operators +-----------+---------------------------+ | Operator | Meaning | +===========+===========================+ | = | Equal to | +-----------+---------------------------+ | <> or != | Not equal to | +-----------+---------------------------+ | < | Less than | +-----------+---------------------------+ | > | Greater than | +-----------+---------------------------+ | <= | Less than or equal to | +-----------+---------------------------+ | >= | Greater than or equal to | +-----------+---------------------------+ Logical operators +----------+--------------------------------------------------------------------------------------+ | Operator | Meaning | +==========+======================================================================================+ | AND | returns 1 if both expressions are 1, and 0 if one of the expressions is 0. | +----------+--------------------------------------------------------------------------------------+ | BETWEEN | returns 1 if a value is within a range. | +----------+--------------------------------------------------------------------------------------+ | EXISTS | returns 1 if a subquery contains any rows. | +----------+--------------------------------------------------------------------------------------+ | IN | returns 1 if a value is in a list of values. | +----------+--------------------------------------------------------------------------------------+ | LIKE | returns 1 if a value matches a pattern | +----------+--------------------------------------------------------------------------------------+ | NOT | reverses the value of other operators such as NOT EXISTS, NOT IN, NOT BETWEEN, etc. | +----------+--------------------------------------------------------------------------------------+ | OR | returns true if either expression is 1 | +----------+--------------------------------------------------------------------------------------+ Single condition (value from column) .. code-block:: sql SELECT columnA FROM tableA WHERE columnA > 5000; Multiple conditions .. raw:: html
    # must all be true
    SELECT columnA, columnB FROM table WHERE columnA > 5000 AND columnB = 10;

    # at least one must be true
    SELECT columnA, columnB FROM table WHERE ANY columnA > 5000 AND columnB = 10;
    
Search value containing a substring (LIKE) -> case-insensitive .. raw:: html
    # must all be true
    SELECT columnA FROM table WHERE columnA LIKE ‘%foobar_’;
    
.. hint:: +---+---------------------------------+ | % | matches zero or more characters | +---+---------------------------------+ | _ | matches a single character | +---+---------------------------------+ Search value that contains any of the wildcard characters (``%`` or ``_``) (here: ‘\' is used as escape character) .. raw:: html
    SELECT columnA FROM table WHERE columnA LIKE ’%50\%%’ ESCAPE ‘\’;
    
Search value containing a substring (GLOB) -> case-sensitive .. raw:: html
    SELECT columnA FROM table where columnA GLOB ‘?Man*’;
    
.. hint:: +----+---------------------------------+ | \* | matches zero or more characters | +----+---------------------------------+ | ? | matches a single character | +----+---------------------------------+ Search if value within a range of allowed values .. raw:: html
    SELECT columnA FROM table WHERE columnA IN (10,20,30);
    
Search if value is between two values (value itself are included) .. raw:: html
    SELECT columnA FROM table WHERE columnA BETWEEN 1 AND 10;
    
Search if value is not between two values (values itself are not included .. raw:: html
    SELECT columnA FROM table WHERE columnA NOT BETWEEN 100 and 199;
    
Limit results ````````````` Limit the amount of rows to return (here: 10) .. raw:: html
    SELECT columnA FROM table LIMIT 10;
    
Limit with an offset (start at nth row of the results, here: 30) .. raw:: html
    SELECT columnA FROM table LIMIT 10 OFFSET 30;
    
Join data from multiple tables `````````````````````````````` Usually foreign keys are used in these conditions (here: someID), which exists in all joined tables. Returns row only if condition matches (here: someID value exists for both a row in tableA and tableB) -> INNER JOIN .. raw:: html
    # regular
    SELECT columnA, columnB FROM tableA INNER JOIN tableB ON tableB.sameID = tableA.someID;

    # shortened via aliases
    SELECT A.columnA, B.ColumnB FROM tableA A INNER JOIN tableB B ON A.someID = B.someID;

    # shortened using USING
    SELECT columnA, columnB FROM tableA INNER JOIN tableB USING(tableA.someID);

    # 2+ tables
    SELECT someID, tableA.columnA, tableB.columnB, tableC.columnC
    FROM tableA
    INNER JOIN tableB ON tableB.someID = tableA.someID
    INNER JOIN tableC ON tableC.someID = tableB.someID;
    
.. figure:: _img/inner_join.png :align: center Inner Join Adding additional condition(s) .. code-block:: sql SELECT columnA, columnB FROM tableA INNER JOIN tableB USING(tableA.someID) WHERE columnA < 10; Returns any row, but uses NULL (here: for columnB value) if “right” table does not have a matching row -> LEFT JOIN .. raw:: html
    # regular
    SELECT columnA, columnB FROM tableA LEFT JOIN tableB ON tableA.someID = tableB.someID;

    # using USING
    SELECT columnA, columnB FROM tableA LEFT JOIN tableB USING (tableA.someID);
    
.. figure:: _img/left_join.png :align: center Left Join Creates a Cartesian product of tables (i.e. all possible column combinations) .. raw:: html
    SELECT columnA FROM tableA CROSS JOIN tableB;
    
Join various columns of a table with itself .. code-block:: sql SELECT columnA1, colummA2 FROM tableA a1 INNER JOIN tableA a2 ON a1.someID = a2.anotherID; Split result into group ``````````````````````` Display count results as groups (one row per resulting group) while using an aggregate function (e.g. COUNT) .. raw:: html
    SELECT columnA, COUNT(someID) FROM tableA GROUP BY columnA;

    # more real example (returns number of tracks per album)
    SELECT albumid, COUNT(trackid) FROM tracks GROUP BY albumid;
    
Without the group by statement, all values for “notuniqueID” are just counted (which returns number of not NULL values for this column). The GROUP BY statement splits up this count to the various values in columnA Combine with INNER JOIN .. code-block:: sql SELECT tableA.columnA1, columnA2, COUNT(someID) FROM tableA INNER JOIN tableB ON tableB.columnA1 = tableA.columnA1 GROUP BY tableA.columnA1; Returns only results that have match on tableB. Please note that *tableA.columnA1* must be specified after SELECT, since both *tableA* and *tableB* have this column. MAX, MIN and AVG functions .. raw:: html
    SELECT tableA.columnA1, min(columnA2), max(columnA2), round(avg(columnA2),2)
    FROM tableA
    INNER JOIN tableB ON tableB.columnA1 = tableA.columnA1
    GROUP BY tableA.columnA1;
    
Grouping by multiple columns (will create all combination values of columnA1 and columnA2 as groups) .. code-block:: sql SELECT columnA1, columnA2, count(someID) FROM tableA GROUP BY columnA1, columnA2; Filter groups ````````````` The HAVING clause can only be applied to group results Direct value .. raw:: html
    SELECT columnA, COUNT(someID) FROM tableA GROUP BY columnA HAVING columnA = 1;
    
Value range .. raw:: html
    SELECT columnA, COUNT(someID) FROM tableA GROUP BY columnA HAVING count(someID) BETWEEN 18 AND 20;
    
Combine multiple queries into single results ```````````````````````````````````````````` Combine two queries into one result (eliminating duplicates) .. raw:: html
    SELECT columnA FROM tableA UNION 18 AND SELECT columnB from tableB;
    
-> results from columnB are merged into columnA results (no duplicates) Combine two queries into one result (including duplicates) .. raw:: html
    SELECT columnA FROM tableA UNION ALL 18 AND SELECT columnB from tableB;
    
-> results from columnB are merged into columnA results (including duplicates) .. figure:: _img/union.png :align: center Union .. figure:: _img/union_all.png :align: center Union All Filter out results from left query that has a match in right query .. raw:: html
    SELECT columnA FROM tableA EXCEPT SELECT columnA FROM tableB;
    
Return rows that are output of two queries `````````````````````````````````````````` .. note:: Both data value and data type must be equal. .. raw:: html
    SELECT columnA FROM tableA INTERSECT SELECT columnB FROM tableB;
    
.. figure:: _img/intersect.png :align: center Intersect Subqueries `````````` Nest a SELECT statement into another ... … within WHERE .. code-block:: sql SELECT columnA, columnB FROM tableA WHERE columnA IN ( SELECT columnB FROM tableB WHERE columnC = 10 ); … within FROM .. code-block:: sql SELECT columnA FROM ( SELECT SUM(columnB) SIZE FROM tableB GROUP BY some_id ) AS columnB_subset; Check if subquery returns any result: * Zero -> False * One or more -> True Only return row if tableB has same value in its columnA .. raw:: html
    SELECT columnA FROM tableA A WHERE EXISTS ( SELECT columnA from tableB WHERE columnA = A.columnA );
    
.. note:: Some EXISTS operations can also be done with IN, but EXISTS in faster. Only return row if tableB does :ulined:`not` have that value in its columnA .. raw:: html
    SELECT columnA FROM tableA A WHERE NOT EXISTS ( SELECT columnA from tableB WHERE columnA = A.columnA );
    
CASE … WHEN … THEN … ELSE … END ``````````````````````````````` Set value ‘foo’ for columnB value, if column contains the value 1 otherwise set ‘bar' .. raw:: html
    SELECT columnA, CASE columnB WHEN '1' THEN 'foo' ELSE 'bar' FROM tableA;
    
Can also be used with other comparisons (set columnB to ‘little’, ‘medium’ or ‘large’ depending on its integer value) .. raw:: html
    SELECT columnA,
        CASE
            WHEN columnB < 1000 THEN ‘little’
            WHEN columnB >= 1000 AND columnB < 10000 THEN ‘medium’
            ELSE ‘large’
        END columnB
    FROM tableA;
    
Add & Update data ----------------- Insert new data values to table ``````````````````````````````` Insert single row to table .. raw:: html
    INSERT INTO tableA (columnA,columnB) VALUES(‘hello’,1);
    
Insert multiple rows .. code-block:: sql INSERT INTO tableA (columnA, columnB) VALUES ('Hello', 1), ('World', 2), ('Here', 3), ('I', 4), ('Am', 5) Insert default values (increment ID columns, add NULL to others) .. raw:: html
    INSERT INTO tableA DEFAULT VALUES;
    
Insert values provided by SELECT statement .. code-block:: sql INSERT INTO tableA_backup SELECT columnA, columnB FROM tableA; Change column data `````````````````` Update single column under condition .. raw:: html
    UPDATE tableA SET columnA = 'some value' WHERE columnB = 10;
    
Update multiple columns .. code-block:: sql UPDATE tableA SET columnA = 'some value', columnX = 0, columnY = 'valueA' WHERE columnB = 10; Update using other column's values .. code-block:: sql UPDATE tableA SET columnA = LOWER(columnB || "." || columnC || "@example.com") ORDER BY columnA LIMIT 1; Delete data ``````````` Delete entire rows .. raw:: html
    DELETE FROM tableA WHERE columnB = 10;
    
Delete all rows from table .. code-block:: sql DELETE FROM tableA; Replace rows (Delete + Add) ``````````````````````````` If **no** unique index column is defined for a table, a REPLACE statement will simply add the values (same as INSERT). Define a unique index (here: columnA) -> two rows cannot have the same value for columnA .. raw:: html
    CREATE UNIQUE INDEX columnA ON tableA (columnA);
    
Replace single column .. raw:: html
    REPLACE INTO tableA (columnA, columnB) VALUES ('some value', 10);
    
REPLACE deletes the old row and inserts a new one. A primary identifier column will receive the next available id, but not the one from the deleted row. Transaction ``````````` *coming later* https://www.sqlitetutorial.net/sqlite-transaction/