Your country

Tools that support it use your country for local currency, number formats, units and paper size. Your choice is saved only in this browser.

Type a name or a two-letter code. Use the up and down arrow keys to move through the countries, Enter to choose one and Escape to close.

SQL (PostgreSQL, MySQL, SQLite) Module 2 – Filtering and sorting rows

ORDER BY, LIMIT and OFFSET

Sort SQL results with ORDER BY on several columns, decide where NULLs go in PostgreSQL, MySQL and SQLite, and page through rows with LIMIT and OFFSET safely.

  • Beginner
  • 20 minutes
  • Examples run with sql.js 1.14.2
  • By MySmartCoPilot

What you will learn

  • Sort by several columns and directions
  • Choose where NULLs sort in PostgreSQL, MySQL and SQLite
  • Retrieve the first N rows and page through a sorted result

Before you start

On this page

A table has no built-in order. The rows of a result arrive in whatever order the database finds convenient, which depends on how the data happens to be stored and on the plan the database picks for the query. The PostgreSQL and SQLite manuals both say so plainly: without ORDER BY, the order is not defined. So whenever the order matters, to a person reading a list or to a program showing “the first ten”, the query has to ask for it.

Sorting with ORDER BY

ORDER BY comes after WHERE and lists one or more sort keys. Each key sorts in ascending order (ASC, smallest first) unless you add DESC. Rows are sorted by the first key; only rows that tie on it are sorted by the second key, and so on:

Three sort keys, two directions SQL · sort_keys.sql
CREATE TABLE products (
  id          INTEGER PRIMARY KEY,
  name        TEXT    NOT NULL,
  category    TEXT    NOT NULL,
  price_paise INTEGER NOT NULL
);
INSERT INTO products VALUES
  (1, 'Toor dal 1 kg',       'pulses',    16500),
  (2, 'Basmati rice 5 kg',   'grains',    62000),
  (3, 'Moong dal 1 kg',      'pulses',    14500),
  (4, 'Sona masoori 10 kg',  'grains',    74000),
  (5, 'Chana dal 1 kg',      'pulses',    11000),
  (6, 'Wheat atta 10 kg',    'grains',    48000),
  (7, 'Masoor dal 1 kg',     'pulses',    14500);

-- By category A to Z; inside a category, the most expensive first;
-- products with the same price by name.
SELECT category, price_paise, name
FROM products
ORDER BY category, price_paise DESC, name;

Output

┌──────────┬─────────────┬────────────────────┐
│ category │ price_paise │        name        │
├──────────┼─────────────┼────────────────────┤
│ grains   │ 74000       │ Sona masoori 10 kg │
│ grains   │ 62000       │ Basmati rice 5 kg  │
│ grains   │ 48000       │ Wheat atta 10 kg   │
│ pulses   │ 16500       │ Toor dal 1 kg      │
│ pulses   │ 14500       │ Masoor dal 1 kg    │
│ pulses   │ 14500       │ Moong dal 1 kg     │
│ pulses   │ 11000       │ Chana dal 1 kg     │
└──────────┴─────────────┴────────────────────┘

Recorded with sql.js 1.14.2 (SQLite 3.49.1) on macOS 26 arm64. To run it yourself: sqlite3 -box :memory: < sort_keys.sql

DESC belongs to the key just before it, not to the whole list: ORDER BY category, price_paise DESC sorts the categories from A to Z and the prices inside each category from high to low. The two lentils at 14500 paise tie on both of the first two keys, and the third key, name, decides between them.

A sort key can be any expression, a column that is not in the SELECT list, or the name you gave an output column with AS. You may also see ORDER BY 2, meaning the second column of the output; it works in all three engines, but it breaks silently when someone reorders the SELECT list, and MySQL’s manual marks it as deprecated.

Ties and the tie-breaker

When several rows have the same value for every sort key, the database may return them in any order, and that order can change between engines, versions or runs. Usually nobody notices, until a query takes only the first few rows:

