Предложения запроса
Функция | Описание |
|---|---|
Извлекает данные из указанных столбцов одной или нескольких таблиц. | |
Возвращает уникальные значения из запроса. | |
Возвращает первую строку для каждой уникальной комбинации указанных столбцов. | |
Указывает таблицы, из которых нужно извлечь или удалить данные. Также может использоваться в качестве начального предложения. | |
Объединяет строки двух или более таблиц на основе связанного столбца. | |
Фильтрует строки, возвращаемые запросом, согласно заданным условиям. | |
Агрегирует значения строк по одному или нескольким ключевым столбцам. | |
Автоматически группирует по всем неагрегатным столбцам проекции. | |
Фильтрует группы в | |
Определяет именованные спецификации окон для оконных функций. | |
Фильтрует строки запроса по результатам оконных функций. | |
Сортирует результат запроса по одному или нескольким указанным столбцам. | |
Сортирует результат запроса по всем выбранным столбцам. | |
Пропускает указанное количество строк. | |
Указывает количество возвращаемых строк. | |
Ограничивает количество возвращаемых строк (альтернатива 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