Postgres查询初学者

时间:2017-04-04 18:11:36

标签: postgresql

好的,我删除了之前的帖子,并会再试一次。我确信我不知道这个主题,我不确定这是一个循环,还是我应该使用存储函数或如何获得我正在寻找的东西。这是样本数据和预期输出;

我有一张表A.表有以下字段;创建日期,唯一人员密钥,类型,位置。

我需要一个Postgres查询,说明任何给定月份(参数,基于创建日期)并给出位置(基于位置的参数 field),为我提供以下链接,其中唯一人密钥可能会复制+或 - 在创建的日期之后30天在同一类型<给出的月份内/ em>但所有位置

示例数据

    Date Created | Unique Person  |  Type   |  Location
    ---------------------------------------------------
     2/5/2017    |   1            |  Admit  |  Hospital1
     2/6/2017    |   2            |  Admit  |  Hospital2
     2/15/2017   |   1            |  Admit  |  Hospital2
     2/28/2017   |   3            |  Admit  |  Hospital2
     3/3/2017    |   2            |  Admit  |  Hospital1
     3/15/2017   |   3            |  Admit  |  Hospital3
     3/20/2017   |   4            |  Admit  |  Hospital1
     4/1/2017    |   1            |  Admit  |  Hospital2 

Hospital1的3月份输出:

    DateCreated| UniquePerson | Type | Location | +-30days | OtherLoc.
    ------------------------------------------------------------------------
     3/3/2017  |    2         | Admit| Hospital1 | 2/6/2017   | Hospital2

Hospital2的3月份输出:

    None, because no one was seen at Hospital2 in March

Hospital3的3月份输出:

    DateCreated| UniquePerson | Type | Location | +-30days | otherLoc.
    ------------------------------------------------------------------------
     3/15/2017 |   3          | Admit| Hospital3 | 2/28/2017  | Hospital2

1 个答案:

答案 0 :(得分:1)

版本1

我会使用WITH子句。请注意,我添加了一列id,它是简化查询的主键。这只是为了防止行与自己匹配。

WITH x AS (
    SELECT
        id,
        date_created,
        unique_person_id,
        type,
        location
    FROM
        a
    WHERE
        location = 'Hospital1' AND
        date_trunc('month', date_created) = date_trunc('month', '2017-03-01'::date)
)
SELECT
    x.date_created,
    x.unique_person_id,
    x.type,
    x.location,
    a.date_created AS "+-30days",
    a.location AS other_location
FROM
    x
    JOIN a
    USING (unique_person_id, type)
WHERE
    x.id != a.id AND
    abs(x.date_created - a.date_created) <= 30;

现在做一些解释:

  • 首先我们选择一个带有WITH子句的参考数据。可以把它想象成一个临时表,我们可以在主查询中引用它。在给定的例子中,它可能是给定医院的“主要访问”。
  • 然后我们加入“主要访问”与同一个人的其他访问和类型(JOIN条件),这些访问发生在30天的日期差异(WHERE条件)。

请注意,WITH查询具有您要检查的限制(位置和日期)。我使用date_trunc函数将日期截断为指定的精度(在这种情况下为一个月)。

版本2

@Laurenz Albe所述,没有特别需要使用WITH子句。是的,所以这是第二个版本。

SELECT
    x.date_created,
    x.unique_person_id,
    x.type,
    x.location,
    a.date_created AS "+-30days",
    a.location AS other_location
FROM
    a AS x
    JOIN a
    USING (unique_person_id, type)
WHERE
    x.location = 'Hospital1' AND
    date_trunc('month', x.date_created) = date_trunc('month', '2017-03-01'::date) AND
    x.id != a.id AND
    abs(x.date_created - a.date_created) <= 30;

这个版本比第一个版本短,但在我看来,第一个版本更容易理解。我没有足够大的数据集来测试,我想知道哪一个运行得更快(查询规划器显示两者的相似值)。