A top five with a tie at the edge SQL · top_five.sql
CREATE TABLE products (id INTEGER PRIMARY KEY, name TEXT NOT NULL, price_paise INTEGER NOT NULL);
INSERT INTO products VALUES
  (1, 'Cashews 500 g',    52000), (2, 'Saffron 1 g',    30000),
  (3, 'Almonds 500 g',    45000), (4, 'Ghee 1 l',       65000),
  (5, 'Pistachios 250 g', 30000), (6, 'Honey 500 g',    24000),
  (7, 'Raisins 500 g',    18000), (8, 'Walnuts 500 g',  52000);

-- Six rows, to see what happens at the edge of a top five:
-- the fifth and sixth products cost the same.
SELECT id, name, price_paise
FROM products
ORDER BY price_paise DESC
LIMIT 6;

-- The top five, with id as the tie-breaker: the same five rows every time.
SELECT id, name, price_paise
FROM products
ORDER BY price_paise DESC, id
LIMIT 5;

Output

┌────┬──────────────────┬─────────────┐
│ id │       name       │ price_paise │
├────┼──────────────────┼─────────────┤
│ 4  │ Ghee 1 l         │ 65000       │
│ 1  │ Cashews 500 g    │ 52000       │
│ 8  │ Walnuts 500 g    │ 52000       │
│ 3  │ Almonds 500 g    │ 45000       │
│ 2  │ Saffron 1 g      │ 30000       │
│ 5  │ Pistachios 250 g │ 30000       │
└────┴──────────────────┴─────────────┘
┌────┬───────────────┬─────────────┐
│ id │     name      │ price_paise │
├────┼───────────────┼─────────────┤
│ 4  │ Ghee 1 l      │ 65000       │
│ 1  │ Cashews 500 g │ 52000       │
│ 8  │ Walnuts 500 g │ 52000       │
│ 3  │ Almonds 500 g │ 45000       │
│ 2  │ Saffron 1 g   │ 30000       │
└────┴───────────────┴─────────────┘

Recorded with sql.js 1.14.2 (SQLite 3.49.1) on macOS 26 arm64. To run it yourself: sqlite3 -box :memory: < top_five.sql

Saffron and pistachios cost the same 30000 paise, so they share fifth place. SQLite happened to put saffron first, but nothing promises that. Another engine, a new index or more data could make the same query return pistachios, and two pages of a list could then both show, or both skip, the same product. The second query adds id, which is unique, as the last key. With a tie-breaker that no two rows share, the order is complete and the top five is the same every time.

PostgreSQL can instead keep every product that ties for the last place, with the standard clause FETCH FIRST 5 ROWS WITH TIES in place of a LIMIT. Sorted by price_paise DESC alone, it returns the six rows of the first query here; after ORDER BY price_paise DESC, id nothing ties any more, and it returns five.

Where NULLs go

The engines do not agree on where missing values belong in a sort:

  • SQLite and MySQL treat NULL as smaller than any value: first in ascending order, last in descending order.
  • PostgreSQL treats NULL as larger than any value: last in ascending order, first in descending order.

You can choose the position yourself. Standard SQL adds NULLS FIRST or NULLS LAST after a sort key, and PostgreSQL and SQLite accept it. MySQL 8.4 does not, but sorting by price_paise IS NULL first does the same job there, because that test is 0 for the priced rows and 1 for the others:

Moving the unpriced product to the end SQL · null_order.sql
CREATE TABLE products (id INTEGER PRIMARY KEY, name TEXT NOT NULL, price_paise INTEGER);
INSERT INTO products VALUES
  (1, 'Jaggery 1 kg', 9000),    (2, 'Kokum 200 g', NULL),  -- not priced yet
  (3, 'Tamarind 500 g', 12000), (4, 'Mango pickle 400 g', 15000);

