Postgres:如何在子查询中使用字段值

时间:2014-08-21 12:23:47

标签: sql postgresql

我有这样的db表:

id | user | service |   pay_date   |   status

---+------+---------+--------------+------------

1  | john |    1    |  2014-08-20  |     1    
2  | john |    3    |  2014-07-24  |     0

我正在尝试构建查询,该查询返回所有未支付服务1或服务3的用户在2个日期和避免活动服务之间(状态= 0表示服务1和服务2)。问题是查询返回服务3,但这不正确,因为服务1处于活动状态。

SELECT * 
FROM services 
WHERE date > 2014-07-01 
  AND date < 2014-07-30 
  AND service = 1 OR service = 3

我的解决方案是在检查服务时检查服务3是否处于活动状态1.这样的事情......

SELECT * 
FROM services 
WHERE date > 2014-07-01 
  AND date < 2014-07-30 
  AND ((service = 1 AND "SERVICE 3 IS NOT ACTIVE") OR service = 3)

但是我无法检查当前用户“SERVICE 3是否处于活动状态”

2 个答案:

答案 0 :(得分:0)

我认为你想要不存在,即检查同一用户不存在另一个活动记录,可能是这样的:

SELECT *
FROM    Services
WHERE   Service IN (1, 3)
AND     pay_date > '2014-07-01'
AND     pay_date < '2014-07-30'
AND     NOT EXISTS 
        (   SELECT  1 
            FROM    services AS s2 
            WHERE   s2.Name = s.Name 
            AND     s2.Status = 1 
            AND     s2.Service IN (1, 3)
            AND     s2.pay_date > '2014-07-01'
            AND     s2.pay_date < '2014-07-30'
        );

答案 1 :(得分:0)

没有符合所有这些标准的单一记录。

id 1记录不能同时服务= 1&amp;服务= 3在某个时间

id | user | service |   pay_date   |   status
---+------+---------+--------------+------------
1  | john |    1    |  2014-08-20  |     1  

id 2记录不能同时服务= 1&amp;服务= 3在某个时间

id | user | service |   pay_date   |   status
---+------+---------+--------------+------------
2  | john |    3    |  2014-08-24  |     0       -- nb: I changed this date!

SO:您的标准要求将记录1与记录2进行比较(或更广泛地说,您需要比较记录和#34;记录和#34;)。下面我使用EXISTS来比较各个记录。

SELECT
      *
FROM services
WHERE (pay_date >= '2014-08-01'
      AND pay_date < '2014-08-30')
      AND service = 1
      AND EXISTS (
            SELECT
                  NULL
            FROM services s3
            WHERE (s3.pay_date >= '2014-08-01'
                  AND s3.pay_date < '2014-08-30')
                  AND s3.service = 3
                  and s3.status = 1
                  AND s3.user = services.user
                 )

参见 SQLfiddle Demo


顺便说一下,通过&gt; =&amp; amp;来使用日期范围更为常规。 &LT;