web-dev-qa-db-ja.com

列でdistinctを使用し、別の列でorder byを実行すると、エラーが発生します

私はテーブルを持っています:列n_num、k_strを持つabc_test。

このクエリは機能しません:

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

しかし、これは機能します:

    select n_num from abc_test order by(k_str)

DISTINCTキーワードとORDERBYキーワードは、両方のクエリの出力が変更されると内部でどのように機能しますか?

13
prateek gupta

私があなたの質問から理解した限りでは。

個別:-個別を選択することを意味します(選択されたすべての値は一意である必要があります)。 order By:-単に、要件に従って選択した行を並べ替えることを意味します。

最初のクエリの問題は次のとおりです。例:テーブルがあります

_ID name
01 a
02 b
03 c
04 d 
04 a
_

現在、クエリselect distinct(ID) from table order by (name)は、ID-04に対してどのレコードを取得する必要があるか混乱しています(名前列に2つの値dとaがあるため)。したがって、DBエンジンの問題は、(名前)で注文すると言うときにここにあります.........

13

代わりにgroupbyを使用することを検討してください。

select n_num
from abc_test
group by n_num
order by min(k_str)
5

最初のクエリは不可能です。これを例で説明しましょう。このテストがあります:

_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のみを返す必要がありますが、それらを注文するにはどうすればよいですか?

3
Florin Ghita

拡張ソートキー列はどのように

SQLでの操作の論理順序 最初のクエリは(簡略化):

  • FROM abc_test
  • SELECT n_num, k_strつまり、いわゆる拡張ソートキー列を追加します
  • ORDER BY k_str DESC
  • SELECT n_numつまり、拡張ソートキー列を結果から再度削除します。

SQL標準拡張ソートキー列機能のおかげで、SELECT句にないもので並べ替えることができます。注文前に舞台裏で一時的に追加され、注文後に再び削除されます。

では、なぜこれがDISTINCTで機能しないのですか?

DISTINCT操作を追加する場合は、SELECTORDER 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構文があり、ここで正確にこのジョブに使用できます。

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

SQLDISTINCTとORDERBYについては、こちらで詳しくブログに書いています

2
Lukas Eder

このアプローチはSQLServer 2000で使用でき、テーブルから個別の値を選択し、Distinctに含まれていない別の列で並べ替えることができます。ただし、SQL 2012では、「SELECT DISTINCTが指定されている場合、ORDERBYアイテムが選択リストに表示される必要があります」というエラーが発生します。

したがって、SQL 2000と同じ機能を使用する場合でも、順序付けに列番号を使用できます(ベストプラクティスでは推奨されません)。

select distinct(n_num) from abc_test order by 1

これにより、結果をフェッチした後、最初の列が並べ替えられます。個別以外の異なる列に基づいて順序付けを行う必要がある場合は、selectステートメントにもその列を追加し、列番号を使用して順序付けする必要があります。

select distinct(n_num), k_str from abc_test order by 2
0
Shiva N

SQL標準によると、SELECT句は、最上位のSELECT句の句(「エイリアス」)または序数位置による結果セットの列のいずれか、つまりクエリのネザーを指す場合があります。準拠します。

Oracleは、他のSQL実装と同様に、SELECT句で投影される直前に(論理的に)存在していた列を参照できるように思われます。このような柔軟性がこれほど良いものかどうかはわかりません。IMOSELECT句に列/式などを含めて、呼び出し元のアプリケーションに並べ替え順序を公開することをお勧めします。

いつものように、意味のある結果を得るにはdsicplineを適用する必要があります。最初のクエリでは、順序の定義は完全に恣意的である可能性があります。エラーに感謝する必要があります;)

0
onedaywhen

私のクエリはあなたのクエリと完全には一致しませんが、かなり近いです。

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
P.B.

クエリの結果セットからコレクションdistinct(n_num)を選択しています。したがって、列k_strとの実際の関係はもうありません。 n_numは、それぞれk_strの値が異なる2つの行から取得できます。したがって、コレクションdistinct(n_num)をk_strで並べ替えることはできません。

0