-- SQLite's default: NULL sorts before every other value.
SELECT name, price_paise FROM products ORDER BY price_paise;

-- Standard SQL, accepted by SQLite and PostgreSQL but not by MySQL.
SELECT name, price_paise FROM products ORDER BY price_paise NULLS LAST;

-- A form that also works in MySQL: sort by "is it missing?" first (0 before 1).
SELECT name, price_paise FROM products ORDER BY price_paise IS NULL, price_paise;

Output

┌────────────────────┬─────────────┐
│        name        │ price_paise │
├────────────────────┼─────────────┤
│ Kokum 200 g        │             │
│ Jaggery 1 kg       │ 9000        │
│ Tamarind 500 g     │ 12000       │
│ Mango pickle 400 g │ 15000       │
└────────────────────┴─────────────┘
┌────────────────────┬─────────────┐
│        name        │ price_paise │
├────────────────────┼─────────────┤
│ Jaggery 1 kg       │ 9000        │
│ Tamarind 500 g     │ 12000       │
│ Mango pickle 400 g │ 15000       │
│ Kokum 200 g        │             │
└────────────────────┴─────────────┘
┌────────────────────┬─────────────┐
│        name        │ price_paise │
├────────────────────┼─────────────┤
│ Jaggery 1 kg       │ 9000        │
│ Tamarind 500 g     │ 12000       │
│ Mango pickle 400 g │ 15000       │
│ Kokum 200 g        │             │
└────────────────────┴─────────────┘

Recorded with sql.js 1.14.2 (SQLite 3.49.1) on macOS 26 arm64. To run it yourself: sqlite3 -box :memory: < null_order.sql

The second and third queries give the same order; the third form is the one to use in MySQL. Writing the position of NULLs explicitly also documents the decision for the next reader.

Taking the first rows: LIMIT

LIMIT n keeps the first n rows of the sorted result, and OFFSET m skips m rows before it starts counting. The order of work matters: the database filters, then sorts, then skips, then takes.

Steps of LIMIT 3 OFFSET 3: WHERE keeps 8 products, ORDER BY sorts them, OFFSET skips 3, LIMIT returns the next 3 as the page.1. WHERE keeps the rows(here all eight products)2. ORDER BY name sorts themAmla, Bael, Chikoo, Dates, …3. OFFSET 3 skipsAmla, Bael and Chikoo4. LIMIT 3 returnsDates, Elaichi and FigsThe page: three rows(Guava and Honey are left out)

How LIMIT 3 OFFSET 3 takes the second page of a sorted result

Text description of the diagram

The diagram shows the steps from top to bottom.

  1. WHERE keeps the rows; in this example all eight products.
  2. ORDER BY name sorts them: Amla, Bael, Chikoo, Dates and so on.
  3. OFFSET 3 skips the first three rows: Amla, Bael and Chikoo.
  4. LIMIT 3 returns the next three rows: Dates, Elaichi and Figs.

The result is a page of three rows; Guava and Honey, which come after them, are left out. OFFSET skips rows only after they have been found and sorted, which is why a large OFFSET still costs the database the work of the rows it skips.

LIMIT without ORDER BY returns an arbitrary few rows, which is fine for a quick look at a table and wrong almost everywhere else.

Paging through results

A list shown page by page is ORDER BY with LIMIT and OFFSET. With s rows a page, page n is LIMIT s OFFSET (n - 1) * s:

Pages of three products SQL · pages.sql
CREATE TABLE products (id INTEGER PRIMARY KEY, name TEXT NOT NULL);
INSERT INTO products VALUES
  (1, 'Amla'), (2, 'Bael'), (3, 'Chikoo'), (4, 'Dates'),
  (5, 'Elaichi'), (6, 'Figs'), (7, 'Guava'), (8, 'Honey');

-- Three products a page. Page 2 skips the first page's 3 rows.
SELECT id, name FROM products ORDER BY name LIMIT 3 OFFSET 3;

