postgresql复杂查询连接同一个表

时间:2013-12-18 16:51:06

标签: postgresql

我想从过去6个月未创建任何交易的表'交易'中获取这些客户。

表:

'transactions'
id, email, state, paid_at

要想象:

|------------------------ time period with all transactions --------------------|
|-- period before month transactions > 0) ---|---- curr month transactions = 0 -|

我想这是可行的,只有那些在右侧没有任何交易的联接。

实施例: 月=十一月

左侧的条件应为:

  1. COUNT(l.id)> 0
  2. l.paid_at< '2013-05-01 00:00:00'
  3. 右侧的条件:

    1. COUNT(r.id)= 0
    2. r.paid_at BETWEEN'2013-05-01 00:00:00''''2013-11-30 23:59:59'
    3. 加入正确的方法吗?

      答案

      SELECT
          C .email
      FROM
          transactions C
      WHERE
          (
              C .email NOT IN (
                  SELECT DISTINCT
                      email
                  FROM
                      transactions
                  WHERE
                      paid_at >= '2013-05-01 00:00:00'
                  AND paid_at <= '2013-11-30 23:59:59'
              )
              AND
              C .email IN (
                  SELECT DISTINCT
                      email
                  FROM
                      transactions
                  WHERE
                      paid_at <= '2013-05-01 00:00:00'
      
              )
          )
      AND c.paid_at <= '2013-11-30 23:59:59'
      

1 个答案:

答案 0 :(得分:1)

有几种方法可以做到这一点。使用子查询为过去6个月内的事务获取不同的客户ID,然后选择其id不在子查询中的客户。

select c.id, c.name
from customer c
where c.id not in (select distinct customer_id from transaction where dt between <start> and <end>);

或者,使用从客户到事务的左连接,并过滤结果以使事务标识为null。左连接包括左侧表中的所有行,即使右侧表中没有匹配的行也是如此。左边连接的解释:http://www.codinghorror.com/blog/2007/10/a-visual-explanation-of-sql-joins.html

select c.id, c.name
from customer c
    left join transaction t on c.id = t.customer_id
          and t.dt between <start> and <end>
where t.id is null;

左连接方法可能更快。