SELECT DISTINCT field1, field2, field3, ...... FROM table
次のSQL文を実行しようとしていますが、すべての列を返すようにしたいのですが、これは可能ですか。何かのようなもの:
SELECT DISTINCT field1, * from table
あなたはグループを探しています:
select *
from table
group by field1
これはときどき別個のonステートメントで書くことができます。
select distinct on field1 *
from table
ただし、ほとんどのプラットフォームでは、他の列の動作が指定されていないため、上記のどちらも機能しません。 (最初のものはMySQLで動作します。それがあなたが使用しているものであれば)
別々のフィールドを取得して、毎回任意の行を1つ選択することに固執することができます。
一部のプラットフォーム(PostgreSQL、Oracle、T-SQLなど)では、これはウィンドウ関数を使用して直接実行できます。
select *
from (
select *,
row_number() over (partition by field1 order by field2) as row_number
from table
) as rows
where row_number = 1
他の人(MySQL、SQLite)では、テーブル全体をそれ自身で結合するようにするサブクエリを書く必要があるでしょう( example )、従ってお勧めできません。
あなたの質問の言い回しから、私はあなたが与えられたフィールドとそのようなそれぞれの値に対して別々の値を選択して同じ行の他の全ての列の値をリストしたいということを理解しています。結果が決定されていないため、ほとんどのDBMSはDISTINCT
とGROUP BY
のどちらでもこれを許可しません。
このように考えてください:あなたのfield1
が2回以上現れると、field2
のどの値がリストされるか(あなたが2つの行でfield1
の同じ値を持つが、それらの2つの行でfield2
の2つの異なる値を持つ)。
ただし、集約関数を使用し(表示したいすべてのフィールドに対して明示的に)、DISTINCT
の代わりにGROUP BY
を使用することもできます。
SELECT field1, MAX(field2), COUNT(field3), SUM(field4), .... FROM table GROUP BY field1
私があなたの問題を正しく理解したならば、それは私が今持っていたものに似ています。すべてのデータに適用するのではなく、DISTINCTの使いやすさを特定のフィールドに限定できるようにする必要があります。
集約関数なしでGROUP BYを使用すると、どのGROUP BYフィールドがDISTINCTフィールドになります。
あなたがあなたの質問をするならば:
SELECT * from table GROUP BY field1;
これは、field1の単一のインスタンスに基づいてすべての結果を表示します。
たとえば、名前、住所、市区町村を含むテーブルがあるとします。 1人の人物に複数の住所が記録されていますが、その人物に1つの住所が必要な場合は、次のようにクエリできます。
SELECT * FROM persons GROUP BY name;
その結果、その名前の1つのインスタンスだけがそのアドレスと共に表示され、もう1つのインスタンスは結果の表から省略されます。注意:あなたのファイルがfirstNameやlastNameのようなアトミックな値を持っているなら、両方でグループ化したいでしょう。
SELECT * FROM persons GROUP BY lastName, firstName;
2人の人が同じ姓を持ち、lastNameによってのみグループ化されている場合、そのうちの1人は結果から除外されます。あなたはそれらのことを考慮に入れる必要があります。お役に立てれば。
SELECT c2.field1 ,
field2
FROM (SELECT DISTINCT
field1
FROM dbo.TABLE AS C
) AS c1
JOIN dbo.TABLE AS c2 ON c1.field1 = c2.field1
それは本当に良い質問です。私はすでにここでいくつかの役に立つ答えを読んだことがありますが、おそらくもっと正確な説明を加えることができます。
追加情報を照会しない限り、GROUP BYステートメントを使用して照会結果の数を減らすことは簡単です。次の表の「位置」が得られたとしましょう。
--country-- --city--
France Lyon
Poland Krakow
France Paris
France Marseille
Italy Milano
今クエリ
SELECT country FROM locations
GROUP BY country
結果は次のようになります。
--country--
France
Poland
Italy
ただし、次のクエリ
SELECT country, city FROM locations
GROUP BY country
... MS SQLでエラーが発生します。3つのフランスの都市 "Lyon"、 "Paris"、または "Marseille"のうちどれが "France"の右側にあるフィールドを読みたいのですか。
2番目のクエリを修正するには、この情報を追加する必要があります。これを行う1つの方法は、すべての候補の中で最大値または最小値を選択して、関数MAX()またはMIN()を使用することです。 MAX()とMIN()は数値に適用できるだけでなく、文字列値のアルファベット順も比較します。
SELECT country, MAX(city) FROM locations
GROUP BY country
結果は次のようになります。
--country-- --city--
France Paris
Poland Krakow
Italy Milano
または
SELECT country, MIN(city) FROM locations
GROUP BY country
結果は次のようになります。
--country-- --city--
France Lyon
Poland Krakow
Italy Milano
これらの関数は、アルファベット順(または数字順)のどちらかの端から自分の値を選択するのに問題がなければ、良い解決策です。しかし、そうでない場合はどうなりますか?あなたが特定の特性を持つ値が必要だと仮定しましょう。文字 'M'で始まります。今、物事は複雑になります。
私がこれまで見つけたことができる唯一の解決策はあなたの全体のクエリをサブクエリに入れて、そして手でそれの外側に追加のカラムを構築することです:
SELECT
countrylist.*,
(SELECT TOP 1 city
FROM locations
WHERE
country = countrylist.country
AND city like 'M%'
)
FROM
(SELECT country FROM locations
GROUP BY country) countrylist
結果は次のようになります。
--country-- --city--
France Marseille
Poland NULL
Italy Milano
素晴らしい質問@aryaxt - 5年前に質問したので、あなたはそれが素晴らしい質問だったと言うことができます。
私はちょうどこれを含むように受け入れられた答えを編集しようとしました、しかし私の編集がそれを行わないならば:
テーブルがそれほど大きくなく、主キーが自動インクリメント整数であると仮定した場合は、次のようにすることができます。
SELECT
table.*
FROM table
--be able to take out dupes later
LEFT JOIN (
SELECT field, MAX(id) as id
FROM table
GROUP BY field
) as noDupes on noDupes.id = table.id
WHERE
//this will result in only the last instance being seen
noDupes.id is not NULL
あなたはそれをWITH
節で行うことができます。
例えば:
WITH c AS (SELECT DISTINCT a, b, c FROM tableName)
SELECT * FROM tableName r, c WHERE c.rowid=r.rowid AND c.a=r.a AND c.b=r.b AND c.c=r.c
これにより、WITH
句のクエリで選択された行のみを選択することもできます。
SQL Serverでは、dense_rankおよび追加のウィンドウ関数を使用して、指定した列に重複した値を持つすべての行と列を取得できます。これは一例です...
with t as (
select col1 = 'a', col2 = 'b', col3 = 'c', other = 'r1' union all
select col1 = 'c', col2 = 'b', col3 = 'a', other = 'r2' union all
select col1 = 'a', col2 = 'b', col3 = 'c', other = 'r3' union all
select col1 = 'a', col2 = 'b', col3 = 'c', other = 'r4' union all
select col1 = 'c', col2 = 'b', col3 = 'a', other = 'r5' union all
select col1 = 'a', col2 = 'a', col3 = 'a', other = 'r6'
), tdr as (
select
*,
total_dr_rows = count(*) over(partition by dr)
from (
select
*,
dr = dense_rank() over(order by col1, col2, col3),
dr_rn = row_number() over(partition by col1, col2, col3 order by other)
from
t
) x
)
select * from tdr where total_dr_rows > 1
これは、col1、col2、およびcol3の個別の組み合わせごとに行数を取ります。
試します
SELECT table.* FROM table
WHERE otherField = 'otherValue'
GROUP BY table.fieldWantedToBeDistinct
limit x
SELECT *
FROM tblname
GROUP BY duplicate_values
ORDER BY ex.VISITED_ON DESC
LIMIT 0 , 30
ORDER BY
では、ここに例を挙げましたが、これにIDフィールドを追加することもできます。