-- The last page holds what is left.
SELECT id, name FROM products ORDER BY name LIMIT 3 OFFSET 6;

Output

┌────┬─────────┐
│ id │  name   │
├────┼─────────┤
│ 4  │ Dates   │
│ 5  │ Elaichi │
│ 6  │ Figs    │
└────┴─────────┘
┌────┬───────┐
│ id │ name  │
├────┼───────┤
│ 7  │ Guava │
│ 8  │ Honey │
└────┴───────┘

Recorded with sql.js 1.14.2 (SQLite 3.49.1) on macOS 26 arm64. To run it yourself: sqlite3 -box :memory: < pages.sql

The first query is page 2; the last page simply holds fewer rows. SQLite and MySQL also accept a shorter form with two numbers and a comma, which is easy to misread:

LIMIT with a comma SQL · limit_comma.sql
CREATE TABLE products (id INTEGER PRIMARY KEY, name TEXT NOT NULL);
INSERT INTO products VALUES
  (1, 'Amla'), (2, 'Bael'), (3, 'Chikoo'), (4, 'Dates'),
  (5, 'Elaichi'), (6, 'Figs'), (7, 'Guava'), (8, 'Honey');

-- SQLite and MySQL also accept LIMIT with two numbers and a comma.
SELECT id, name FROM products ORDER BY name LIMIT 2, 3;

Output

┌────┬─────────┐
│ id │  name   │
├────┼─────────┤
│ 3  │ Chikoo  │
│ 4  │ Dates   │
│ 5  │ Elaichi │
└────┴─────────┘

Recorded with sql.js 1.14.2 (SQLite 3.49.1) on macOS 26 arm64. To run it yourself: sqlite3 -box :memory: < limit_comma.sql

LIMIT 2, 3 skipped two rows and returned three: the first number is the offset and the second the count, the reverse of the order in which LIMIT … OFFSET … names them. The SQLite manual itself calls this counter-intuitive and recommends the OFFSET keyword, and PostgreSQL’s LIMIT has no comma form at all, so LIMIT 3 OFFSET 2 is the form to write.

Three more details differ between the engines:

  • Skipping rows and returning all the rest. PostgreSQL writes LIMIT ALL OFFSET m and SQLite LIMIT -1 OFFSET m, since a negative limit means no limit there. MySQL has no keyword for it: its manual suggests a very large count, LIMIT m, 18446744073709551615.
  • What the count and the offset may be. PostgreSQL and SQLite accept expressions that give a whole number. MySQL wants non-negative whole-number constants, or ? placeholders in a prepared statement.
  • Rows tied for the last place. Only PostgreSQL, of the three, can add them, with FETCH FIRST n ROWS WITH TIES.

Paging with OFFSET has a cost that grows with the page number: to show page 500, the database still has to work through the rows of the 499 pages before it, only to throw them away. It also shifts when rows are added while someone pages through. For long lists, the performance module shows keyset pagination, which remembers the last row of a page instead of counting rows.

Text and numbers that sort strangely

Two sorting surprises come from the data rather than from the query:

Letter case and numbers stored as text SQL · text_sort.sql
CREATE TABLE items (name TEXT NOT NULL, size TEXT NOT NULL);
INSERT INTO items VALUES ('apple', '9'), ('Banana', '10'), ('cherry', '100'), ('Date', '25');

-- Text sorts by character codes: capital letters before small ones,
-- and '10' before '9', because '1' comes before '9'.
SELECT name, size FROM items ORDER BY name;
SELECT name, size FROM items ORDER BY size;

-- Fixes: sort without regard to case, and sort numbers as numbers.
SELECT name FROM items ORDER BY name COLLATE NOCASE;
SELECT name, size FROM items ORDER BY CAST(size AS INTEGER);

Output

