Функция Different () (не выбирать классификатор) в postgres - PullRequest
7 голосов
/ 04 августа 2010

Я только что натолкнулся на SQL-запрос, в частности, к базе данных Postgres, который использует функцию с именем «Different». А именно:

select distinct(pattern) as pattern, style, ... etc ...
from styleview
where ... etc ...

Обратите внимание, что это НЕ обычный квалификатор DISTINCT в SELECT - по крайней мере, это не обычный синтаксис для квалификатора DISTINCT, обратите внимание на круглые скобки. Очевидно, он использует DISTINCT в качестве функции, или, может быть, это какой-то особый синтаксис.

Есть идеи, что это значит?

Я попытался немного поиграть с ним, и если я напишу

select distinct(foo)
from bar

Я получаю те же результаты, что и

select distinct foo
from bar

Когда я объединяю его с другими полями в том же списке, мне не совсем понятно, что он делает.

Я ничего не могу найти в документации Postgres.

Спасибо за любую помощь!

Ответы [ 4 ]

10 голосов
/ 28 июля 2015

(Вопрос старый, но в результатах поиска Google он высокий для «sql Different - это не функция» (второе, первое из «Переполнения стека»), но до сих пор не найден удовлетворительный ответ, поэтому .. .)

На самом деле это является обычным классификатором DISTINCT в SELECT, но с вводящим в заблуждение синтаксисом (вы правы в этом вопросе).

DISTINCT никогда не является функцией, всегда ключевым словом. Здесь он используется (неправильно), как если бы это была функция, но

select distinct(pattern) as pattern, style, ... etc ...
from styleview
where ... etc ...

фактически эквивалентен всем следующим формам:

- добавить пробел после distinct:

select distinct (pattern) as pattern, style, ... etc ...
from styleview
where ... etc ...

- убрать скобки вокруг имени столбца:

select distinct pattern as pattern, style, ... etc ...
from styleview
where ... etc ...

- содержание пунктов отступа:

select distinct
    pattern as pattern, style, ... etc ...
from
    styleview
where
    ... etc ...

- удалить избыточный псевдоним, идентичный имени столбца:

select distinct
    pattern, style, ... etc ...
from
    styleview
where
    ... etc ...

Дополнительное чтение:


Примечание: OMG Ponies в ответе на текущий вопрос упомянул расширение DISTINCT ON, представленное PostgreSQL.
Но (как справедливо заметил Джей в комментарии) это не то, что здесь используется, потому что запрос (и результаты) были бы другими, например ::

select distinct on(pattern) pattern, style, ... etc ...
from styleview
where ... etc ...
order by pattern, ... etc ...

эквивалентно:

select  distinct on (pattern)
    pattern, style, ... etc ...
from
    styleview
where
    ... etc ...
order by
    pattern, ... etc ...

Дополнительное чтение:


Примечание: Лукас Эдер в ответе на текущий вопрос упомянул синтаксис использования ключевого слова DISTINCT внутри статистической функции:
синтаксис COUNT(DISTINCT (foo, bar, ...)) от HSQLDB
(или COUNT(DISTINCT foo, bar, ...), который работает и для MySQL, но также для PostgreSQL, SQL Server, Oracle и, возможно, других).
Но (достаточно ясно) это не то, что используется здесь.

3 голосов
/ 04 августа 2010

С документация :

Если указано DISTINCT , все дублирующиеся строки удаляются из результирующего набора (одна строка сохраняется из каждой группы дубликатов). ВСЕ указывает на обратное: все строки сохраняются; это значение по умолчанию.

DISTINCT ON (выражение [, ...]) сохраняет только первую строку каждого набора строк, где заданные выражения оцениваются как равные. Выражения DISTINCT ON интерпретируются с использованием тех же правил, что и для ORDER BY (см. Выше). Обратите внимание, что «первая строка» каждого набора непредсказуема, если только ORDER BY не используется, чтобы гарантировать, что желаемая строка появляется первой. Например,

Часть ON является необязательной, поэтому она действительно сводится к:

  1. Используемые скобки
  2. Размещение в запросе - SQL Server и MySQL выдают ошибку, если вы используете DISTINCT в любой позиции, кроме первой, в предложении SELECT

PostgreSQL - единственная база данных, которая, насколько мне известно, поддерживает этот синтаксис.

0 голосов
/ 14 февраля 2016

Из документации PostgreSQL :

SELECT [ ALL | DISTINCT [ ON ( expression [, ...] ) ] ]
    [ * | expression [ [ AS ] output_name ] [, ...] ]

В первой строке этого цитируемого синтаксиса вы найдете, что часть ON является необязательной, , но , это также та часть ON , которая ссылается на скобки. Другими словами, если ON не присутствует, то круглые скобки не имеют смысла.

