Spec-Zone.ru › Polars

Предложения запроса

Функция

Описание

SELECT

Извлекает данные из указанных столбцов одной или нескольких таблиц.

DISTINCT

Возвращает уникальные значения из запроса.

DISTINCT ON

Возвращает первую строку для каждой уникальной комбинации указанных столбцов.

FROM

Указывает таблицы, из которых нужно извлечь или удалить данные. Также может использоваться в качестве начального предложения.

JOIN

Объединяет строки двух или более таблиц на основе связанного столбца.

WHERE

Фильтрует строки, возвращаемые запросом, согласно заданным условиям.

GROUP BY

Агрегирует значения строк по одному или нескольким ключевым столбцам.

GROUP BY ALL

Автоматически группирует по всем неагрегатным столбцам проекции.

HAVING

Фильтрует группы в GROUP BY согласно заданным условиям.

WINDOW

Определяет именованные спецификации окон для оконных функций.

QUALIFY

Фильтрует строки запроса по результатам оконных функций.

ORDER BY

Сортирует результат запроса по одному или нескольким указанным столбцам.

ORDER BY ALL

Сортирует результат запроса по всем выбранным столбцам.

OFFSET

Пропускает указанное количество строк.

LIMIT

Указывает количество возвращаемых строк.

FETCH

Ограничивает количество возвращаемых строк (альтернатива LIMIT).

SELECT

Выбирает столбцы, которые должен вернуть запрос.

Пример:

df = pl.DataFrame(
  {
    "a": [1, 2, 3],
    "b": ["zz", "yy", "xx"],
  }
)
df.sql("""
  SELECT a, b FROM self
""")
# shape: (3, 2)
# ┌─────┬─────┐
# │ a   ┆ b   │
# │ --- ┆ --- │
# │ i64 ┆ str │
# ╞═════╪═════╡
# │ 1   ┆ zz  │
# │ 2   ┆ yy  │
# │ 3   ┆ xx  │
# └─────┴─────┘

Примечание

Также поддерживается использование FROM tbl без уточнений — это сокращённая форма SELECT * FROM tbl; подробности см. в предложении FROM.

DISTINCT

Возвращает уникальные значения из запроса.

Пример:

df = pl.DataFrame(
  {
    "a": [1, 2, 2, 1],
    "b": ["xx", "yy", "yy", "xx"],
  }
)
df.sql("""
  SELECT DISTINCT * FROM self
""")
# shape: (2, 2)
# ┌─────┬─────┐
# │ a   ┆ b   │
# │ --- ┆ --- │
# │ i64 ┆ str │
# ╞═════╪═════╡
# │ 1   ┆ xx  │
# │ 2   ┆ yy  │
# └─────┴─────┘

DISTINCT ON

Возвращает первую строку для каждой уникальной комбинации указанных столбцов. При использовании с ORDER BY сохраняется первая строка каждой группы согласно заданному порядку сортировки.

Примечание

DISTINCT ON поддерживает только имена столбцов (не произвольные выражения).

Пример:

df = pl.DataFrame(
  {
    "category": ["A", "A", "A", "B", "B", "B"],
    "value": [30, 10, 20, 50, 40, 60],
    "label": ["x", "y", "z", "p", "q", "r"],
  }
)
df.sql("""
  SELECT DISTINCT ON (category)
    category,
    value,
    label
  FROM self
  ORDER BY category, value DESC
""")
# shape: (2, 3)
# ┌──────────┬───────┬───────┐
# │ category ┆ value ┆ label │
# │ ---      ┆ ---   ┆ ---   │
# │ str      ┆ i64   ┆ str   │
# ╞══════════╪═══════╪═══════╡
# │ A        ┆ 30    ┆ x     │
# │ B        ┆ 60    ┆ r     │
# └──────────┴───────┴───────┘

FROM

Указывает таблицы, из которых нужно извлечь или удалить данные.

Помимо обычного синтаксиса SELECT ... FROM tbl, предложение FROM также можно использовать в качестве начального предложения запроса. Поддерживаются следующие варианты:

  • FROM tbl — эквивалентно SELECT * FROM tbl.
  • FROM tbl SELECT ... — переставленное SELECT с явным указанием проекций.
  • FROM tbl1, tbl2 ... — несколько таблиц, разделённых запятыми; синтаксис неявного соединения см. в предложении JOIN.