┌────────┬──────┐
│  name  │ size │
├────────┼──────┤
│ Banana │ 10   │
│ Date   │ 25   │
│ apple  │ 9    │
│ cherry │ 100  │
└────────┴──────┘
┌────────┬──────┐
│  name  │ size │
├────────┼──────┤
│ Banana │ 10   │
│ cherry │ 100  │
│ Date   │ 25   │
│ apple  │ 9    │
└────────┴──────┘
┌────────┐
│  name  │
├────────┤
│ apple  │
│ Banana │
│ cherry │
│ Date   │
└────────┘
┌────────┬──────┐
│  name  │ size │
├────────┼──────┤
│ apple  │ 9    │
│ Banana │ 10   │
│ Date   │ 25   │
│ cherry │ 100  │
└────────┴──────┘

Recorded with sql.js 1.14.2 (SQLite 3.49.1) on macOS 26 arm64. To run it yourself: sqlite3 -box :memory: < text_sort.sql

  • SQLite compares text with the BINARY collation, character code by character code, and capital letters come before small ones in that code. Banana and Date therefore sort before apple. COLLATE NOCASE sorts the 26 English letters without regard to case. MySQL sorts text without regard to case by default, and PostgreSQL sorts by the column’s collation, which by default comes from the locale chosen when the database was created, so the same query can list these four names in different orders in different engines.
  • A number stored as text sorts like text: '10' comes before '9' because the character 1 comes before 9. CAST(size AS INTEGER) sorts the values as numbers. The better fix is to store numbers in a number column, which the module on data types explains.

Version note

NULLS FIRST and NULLS LAST arrived in SQLite 3.30.0; older SQLite versions report a syntax error, as MySQL 8.4 does. FETCH FIRST … WITH TIES is PostgreSQL syntax from the SQL standard; MySQL 8.4 and SQLite do not accept it. The examples on this page ran with SQLite 3.49.1.

SQL Formatter Lay out a long query with one ORDER BY key per line, in the dialect of your engine.

Key takeaways

  • Without ORDER BY the order of rows is undefined; ask for an order whenever it matters.
  • Each sort key has its own direction, ASC by default; DESC applies only to the key before it.
  • End the sort keys with a unique column, such as the primary key, so that ties cannot change the result.
  • SQLite and MySQL sort NULLs first in ascending order, PostgreSQL last; use NULLS LAST or ORDER BY x IS NULL, x.
  • Page n of s rows is LIMIT s OFFSET (n - 1) * s; in LIMIT a, b the first number is the offset.

Exercise

Exercise · Easy · SQL

Show the second page of a price list

A shop lists its products ten to a page, the most expensive first. Products with the same price are listed in alphabetical order of their names. The table products has the columns id, name and price_paise.

Write a query that returns the second page of that list: the id, name and price_paise of rows 11 to 20, sorted by price from the highest down, and by name from A to Z where prices are equal.

The checker compares the rows in order, so the sorting must be exactly as described. The sample tests use a table of 24 products (with equal prices right at the edges of the page), one of 15 (so the second page is short) and one of 6 (so the second page is empty).

Starter code · page_two.sql