Итак, для этого вопроса [ON (выражение [, ...])] не имеет отношения .

Вот несколько очень простых тестовых данных:

CREATE TABLE bar
    (foo varchar(3), fub varchar(1), flut timestamp)
;

INSERT INTO bar
    (foo, fub, flut)
VALUES
    ('one', 'a', '2016-01-01 01:01:03'),
    ('one', 'b', '2016-01-01 01:01:02'),
    ('one', 'c', '2016-01-01 01:01:01'),
    ('two', 'd', '2016-01-01 01:01:03'),
    ('two', 'e', '2016-01-01 01:01:02'),
    ('two', 'f', '2016-01-01 01:01:01')
;

Давайте сначала сконцентрируемся на скобках. Что делают только круглые скобки вокруг выражения после выбора? например, * +1025 *

select (foo) from bar;

| foo |
|-----|
| one |
| one |
| one |
| two |
| two |
| two |

Я надеюсь, что вы увидите, что этот результат идентичен запросу без скобок, окружающих столбец foo , и поэтому мы находим из этого запроса, что скобки НИЧЕГО не делают. Они просто игнорируются. Что произойдет, если мы введем DISTINCT?

select distinct(foo) from bar;

| foo |
|-----|
| two |
| one |

select distinct foo from bar;

| foo |
|-----|
| two |
| one |

Опять же, мы видим, что скобки не имеют никакого эффекта вообще. Если мы вернемся к синтаксису, это согласуется. DISTINCT НЕ является ФУНКЦИЕЙ и размещение выражения в скобках после DISTINCT не меняет способ его работы.

Итак, на вопрос:

только что натолкнулся на SQL-запрос, в частности, к базе данных Postgres, в которой используется функция с именем «Different». А именно:

select distinct(pattern) as pattern, style, ... etc ...
from styleview
where ... etc ...

DISTINCT НЕ является функцией! и круглые скобки в этом примере запроса игнорируются .



Если используется необязательный [ON (выражение)] действительно меняет результаты.

Тест :

select distinct ON (foo) foo, fub, flut from bar order by foo

| foo | fub |                      flut |
|-----|-----|---------------------------|
| one |   a | January, 01 2016 01:01:03 |
| two |   d | January, 01 2016 01:01:03 |

Испытание b :

select distinct ON (fub) foo, fub, flut from bar order by fub

| foo | fub |                      flut |
|-----|-----|---------------------------|
| one |   a | January, 01 2016 01:01:03 |
| one |   b | January, 01 2016 01:01:02 |
| one |   c | January, 01 2016 01:01:01 |
| two |   d | January, 01 2016 01:01:03 |
| two |   e | January, 01 2016 01:01:02 |
| two |   f | January, 01 2016 01:01:01 |

Испытание c :

select distinct ON (flut) foo, fub, flut from bar order by flut

| foo | fub |                      flut |
|-----|-----|---------------------------|
| one |   c | January, 01 2016 01:01:01 |
| one |   b | January, 01 2016 01:01:02 |
| one |   a | January, 01 2016 01:01:03 |

Функция [ON (выражение)] очень полезна, поскольку она может предоставлять «первые», «последние», «самые ранние» или «самые последние» строки в отдельном списке. Но имейте в виду, что эта возможность связана с предложением ORDER BY и фактически, если только предложение order by ALSO не ссылается на выражения, используемые в SELECT DISTINCT ON PostgreSQL, выдает ошибку:

ОШИБКА: выражения SELECT DISTINCT ON должны соответствовать начальному ORDER BY выражения

Приведенные выше примеры можно увидеть на sqlfiddle здесь


Хотя я не хочу слишком усложнять свой ответ, есть морщина, о которой стоит упомянуть:

select distinct (foo,fub) from bar;

СЕЙЧАС скобки что-то делают , но то, что они делают, не имеет прямого отношения к разным. Смотрите " сложные типы "

0 голосов
/ 08 октября 2015

Это либо опечатка, либо кто-то неправильно понял, что они пишут.

Я не знаю всех деталей, но вы можете использовать скобки в качестве операторов приоритета (как в математике).Тем не менее, я думаю, что в конечном итоге вы можете поставить круглые скобки во многие вещи, не меняя их значения.

Например, следующие 2 запроса возвращают одно и то же:

select foo
from bar

select (foo)
from bar

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

select (foo, baz)
from bar

Так что в вашем исходном запросе то, что они на самом деле написали, будет эквивалентно этому:

select distinct *
from
(
    select pattern as pattern, style, ... etc ...
    from styleview
    where ... etc ...
)

что может или не может быть тем, что они намеревались.Если бы мне пришлось угадывать, я бы предположил, что они использовали синтаксис «DISTINCT ON (...)», упомянутый в некоторых других ответах.

...