如何从多个列中任一列的列表中查找值

时间:2019-05-12 03:08:44

标签: database postgresql

我有一个数字代码列表(例如“ 110”),并且正在查询包含3列crm_cd,crm_cd_1,crm_cd_2的数据集...我试图找到包含任何我的代码的任何记录3列。

我不知道是否应该创建另一个col并将3连接在一起,或者我是否可以使用OR语句进行查询-我尝试过的所有方法都没有成功(例如,给我天文数字)。

+----+--------+----------+----------+
| id | crm_cd | crm_cd_1 | crm_cd_2 |
+----+--------+----------+----------+
|  1 |    110 |      113 |          |
|  2 |    987 |      444 |      777 |
|  3 |    888 |      113 |      222 |
|  4 |    999 |      444 |          |
|  5 |    333 |      121 |      888 |
+----+--------+----------+----------+

    SELECT count (*)
    FROM public.crime
    WHERE date_occ >= '2017-06-01 00:00:00' 
      AND date_occ <= '2018-05-31 00:00:00'
    AND crm_cd IN ('110','113','121')
      OR crm_cd_1 IN ('110','113','121')      
      OR crm_cd_2 IN ('110','113','121');

使用上面的示例,我试图获取记录1,3,&5。

任何方向将不胜感激。

2 个答案:

答案 0 :(得分:0)

您需要在crm限制周围加上括号:

SELECT
    COUNT(*) AS cnt
FROM public.crime
WHERE
    date_occ BETWEEN '2017-06-01 00:00:00' AND '2018-05-31 00:00:00' AND
    (
        crm_cd IN ('110','113','121') OR
        crm_cd_1 IN ('110','113','121') OR
        crm_cd_2 IN ('110','113','121')
    );

由于默认情况下AND的优先级比OR高,因此这是对当前WHERE子句进行求值的方式:

WHERE
    (date_occ BETWEEN '2017-06-01 00:00:00' AND '2018-05-31 00:00:00' AND
    crm_cd IN ('110','113','121')) OR
    crm_cd_1 IN ('110','113','121') OR
    crm_cd_2 IN ('110','113','121')

也就是说,任何与crm_cd_1crm_cd_2限制匹配的记录,无论日期限制如何,都将被视为匹配项。但是,您的既定逻辑是同时使crm和日期限制均正确。

答案 1 :(得分:0)

一种简短的编写方法是使用Postgres的数组功能:

WHERE date_occ BETWEEN '2017-06-01 00:00:00' AND '2018-05-31 00:00:00' 
  AND array[crm_cd, crm_cd_1, crm_cd_1] && array[110,113,121];

&&overlaps运算符,如果每边的至少一个值匹配,则返回true。

还可以在表达式array[crm_cd, crm_cd_1, crm_cd_1]上创建索引