-- Rows 11 to 20 of the price list: most expensive first, equal prices by name.
SELECT id, name, price_paise
FROM products
LIMIT 10;
The sample tests · tests.yaml
# Sample tests: each one builds a products table, runs your query on it and compares the rows it returns in order.
tests:
  - name: returns rows 11 to 20, with equal prices in name order
    ordered: true
    setup: |
      CREATE TABLE products (id INTEGER PRIMARY KEY, name TEXT, price_paise INTEGER);
      INSERT INTO products VALUES
        (1, 'Saffron 2 g', 64000), (2, 'Ghee 1 l', 65000), (3, 'Cashews 500 g', 52000),
        (4, 'Walnuts 500 g', 52000), (5, 'Almonds 500 g', 45000), (6, 'Pistachios 250 g', 42000),
        (7, 'Honey 1 kg', 42000), (8, 'Cardamom 100 g', 38000), (9, 'Basmati rice 5 kg', 36000),
        (10, 'Dates 1 kg', 30000), (11, 'Raisins 500 g', 30000), (12, 'Mustard oil 1 l', 30000),
        (13, 'Tea 500 g', 28000), (14, 'Coffee 500 g', 28000), (15, 'Jaggery 2 kg', 21000),
        (16, 'Toor dal 1 kg', 16500), (17, 'Moong dal 1 kg', 14500), (18, 'Masoor dal 1 kg', 14500),
        (19, 'Poha 1 kg', 9000), (20, 'Sugar 1 kg', 9000), (21, 'Salt 1 kg', 2800),
        (22, 'Rice flour 1 kg', 9000), (23, 'Besan 1 kg', 12000), (24, 'Turmeric 200 g', 7000);
    expected:
      columns: [id, name, price_paise]
      rows:
        - [12, Mustard oil 1 l, 30000]
        - [11, Raisins 500 g, 30000]
        - [14, Coffee 500 g, 28000]
        - [13, Tea 500 g, 28000]
        - [15, Jaggery 2 kg, 21000]
        - [16, Toor dal 1 kg, 16500]
        - [18, Masoor dal 1 kg, 14500]
        - [17, Moong dal 1 kg, 14500]
        - [23, Besan 1 kg, 12000]
        - [19, Poha 1 kg, 9000]
  - name: returns a short second page when there are only 15 products
    ordered: true
    setup: |
      CREATE TABLE products (id INTEGER PRIMARY KEY, name TEXT, price_paise INTEGER);
      INSERT INTO products VALUES
        (1, 'Amla 1 kg', 12000), (2, 'Bael 1 kg', 8000), (3, 'Chikoo 1 kg', 9000),
        (4, 'Dates 500 g', 15000), (5, 'Figs 250 g', 15000), (6, 'Guava 1 kg', 8000),
        (7, 'Jamun 500 g', 11000), (8, 'Kiwi 3 pcs', 11000), (9, 'Lychee 500 g', 20000),
        (10, 'Mango 1 kg', 20000), (11, 'Orange 1 kg', 9000), (12, 'Papaya 1', 6000),
        (13, 'Pear 1 kg', 14000), (14, 'Plum 500 g', 14000), (15, 'Sweet lime 1 kg', 7000);
    expected:
      columns: [id, name, price_paise]
      rows:
        - [11, Orange 1 kg, 9000]
        - [2, Bael 1 kg, 8000]
        - [6, Guava 1 kg, 8000]
        - [15, Sweet lime 1 kg, 7000]
        - [12, Papaya 1, 6000]
  - name: returns no rows when everything fits on the first page
    ordered: true
    setup: |
      CREATE TABLE products (id INTEGER PRIMARY KEY, name TEXT, price_paise INTEGER);
      INSERT INTO products VALUES
        (1, 'Rock salt 1 kg', 6000), (2, 'Sesame oil 1 l', 32000), (3, 'Ragi flour 1 kg', 9500),
        (4, 'Kokum 200 g', 9500), (5, 'Curry leaves', 1500), (6, 'Coconut 1', 4000);
    expected:
      columns: [id, name, price_paise]
      rows: []
A hint

Sort first with two keys, ORDER BY price_paise DESC, name ASC, then take the page: page n of a list with s rows to a page is LIMIT s OFFSET (n - 1) * s, so the second page of ten is LIMIT 10 OFFSET 10.

The sample tests run on this device, in your browser (sql.js): nothing is sent to mysmartcopilot.com. The first run downloads SQLite (about 0.7 MB), which is kept for the next runs. A check in your browser is feedback for you, not proof that the code is right for every input.

Check yourself