Пример:

df = pl.DataFrame(
  {
    "a": [1, 2, 3],
    "b": ["zz", "yy", "xx"],
  }
)
for query in (
  "SELECT * FROM self",
  "FROM self SELECT *",
  "FROM self",
):
  df.sql(query)
  # shape: (3, 2)
  # ┌─────┬─────┐
  # │ a   ┆ b   │
  # │ --- ┆ --- │
  # │ i64 ┆ str │
  # ╞═════╪═════╡
  # │ 1   ┆ zz  │
  # │ 2   ┆ yy  │
  # │ 3   ┆ xx  │
  # └─────┴─────┘

Использование FROM в качестве начального предложения с SELECT:

df.sql("""
  FROM self SELECT b, a
""")
# shape: (3, 2)
# ┌─────┬─────┐
# │ b   ┆ a   │
# │ --- ┆ --- │
# │ str ┆ i64 │
# ╞═════╪═════╡
# │ zz  ┆ 1   │
# │ yy  ┆ 2   │
# │ xx  ┆ 3   │
# └─────┴─────┘

JOIN

Объединяет строки двух или более таблиц на основе связанного столбца.

Типы соединений

  • CROSS JOIN
  • [NATURAL] FULL [OUTER] JOIN
  • [NATURAL] INNER [OUTER] JOIN
  • [NATURAL] LEFT [OUTER] JOIN
  • [NATURAL] RIGHT [OUTER] JOIN
  • [LEFT | RIGHT] ANTI JOIN
  • [LEFT | RIGHT] SEMI JOIN

Пример:

df1 = pl.DataFrame(
  {
    "foo": [1, 2, 3],
    "ham": ["a", "b", "c"],
  }
)
df2 = pl.DataFrame(
  {
    "apple": ["x", "y", "z"],
    "ham": ["a", "b", "d"],
  }
)
pl.sql("""
  SELECT foo, apple, COALESCE(df1.ham, df2.ham) AS ham
  FROM df1 FULL JOIN df2
  USING (ham)
""").collect()
# shape: (4, 3)
# ┌──────┬───────┬─────┐
# │ foo  ┆ apple ┆ ham │
# │ ---  ┆ ---   ┆ --- │
# │ i64  ┆ str   ┆ str │
# ╞══════╪═══════╪═════╡
# │ 1    ┆ x     ┆ a   │
# │ 2    ┆ y     ┆ b   │
# │ null ┆ z     ┆ d   │
# │ 3    ┆ null  ┆ c   │
# └──────┴───────┴─────┘

pl.sql("""
  SELECT * FROM df1 NATURAL INNER JOIN df2
""").collect()
# shape: (2, 3)
# ┌─────┬───────┬─────┐
# │ foo ┆ apple ┆ ham │
# │ --- ┆ ---   ┆ --- │
# │ i64 ┆ str   ┆ str │
# ╞═════╪═══════╪═════╡
# │ 1   ┆ x     ┆ a   │
# │ 2   ┆ y     ┆ b   │
# └─────┴───────┴─────┘

Неявные соединения (через запятую)

Таблицы также можно объединять с помощью устаревшего синтаксиса FROM с разделением через запятую, указывая условия соединения в предложении WHERE. Предикаты равенства между таблицами переносятся в ключи соединения (в результате получается соединение INNER), а все оставшиеся предикаты применяются как фильтры. Если предикат не связывает две таблицы, они объединяются как CROSS JOIN.

pl.sql("""
  SELECT foo, apple, df1.ham
  FROM df1, df2
  WHERE df1.ham = df2.ham
""").collect()
# shape: (2, 3)
# ┌─────┬───────┬─────┐
# │ foo ┆ apple ┆ ham │
# │ --- ┆ ---   ┆ --- │
# │ i64 ┆ str   ┆ str │
# ╞═════╪═══════╪═════╡
# │ 1   ┆ x     ┆ a   │
# │ 2   ┆ y     ┆ b   │
# └─────┴───────┴─────┘

Примечание

При неявном соединении столбцы сравнения с обеих сторон следует указывать с именем или псевдонимом таблицы (например: WHERE df1.ham = df2.ham). Сравнения без указания таблицы обрабатываются как обычные фильтры, а не как ключи соединения.

Условия соединения не по равенству

