Использование отличного в столбце и выполнение порядка в другом столбце приводит к ошибке - PullRequest
8 голосов
/ 18 января 2012

У меня есть таблица: abc_test со столбцами n_num, k_str.

Этот запрос не работает:

    select distinct(n_num) from abc_test order by(k_str)

Но этот работает:

    select n_num from abc_test order by(k_str)

Каквнутренние ключевые слова DISTINCT и ORDER BY работают так, что вывод обоих запросов изменился?

Ответы [ 11 ]

11 голосов
/ 18 января 2012

Насколько я понял из вашего вопроса.

Отличный: - означает выбрать отдельный (все выбранные значения должны быть уникальными).упорядочить по: - просто означает упорядочить выбранные строки согласно вашему требованию.

Проблема в вашем первом запросе Например: у меня есть таблица

ID name
01 a
02 b
03 c
04 d 
04 a

, теперь запрос select distinct(ID) from table order by (name) не понимает, какую запись следует принять для идентификатора - 04 (поскольку в столбце Имя есть два значения, d и a).Таким образом, проблема для движка БД здесь, когда вы говорите заказ по (имя) .........

4 голосов
/ 18 января 2012

Вы можете подумать об использовании группы вместо:

select n_num
from abc_test
group by n_num
order by min(k_str)
3 голосов
/ 18 января 2012

Первый запрос невозможен.Давайте объясним это на примере.у нас есть этот тест:

n_num k_str
2     a
2     c
1     b

select distinct (n_num) from abc_test это

2
1

Select n_num from abc_test order by k_str это

2
1
2

Что вы хотите вернуть

select distinct (n_num) from abc_test order by k_str?

он должен вернуть только 1 и 2, но как их заказать?

0 голосов
/ 25 мая 2019

Мой запрос не совсем соответствует вашему, но он довольно близок.

select distinct a.character_01 , (select top 1 b.sort_order from LookupData b where a.character_01 = b.character_01 )
from LookupData a 
where 
Dataset_Name = 'Sample' and status = 200
order by 2, 1
0 голосов
/ 20 июля 2018

Как работают расширенные столбцы ключей сортировки

Логический порядок операций в SQL для вашего первого запроса (упрощенный):

  • FROM abc_test
  • SELECT n_num, k_str т.е. добавить так называемый расширенный столбец ключа сортировки
  • ORDER BY k_str DESC
  • SELECT n_num т.е. удалить расширенную сортировку ключевой столбец снова из результата.

Благодаря стандартной функции SQL расширенный столбец ключа сортировки можно упорядочить что-то, чего нет в SELECT пункт, потому что он временно добавляется к нему за кулисами до заказа, а затем снова удаляется после заказа.

Итак, почему это не работает с DISTINCT?

Если мы добавим операцию DISTINCT, ее нужно будет добавить между SELECT и ORDER BY:

  • FROM abc_test
  • SELECT n_num, k_str т.е. добавить так называемый расширенный столбец ключа сортировки
  • DISTINCT
  • ORDER BY k_str DESC
  • SELECT n_num т.е. удалить столбец расширенного ключа сортировки снова из результата.

Но теперь, с расширенным столбцом ключа сортировки k_str, семантика операции DISTINCT была изменена, поэтому результат больше не будетбыть таким же.Это не то, что нам нужно, поэтому и стандарт SQL, и все разумные базы данных запрещают это использование.

Временные решения

PostgreSQL имеет синтаксис DISTINCT ON, который можно использовать здесь именно для этогоjob:

SELECT DISTINCT ON (k_str) n_num
FROM abc_test
ORDER BY k_str DESC

Его можно эмулировать со стандартным синтаксисом следующим образом, если вы не используете PostgreSQL

SELECT n_num
FROM (
  SELECT n_num, MIN(k_str) AS k_str
  FROM abc_test
  GROUP BY n_num
) t
ORDER BY k_str

Или просто (в данном случае)

SELECT n_num, MIN(k_str) AS k_str
FROM abc_test
GROUP BY n_num
ORDER BY k_str

Я уже писал о SQL DISTINCT и ORDER BY более подробно здесь .

0 голосов
/ 13 июля 2017

Когда я получил ту же ошибку, я решил ее, изменив на

SELECT n_num 
FROM(
   SELECT DISTINCT(n_num) AS n_num, k_str
   FROM abc_test
) as tbl
ORDER BY tbl.k_str
0 голосов
/ 01 ноября 2016

вы можете сделать

select distinct top 10000 (n_num)  --assuming you won't have more than 10,000 rows                
from abc_test order by(k_str)
0 голосов
/ 16 сентября 2014

Этот подход доступен в SQL Server 2000, вы можете выбрать различные значения из таблицы и порядка по другому столбцу, который не включен в Distinct.Но в SQL 2012 это приведет к ошибке «Элементы ORDER BY должны появиться в списке выбора, если указано SELECT DISTINCT».

Итак, если вы хотите использовать ту же функцию, что и в SQL 2000,используйте номер столбца для заказа (это не рекомендуется в лучшей практике).

select distinct(n_num) from abc_test order by 1

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

select distinct(n_num), k_str from abc_test order by 2
0 голосов
/ 18 января 2012

В соответствии со стандартами SQL, предложение SELECT может называться либо предложениями ("псевдонимами") в предложении верхнего уровня SELECT, либо столбцами результирующего набора по порядковому положению, и поэтому ни один из ваших запросов не будет соответствовать.

Похоже, что Oracle, как и другие реализации SQL, позволяет ссылаться на столбцы, которые существовали (логически) непосредственно перед проекцией в предложении SELECT.Я не уверен, является ли такая гибкость хорошей вещью: IMO - это хорошая практика выставлять порядок сортировки вызывающему приложению путем включения столбца / выражений и т. Д. В предложение SELECT.

Как всегда, вам нужно применить dsicpline, чтобы получить значимые результаты.Для вашего первого запроса определение порядка потенциально совершенно произвольно. Вы должны быть благодарны за ошибку;)

0 голосов
/ 18 января 2012

ты пробовал это?

SELECT DISTINCT n_num as iResult
FROM abc_test 
ORDER BY iResult
...