web-dev-qa-db-ja.com

列の一意の値ごとに最初の行のみを選択する方法

顧客の住所のテーブルがあるとしましょう:

CName           |   AddressLine
-------------------------------
John Smith      | 123 Nowheresville
Jane Doe        | 456 Evergreen Terrace
John Smith      | 999 Somewhereelse
Joe Bloggs      | 1 Second Ave

この表では、John Smithのような1人の顧客が複数の住所を持つことができます。 'CName'に重複がある最初の行のみを返すには、このテーブルの選択クエリが必要です。このテーブルでは、3番目を除くすべての行を返す必要があります(または1番目-これら2つのアドレスのいずれでも構いませんが、1つだけを返すことができます)。サーバーが以前に列の値をすでに見たかどうかに基づいてフィルタリングするために、SELECTクエリに追加できるキーワードはありますか?

79
nuit9

どのアドレスが使用されても構わないと言う場合、非常に簡単な答えです。

SELECT
    CName, MIN(AddressLine)
FROM
    MyTable
GROUP BY
    CName

たとえば、「挿入」列に従って最初の列が必要な場合、それは別のクエリです

SELECT
    M.CName, M.AddressLine,
FROM
    (
    SELECT
        CName, MIN(Inserted) AS First
    FROM
        MyTable
    GROUP BY
        CName
    ) foo
    JOIN
    MyTable M ON foo.CName = M.CName AND foo.First = M.Inserted
113
gbn

SQL 2k5 +では、次のようなことができます。

;with cte as (
  select CName, AddressLine,
  rank() over (partition by CName order by AddressLine) as [r]
  from MyTable
)
select CName, AddressLine
from cte
where [r] = 1
20
Ben Thul

row_number()を使用して、行の行番号を取得できます。 overコマンドを使用します-partition by句は番号付けをいつ再開するかを指定し、order byは行番号の順序を選択します。クエリの最後にorder byを追加した場合でも、番号付け時にoverコマンドの順序を保持します。

select *
from mytable
where row_number() over(partition by Name order by AddressLine) = 1
10
Rizzi Frank

次のようなrow_numer() over(partition by ...)構文を使用できます。

select * from
(
select *
, ROW_NUMBER() OVER(PARTITION BY CName ORDER BY AddressLine) AS row
from myTable
) as a
where row = 1

これは、rowという列を作成します。これは、同じCNameを検出するたびに増加するカウンターであり、AddressLineによってそれらの発生にインデックスを付けます。 where row = 1を課すことにより、CNameがアルファベット順に最初に来るAddressLineを選択できます。 order bydescの場合、CNameがアルファベット順に最後に来るAddressLineを選択します。

4
FatihAkici

これにより、重複する行ごとに1行が表示されます。また、ビット型の列も提供され、少なくともMS Sql Serverで機能します。

(select cname, address 
from (
  select cname,address, rn=row_number() over (partition by cname order by cname) 
  from customeraddresses  
) x 
where rn = 1) order by cname

代わりにすべての重複を検索する場合は、rn = 1をrn> 1に変更します。これが役立つことを願っています

1
netfed