Условия соединения не ограничиваются равенством: также поддерживаются операторы <, <=, >, >= и != (как в явных предложениях ON, так и в неявных соединениях). Их можно свободно комбинировать с условиями на равенство с помощью AND.

df3 = pl.DataFrame({"value": [5, 25, 45]})
df4 = pl.DataFrame({"lo": [0, 20], "hi": [20, 50]})
pl.sql("""
  SELECT value, lo, hi
  FROM df3 INNER JOIN df4
  ON df3.value >= df4.lo AND df3.value < df4.hi
""").collect()
# shape: (3, 3)
# ┌───────┬─────┬─────┐
# │ value ┆ lo  ┆ hi  │
# │ ---   ┆ --- ┆ --- │
# │ i64   ┆ i64 ┆ i64 │
# ╞═══════╪═════╪═════╡
# │ 5     ┆ 0   ┆ 20  │
# │ 25    ┆ 20  ┆ 50  │
# │ 45    ┆ 20  ┆ 50  │
# └───────┴─────┴─────┘

WHERE

Фильтрует строки, возвращаемые запросом, согласно заданным условиям.

df = pl.DataFrame(
  {
    "foo": [30, 40, 50],
    "ham": ["a", "b", "c"],
  }
)
df.sql("""
  SELECT * FROM self WHERE foo > 42
""")
# shape: (1, 2)
# ┌─────┬─────┐
# │ foo ┆ ham │
# │ --- ┆ --- │
# │ i64 ┆ str │
# ╞═════╪═════╡
# │ 50  ┆ c   │
# └─────┴─────┘

GROUP BY

Группирует строки с одинаковыми значениями в указанных столбцах, формируя сводные строки.

Пример:

df = pl.DataFrame(
    {
      "foo": ["a", "b", "b"],
      "bar": [10, 20, 30],
    }
  )
df.sql("""
  SELECT foo, SUM(bar) FROM self GROUP BY foo
""")
# shape: (2, 2)
# ┌─────┬─────┐
# │ foo ┆ bar │
# │ --- ┆ --- │
# │ str ┆ i64 │
# ╞═════╪═════╡
# │ b   ┆ 50  │
# │ a   ┆ 10  │
# └─────┴─────┘

GROUP BY ALL

Автоматически группирует по всем столбцам проекции SELECT, которые не заключены в агрегатную функцию или оконное выражение и не являются литеральными значениями. Это удобная сокращённая форма, избавляющая от необходимости вручную повторять имена столбцов в предложении GROUP BY.

Пример:

df = pl.DataFrame(
  {
    "category": ["A", "A", "B", "B"],
    "sub": ["x", "y", "x", "y"],
    "value": [10, 20, 30, 40],
  }
)
df.sql("""
  SELECT category, sub, SUM(value) AS total
  FROM self
  GROUP BY ALL
  ORDER BY category, sub
""")
# shape: (4, 3)
# ┌──────────┬─────┬───────┐
# │ category ┆ sub ┆ total │
# │ ---      ┆ --- ┆ ---   │
# │ str      ┆ str ┆ i64   │
# ╞══════════╪═════╪═══════╡
# │ A        ┆ x   ┆ 10    │
# │ A        ┆ y   ┆ 20    │
# │ B        ┆ x   ┆ 30    │
# │ B        ┆ y   ┆ 40    │
# └──────────┴─────┴───────┘

HAVING

Фильтрует группы в GROUP BY согласно заданным условиям.

df = pl.DataFrame(
      {
      "foo": ["a", "b", "b", "c"],
      "bar": [10, 20, 30, 40],
    }
  )
df.sql("""
  SELECT foo, SUM(bar) FROM self GROUP BY foo HAVING bar >= 40
""")
# shape: (2, 2)
# ┌─────┬─────┐
# │ foo ┆ bar │
# │ --- ┆ --- │
# │ str ┆ i64 │
# ╞═════╪═════╡
# │ c   ┆ 40  │
# │ b   ┆ 50  │
# └─────┴─────┘

WINDOW

Определяет именованные спецификации окон, на которые могут ссылаться оконные функции.

Пример:

Одно окно, несколько выражений:

df = pl.DataFrame({
    "id": [1, 2, 3, 4, 5, 6, 7],
    "category": ["A", "A", "A", "B", "B", "B", "C"],
    "value": [20, 10, 30, 15, 50, 30, 35],
})
df.sql("""
  SELECT
    category,
    value,
    SUM(value) OVER w AS "w:sum",
    MIN(value) OVER w AS "w:min",
    AVG(value) OVER w AS "w:avg",
  FROM self
  WINDOW w AS (PARTITION BY category ORDER BY value)
  ORDER BY category, value
""")
# shape: (7, 5)
# ┌──────────┬───────┬───────┬───────┬───────────┐
# │ category ┆ value ┆ w:sum ┆ w:min ┆ w:avg     │
# │ ---      ┆ ---   ┆ ---   ┆ ---   ┆ ---       │
# │ str      ┆ i64   ┆ i64   ┆ i64   ┆ f64       │
# ╞══════════╪═══════╪═══════╪═══════╪═══════════╡
# │ A        ┆ 10    ┆ 10    ┆ 10    ┆ 20.0      │
# │ A        ┆ 20    ┆ 30    ┆ 10    ┆ 20.0      │
# │ A        ┆ 30    ┆ 60    ┆ 10    ┆ 20.0      │
# │ B        ┆ 15    ┆ 15    ┆ 15    ┆ 31.666667 │
# │ B        ┆ 30    ┆ 45    ┆ 15    ┆ 31.666667 │
# │ B        ┆ 50    ┆ 95    ┆ 15    ┆ 31.666667 │
# │ C        ┆ 35    ┆ 35    ┆ 35    ┆ 35.0      │
# └──────────┴───────┴───────┴───────┴───────────┘

Несколько окон, несколько выражений:

df.sql("""
  SELECT
    category,
    value,
    AVG(value) OVER w1 AS category_avg,
    SUM(value) OVER w2 AS running_value,
    COUNT(*) OVER w3 AS total_count
  FROM self
  WINDOW
    w1 AS (PARTITION BY category),
    w2 AS (ORDER BY value),
    w3 AS ()
  ORDER BY category, value
""")
# shape: (7, 5)
# ┌──────────┬───────┬──────────────┬───────────────┬─────────────┐
# │ category ┆ value ┆ category_avg ┆ running_value ┆ total_count │
# │ ---      ┆ ---   ┆ ---          ┆ ---           ┆ ---         │
# │ str      ┆ i64   ┆ f64          ┆ i64           ┆ u32         │
# ╞══════════╪═══════╪══════════════╪═══════════════╪═════════════╡
# │ A        ┆ 10    ┆ 20.0         ┆ 10            ┆ 7           │
# │ A        ┆ 20    ┆ 20.0         ┆ 45            ┆ 7           │
# │ A        ┆ 30    ┆ 20.0         ┆ 75            ┆ 7           │
# │ B        ┆ 15    ┆ 31.666667    ┆ 25            ┆ 7           │
# │ B        ┆ 30    ┆ 31.666667    ┆ 105           ┆ 7           │
# │ B        ┆ 50    ┆ 31.666667    ┆ 190           ┆ 7           │
# │ C        ┆ 35    ┆ 35.0         ┆ 140           ┆ 7           │
# └──────────┴───────┴──────────────┴───────────────┴─────────────┘

QUALIFY

Фильтрует строки запроса по результатам оконных функций.

Пример:

Ограничение результата двумя наибольшими значениями в каждой категории:

df = pl.DataFrame({
    "id": [100, 200, 300, 400, 500, 600, 700, 800],
    "category": ["A", "A", "A", "B", "B", "B", "B", "A"],
    "value": [20, 15, 30, 25, 15, 50, 35, 45],
})
df.sql("""
  SELECT
    id,
    category,
    value
  FROM self
  WINDOW w AS (PARTITION BY category ORDER BY value DESC)
  QUALIFY ROW_NUMBER() OVER w <= 2
  ORDER BY category, value DESC
""")
# shape: (4, 3)
# ┌─────┬──────────┬───────┐
# │ id  ┆ category ┆ value │
# │ --- ┆ ---      ┆ ---   │
# │ i64 ┆ str      ┆ i64   │
# ╞═════╪══════════╪═══════╡
# │ 800 ┆ A        ┆ 45    │
# │ 300 ┆ A        ┆ 30    │
# │ 600 ┆ B        ┆ 50    │
# │ 700 ┆ B        ┆ 35    │
# └─────┴──────────┴───────┘