6 questions about this lesson. Every answer and why it is right is on the page, behind “Show the answer”. Your score stays in this browser.

  1. Question 1 of 6 The table t holds the rows (b, 1), (a, 2), (b, 3) and (a, 1) in its columns k and n. In what order does this query return them?

    Read the code, then choose one answer.

    SELECT k, n FROM t ORDER BY k, n DESC;
    Show the answer to question 1

    Answer: (a, 2), (a, 1), (b, 3), (b, 1)

    DESC belongs to n only, so k is sorted from a to z, and inside each value of k the numbers run from high to low. A DESC for both keys would need ORDER BY k DESC, n DESC.

  2. Question 2 of 6 In PostgreSQL, where do rows whose price is NULL appear with ORDER BY price (ascending)?

    Choose one answer.

    Show the answer to question 2

    Answer: After all the priced rows

    PostgreSQL sorts a NULL as if it were larger than any value: last in ascending order and first in descending order. SQLite and MySQL do the opposite and put NULLs first in ascending order. NULLS FIRST or NULLS LAST (PostgreSQL and SQLite) or sorting by price IS NULL first (the form MySQL needs) makes the position explicit.

  3. Question 3 of 6 What does this query print?

    What does this program print? Choose one answer.

    CREATE TABLE products (id INTEGER PRIMARY KEY, name TEXT NOT NULL);
    INSERT INTO products VALUES
      (1, 'Amla'), (2, 'Bael'), (3, 'Chikoo'), (4, 'Dates'),
      (5, 'Elaichi'), (6, 'Figs'), (7, 'Guava'), (8, 'Honey');
    
    -- SQLite and MySQL also accept LIMIT with two numbers and a comma.
    SELECT id, name FROM products ORDER BY name LIMIT 2, 3;
    Show the answer to question 3

    Answer: it prints

    ┌────┬─────────┐
    │ id │  name   │
    ├────┼─────────┤
    │ 3  │ Chikoo  │
    │ 4  │ Dates   │
    │ 5  │ Elaichi │
    └────┴─────────┘
    

    In the comma form the first number is the offset and the second the count, so LIMIT 2, 3 skips Amla and Bael and returns the next three rows. It means the same as LIMIT 3 OFFSET 2, the clearer form and the only one PostgreSQL accepts.

  4. Question 4 of 6 A list shows 25 rows a page. What number goes after OFFSET to show page 4?

    Type a number.

    Show the answer to question 4

    Answer: 75

    Page n of s rows a page skips the (n - 1) earlier pages: (4 - 1) × 25 = 75. The query ends with LIMIT 25 OFFSET 75 and returns rows 76 to 100.

  5. Question 5 of 6 Orders have a unique id and a placed_at time that several orders can share. Which ORDER BY clauses make every page of a LIMIT … OFFSET … listing the same each time it is shown, as long as the data does not change?

    Choose every answer that is right.

    Show the answer to question 5

    Answer:

    • ORDER BY id
    • ORDER BY placed_at, id

    Rows that tie on every sort key can come back in any order, so the sort must end with a column that no two rows share. id is unique, so both clauses that include it give a complete order. placed_at alone leaves the orders of the same moment unordered, and a query without ORDER BY has no defined order at all.

  6. Question 6 of 6 In what order does SQLite return these names?

    Read the code, then choose one answer.

    CREATE TABLE fruit (name TEXT);
    INSERT INTO fruit VALUES ('apple'), ('Banana'), ('cherry');
    SELECT name FROM fruit ORDER BY name;
    Show the answer to question 6

    Answer: Banana, apple, cherry

    SQLite's default BINARY collation compares character codes, and every capital letter has a smaller code than every small letter, so Banana comes first. ORDER BY name COLLATE NOCASE gives apple, Banana, cherry.

References

Related tools

Report a problem with this lesson

Quick answers and tool search

Type to search tools or to get a quick answer, for example 18% of 2500. Use the up and down arrow keys to move through the results, Enter to choose, and Escape to close.