SQL:获取第一个匹配,如果first为null,则为第二个匹配,如果两者都存在,则为两者(PostgreSQL)

时间:2014-10-03 14:49:54

标签: sql postgresql join conditional-statements

  

table1.created_at BETWEEN'2014-10-02 00:00:00 UTC'AND'2014-10-02   23:59:59 UTC'AND table2.created_at BETWEEN'2014-10-02 00:00:00 UTC'   AND'2014-10-02 23:59:59 UTC'

我也有一些联接和另一个查询,但这对我来说很有意思。

所以,如果我在第一张桌子的某个范围内有一些记录 - 我应该接受它。 如果是第一个和第二个 - 来自两者的值。 如果仅次于 - 从第二个。

现在,如果其中一个表为空 - 我的结果为空。 如果我将使用OR - 我也只会从其中一个表中获得记录。

如何重写查询以获得预期结果?

2 个答案:

答案 0 :(得分:1)

我建议您将查询分成两个单独的查询,一个针对table1日期进行测试,另一个针对table2日期进行测试。然后你可以使用UNION ALL来组合它们,这应该产生你要求的行为。

样品:

SELECT t1.Data1, ...
FROM Table1 t1
    INNER JOIN Table2 t2 ON ...
WHERE t1.Created_at BETWEEN '2014-10-02 00:00:00 UTC' AND '2014-10-02 23:59:59 UTC'
UNION ALL
SELECT t1.Data1, ...
FROM Table1 t1
    INNER JOIN Table2 t2 ON ...
WHERE t2.Created_at BETWEEN '2014-10-02 00:00:00 UTC' AND '2014-10-02 23:59:59 UTC'

修改

根据你的例子,我会做这样的事情:

SELECT COUNT(*) AS count_all,
    users.id AS users_id 
FROM 
(
    SELECT users.id
    FROM "users" 
        LEFT JOIN table1 ON table1.col1_id = cols1.id 
        LEFT JOIN table2 ON table2.col2_id = cols2.id 
    WHERE "users"."role_id" IN (1,2,4,5,6,7,8)
        AND table1.created_at BETWEEN '2014-09-27 00:00:00 UTC' AND '2014-10-03 23:59:59 UTC' 
    UNION ALL
    SELECT users.id
    FROM "users" 
        LEFT JOIN table1 ON table1.col1_id = cols1.id 
        LEFT JOIN table2 ON table2.col2_id = cols2.id 
    WHERE "users"."role_id" IN (1,2,4,5,6,7,8)
        AND table2.created_at BETWEEN '2014-09-27 00:00:00 UTC' AND '2014-10-03 23:59:59 UTC' 
)
GROUP BY users.id

答案 1 :(得分:0)

试试这个:

SELECT *
  FROM table1
 WHERE table1.created_at BETWEEN '2014-10-02 00:00:00 UTC' AND '2014-10-02 23:59:59 UTC' 

UNION ALL

SELECT *
  FROM table2
 WHERE table2.created_at BETWEEN '2014-10-02 00:00:00 UTC' AND '2014-10-02 23:59:59 UTC'

确保table1具有与table2相同的列数。