3

ID が繰り返されるテーブルがありますが、これは後で修正します。基本的に、ID が異なるすべての行を返したいのですが、ENTIRE 行が必要です。何かのようなもの:

select * from table group by ID

select * from table where (ID is not repeated)

この場合、それらは同一の行であるため、最初か最後か、最小か最大かは気にしません。

私はこれをしたくないことに注意してください:

select MIN(col1), MIN(col2), ... from table group by ID

すべての列を列挙せずにこの結果を取得する方法が必要です。

編集: SQL Server 2008 R2 を使用しています。

4

4 に答える 4

2

MySqlを使用している場合は、次のようにします。

select 
    *
from tbl
group by ID

MySQLライブテスト:http ://www.sqlfiddle.com/#!2 / 8c7fd / 2

Postgresqlを使用している場合は、次のようにします。

select distinct on(id)
    *
from tbl
order by id

Postgresql DISTINCT ONが必要な場合は、少なくともCTEウィンドウ関数と同じくらい予測可能です。別の列を並べ替えます:

select distinct on(id)
    *
from tbl
order by id
   , someColumnHere -- Choose ASC for first row, DESC for last row

Postgresqlライブテスト:http ://www.sqlfiddle.com/#!1 / 8c7fd / 1

CTEウィンドウ対応データベース(Postgres、Oracle、Sql Serverなど)を使用している場合は、次を使用します。

with ranked as
(
  select 
      rank() over(partition by id order by column) rn,
      *
  from tbl
)
select * from ranked where rn = 1

CTEウィンドウ対応データベース:

Posgtresql:http ://www.sqlfiddle.com/#!1/8c7fd/2

Oracle:http ://www.sqlfiddle.com/#!4/b5cf9/1

SQL Server:http ://www.sqlfiddle.com/#!3/8c7fd/3

于 2012-05-03T23:41:41.713 に答える
2

どのデータベースを使用しているかを質問で述べていないため、すべてのデータベース プラットフォームで機能するクエリを作成することをお勧めします。ただし、このクエリでは、auto_number、identity、serial などのプロパティを持つ新しい列を作成する必要があります

これはクエリになります:

select * from tbl 
where (id,auto_number_here) in
   (select id, min(auto_number_here) 
    from tbl 
    group by id)

これは、Sql Server を除く多くのプラットフォームで機能します。Sql Server はタプルに対応していません。これを行う必要があります:

select * from tbl x
where 
   -- leave this comment, so it mimics the tuple capability
   -- (id,auto_number_here) in
   EXISTS
   (select
       -- Replace this:  
       -- id, min(auto_number_here) 

       -- With whatever floats your boat, 
       -- you can use 1, null(the value generated by Entity Framework's EXIST clause), 
       -- even 1/0 is ok :-) (this will not result to divide-by-zero error)

       -- But I prefer retaining the columns, so it mimics the tuple-capable database:
       id, min(auto_number_here) 

    from tbl 
    where id = x.id 
    group by id
    having x.auto_number_here = min(auto_number_here))

タプル関連の質問: sql in 句でタプルを使用する

一部のデータベースはタプルをサポートしていないため、代わりにシミュレートできます

select z.* from tbl z
join (select id, min(auto_number_here) as first_row from tbl group by id) as x
on z.id = x.id and z.auto_number_here = x.first_row

EXISTS アプローチよりも少し優れています。ただし、データベースがタプルをサポートしている場合は、代わりに使用してください。可能な限り、テーブルの関係のみを反映するために JOIN を使用し、フィルタリングには WHERE 句を使用します。


アップデート

おそらく具体的な例で明確に説明できるでしょう。主キーを置き忘れた既存のテーブルがあるとします。

create table tbl(
  id varchar(5), -- supposedly primary key 
  data int,
  message varchar(100) 
);


insert into tbl values
('A',1,'the'),
('A',1,'quick'),
('A',4,'brown'),
('B',2, 'fox'),
('B',5, 'jumps'),
('B',5, 'over'),
('C',6, 'the'),
('C',7, 'lazy');

重複から 1 行だけを取得するには、既存のデータに 3 番目の列を追加する必要があります。

これは、重複から 1 行だけを選択するのに役立ちます。

alter table tbl add auto_number_here int identity(1,1) not null;

これは今すぐ動作します:

select z.* from tbl z
join (select id, min(auto_number_here) as first_row from tbl group by id) as x
on z.id = x.id and z.auto_number_here = x.first_row

ライブ テスト: http://www.sqlfiddle.com/#!6/19b55/3

そして、これは次のとおりです。

select * from tbl x
where 
   -- leave this comment, so it mimics the tuple capability
   -- (id,auto_number_here) in
   EXISTS
   (
     select
       -- Replace this:  
       -- id, min(auto_number_here) 

       -- With whatever floats your boat, 
       -- you can use 1, null(the value generated by Entity Framework's EXIST clause), 
       -- even 1/0 is ok :-) (this will not result to divide-by-zero error)

       -- But I prefer retaining the columns, so it mimics the tuple-capable database:
       id, min(auto_number_here) 

    from tbl 
    where id = x.id 
    group by id
    having x.auto_number_here = min(auto_number_here)

   )

ライブ テスト: http://www.sqlfiddle.com/#!6/19b55/4

于 2012-05-04T00:49:53.037 に答える
1

これを試してみてください。2つの行のすべての列が同一であるため、機能する可能性があります。

select distinct *
from table
于 2012-05-03T23:38:11.810 に答える
1

サブクエリを使用して一意の ID を取得し、それを使用して結果をフィルタリングします。

SELECT *
FROM YourTable t,
INNER JOIN (
  SELECT Id, COUNT(*) 'count'
  FROM YourTable
  GROUP BY Id
) sq ON sq.Id = t.Id
WHERE sq.count = 1
于 2012-05-03T23:46:09.953 に答える