消除重复数据

时间:2010-09-22 19:10:12

标签: sql postgresql group-by distinct

查询

SELECT
  ppc.personid,
  ppc.category,
  ppc.phonenumber,
  ppc.createts
FROM
  person_phone_contacts ppc
WHERE  
      CURRENT_TIMESTAMP BETWEEN ppc.createts AND ppc.endts
  AND CURRENT_DATE BETWEEN ppc.effectivedate AND ppc.enddate
ORDER BY
  ppc.personid, ppc.category, ppc.createts DESC

产生的数据

3742 | Home   | xxx-xxx-xxxx | 2009-09-09 11:59:00.357-04
3742 | Home   | xxx-xxx-xxxx | 2009-08-04 20:13:17.161-04*
3742 | Mobile | xxx-xxx-xxxx | 2009-09-09 11:59:20.070-04
3742 | Mobile | xxx-xxx-xxxx | 2009-09-09 11:59:20.070-04*
3742 | Other  | xxx-xxx-xxxx | 2009-08-04 20:13:17.161-04

* 要丢弃的重复项。

所需数据

3742 | Home   | xxx-xxx-xxxx | 2009-09-09 11:59:00.357-04
3742 | Mobile | xxx-xxx-xxxx | 2009-09-09 11:59:20.070-04
3742 | Other  | xxx-xxx-xxxx | 2009-08-04 20:13:17.161-04

问题

使用最近的日期(即使同一个人的同一类别中的多个电话号码具有相同的日期),每个人每个类别检索一个电话号码的最有效方法是什么?

可能的解决方案

使用DISTINCT ON (ppc.category) category可以限制每个人的结果,但是如何将其单独应用于所有人?

约束

  • PostgreSQL 8.3
  • 没有存储的功能或程序

谢谢!

1 个答案:

答案 0 :(得分:1)

假设(personid,category,createts)是唯一的......

SELECT
  ppc.personid,
  ppc.category,
  ppc.phonenumber,
  ppc.createts
FROM
  person_phone_contacts AS ppc
  INNER JOIN (
    SELECT
      personid,
      category,
      MAX(createts) AS newest_createts
    FROM
      person_phone_contacts
    WHERE  
          CURRENT_TIMESTAMP BETWEEN createts AND endts
      AND CURRENT_DATE BETWEEN effectivedate AND enddate
    GROUP BY
      personid, category
  ) AS ppc2
  ON ppc.personid = ppc2.personid
    AND ppc.category = ppc2.category
    AND ppc.createts = ppc2.newest_createts

我不熟悉Postgres的SQL方言(我自己使用MSSQL,可以更优雅地解决这个问题),但由于这是非常标准的SQL,我认为它应该可行。