SQL:返回所有行的不同选择

时间:2013-02-28 22:59:34

标签: sql ms-access group-by distinct

好吧也许没有可以帮助我的SQL语句,所以我不知道该怎么称呼它。

在我正在使用的Access 2013数据库中:

所有表格都包含name address phone city state zip

的字段

什么用作primary key is the phone number,但未将其设置为Access中的主键。

我想从此数据库中删除重复记录。

电话号码是这里明显的唯一标识符,但我如何能够检索所有数据,按电话号码排序,并删除任何包含电话号码但保留其中一个的记录?

在大多数情况下,我相当确定地址,名称和所有其他字段将匹配,我只想清理表格,以便没有重复。

2 个答案:

答案 0 :(得分:1)

我假设phone是你的伪主键。意味着:使用查询它应该是唯一的。

对于Postgres,以下内容可行:

SELECT DISTINCT ON (phone)
  *
FROM your_table

它为每个电话号码选择一个任意行,因此保持电话号码不同。

也许有相当于DISTINCT ON (...)的访问权限?


如果表中有一个真正的唯一id标识符,这将有效:

SELECT *
FROM your_table
WHERE id IN (
  SELECT min(id)
  FROM your_table
  GROUP BY phone
)

让它工作,也许不完美(最快的查询),但它正在工作!

SELECT *
FROM (
  SELECT ROW_NUMBER() OVER () AS pseudoid, *
  FROM your_table
) x
JOIN (
  SELECT MIN(pseudoid) AS pseudoid
  FROM (
    SELECT ROW_NUMBER() OVER () AS pseudoid, phone
    FROM your_table
  ) z
  GROUP BY z.phone
) y
ON x.pseudoid = y.pseudoid

说明:

第一(第9-10行):

SELECT ROW_NUMBER() OVER () AS pseudoid, phone
FROM your_table

这为每行提供了一个pseudo_id(加上电话号码)。所以我们有重复的条目,但每个条目都有其独特的伪。然后(第7-12行):

SELECT MIN(pseudoid) AS pseudoid
FROM (
  SELECT ROW_NUMBER() OVER () AS pseudoid, phone
  FROM your_table
) z
GROUP BY z.phone

这使我们的电话号码独一无二,并始终选择MIN(伪音)。然后(第3-4行):

SELECT ROW_NUMBER() OVER () AS pseudoid, *
FROM your_table

为WHOLE表创建一个伪类。

然后我们加入这些表:这为每个电话号码提供了具有最小伪id的完整行(+ pseudoid)。

小一点(也许更快):

WITH pseudo_id_table AS (SELECT ROW_NUMBER() OVER () AS pseudoid, * FROM your_table)
SELECT *
FROM pseudo_id_table x
JOIN (
  SELECT MIN(pseudoid) AS pseudoid
  FROM pseudo_id_table
  GROUP BY phone
) y
ON x.pseudoid = y.pseudoid

答案 1 :(得分:0)

有一种更简单的方法:

  1. 复制表格(仅限结构)
  2. 将手机设为主键
  3. 将旧表中的数据附加到新表。任何重复的记录都会拒绝附加。
  4. 删除旧表
  5. 将新表重命名为旧表名
  6. 这只有在您保留哪条记录无关紧要的情况下才有效。