3

我有一张带有重复 ID 的表格,稍后我会修复它。基本上我想返回 ID 不同的所有行,但我想要整个行。就像是:

select * from table group by ID

select * from table where (ID is not repeated)

在这种情况下,它们是相同的行,所以我不在乎它是 First 还是 Last,Min 还是 Max。

请注意,我不想这样做:

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

甲骨文:http ://www.sqlfiddle.com/#!4/b5cf9/1

Sql 服务器: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');

为了从重复中只提取一行,我们需要在现有数据上添加第三列。

这将帮助我们从重复项中提取一行且仅一行

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

试试这个。它可能会起作用,因为两行中的所有列都是相同的。

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 回答