ORDER BY

Сортирует результат запроса по одному или нескольким указанным столбцам.

Пример:

df = pl.DataFrame(
  {
    "foo": ["b", "a", "c", "b"],
    "bar": [20, 10, 40, 30],
  }
)
df.sql("""
  SELECT foo, bar FROM self ORDER BY bar DESC
""")
# shape: (4, 2)
# ┌─────┬─────┐
# │ foo ┆ bar │
# │ --- ┆ --- │
# │ str ┆ i64 │
# ╞═════╪═════╡
# │ c   ┆ 40  │
# │ b   ┆ 30  │
# │ b   ┆ 20  │
# │ a   ┆ 10  │
# └─────┴─────┘

ORDER BY ALL

Сортирует результат запроса по всем выбранным столбцам. Это удобная сокращённая форма, избавляющая от необходимости повторять имена столбцов. Модификаторы ASC/DESC и NULLS FIRST/NULLS LAST применяются к каждому столбцу.

Пример:

df = pl.DataFrame(
  {
    "a": ["x", "y", "x", "y"],
    "b": [30, 10, 20, 40],
  }
)
df.sql("""
  SELECT a, b FROM self ORDER BY ALL
""")
# shape: (4, 2)
# ┌─────┬─────┐
# │ a   ┆ b   │
# │ --- ┆ --- │
# │ str ┆ i64 │
# ╞═════╪═════╡
# │ x   ┆ 20  │
# │ x   ┆ 30  │
# │ y   ┆ 10  │
# │ y   ┆ 40  │
# └─────┴─────┘

df.sql("""
  SELECT a, b FROM self ORDER BY ALL DESC
""")
# shape: (4, 2)
# ┌─────┬─────┐
# │ a   ┆ b   │
# │ --- ┆ --- │
# │ str ┆ i64 │
# ╞═════╪═════╡
# │ y   ┆ 40  │
# │ y   ┆ 10  │
# │ x   ┆ 30  │
# │ x   ┆ 20  │
# └─────┴─────┘

OFFSET

Пропускает указанное количество строк, прежде чем начать возвращать строки запроса.

Пример:

df = pl.DataFrame(
  {
    "foo": ["b", "a", "c", "b"],
    "bar": [20, 10, 40, 30],
  }
)
df.sql("""
  SELECT foo, bar FROM self LIMIT 2 OFFSET 2
""")
# shape: (2, 2)
# ┌─────┬─────┐
# │ foo ┆ bar │
# │ --- ┆ --- │
# │ str ┆ i64 │
# ╞═════╪═════╡
# │ c   ┆ 40  │
# │ b   ┆ 30  │
# └─────┴─────┘

LIMIT

Ограничивает количество строк, возвращаемых запросом.

Пример:

df = pl.DataFrame(
  {
    "foo": ["b", "a", "c", "b"],
    "bar": [20, 10, 40, 30],
  }
)
df.sql("""
  SELECT foo, bar FROM self LIMIT 2
""")
# shape: (2, 2)
# ┌─────┬─────┐
# │ foo ┆ bar │
# │ --- ┆ --- │
# │ str ┆ i64 │
# ╞═════╪═════╡
# │ b   ┆ 20  │
# │ a   ┆ 10  │
# └─────┴─────┘

FETCH

Ограничивает количество строк, возвращаемых запросом; это соответствующая стандарту ANSI SQL альтернатива предложению LIMIT, которую можно сочетать с OFFSET. Модификаторы WITH TIES и PERCENT в настоящее время не поддерживаются.

Пример:

df = pl.DataFrame(
  {
    "foo": ["b", "a", "c", "b"],
    "bar": [20, 10, 40, 30],
  }
)
df.sql("""
  SELECT foo, bar
  FROM self
  ORDER BY bar
  OFFSET 1 FETCH NEXT 2 ROWS ONLY
""")
# shape: (2, 2)
# ┌─────┬─────┐
# │ foo ┆ bar │
# │ --- ┆ --- │
# │ str ┆ i64 │
# ╞═════╪═════╡
# │ b   ┆ 20  │
# │ b   ┆ 30  │
# └─────┴─────┘

© 2020 Ritchie Vink
© 2022 Polars contributors
Licensed under the MIT License.
https://docs.pola.rs/api/python/stable/reference/sql/clauses.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API