Я борюсь с несколькими И/ИЛИ условиями в этом запросе. Я близок или есть более простое решение?

#sql

Вопрос:

В таблице данных есть три поля, в которых указана страна пользователя. Например, suzyq@email.com имеет страну доставки, страну и страну, все из которых могут быть заполнены или не заполнены полностью. Существуют также различные варианты данных, которые находятся в этих полях (США, США, США, Калифорния, CAN).

Пример таблицы данных:

 | email   | shipping| country  | country_sel |
|:----:   | :------:| :-----:  |   :-----:   |
|1@ex.com |   US    |    US    |     USA     |
|2@ex.com |   US    |          |      US     |
|3@ex.com |   CA    |    CA    |      US     |
|4@ex.com |   AU    |    AU    |             |

 

Цель состоит в том, чтобы выбрать ТОЛЬКО пользователей, у которых есть варианты США, США, США в одном, двух или всех трех из этих полей, таких как 1@ex.com и 2@ex.com.
Примечание : Два из этих полей могут быть пустыми

И мне нужно исключить всех пользователей, у которых нет никаких вариантов США, США, США, таких как 4@ex.com.

Мне также нужно исключить всех пользователей, у которых есть варианты США, США, США с данными, не относящимися к США. Как 3@ex.com пример выше.

Ближе всего я подошел к использованию пункта «КРОМЕ» ниже, но он исключает набор пользователей, которые мне ДЕЙСТВИТЕЛЬНО нужны. Также есть один или два пользователя, которые не являются НАМИ. Я несколько раз пробовал этот запрос, меняя И и или, но, похоже, не могу сделать это правильно. Пожалуйста, любая помощь будет очень признательна!

     SELECT email, shipping, country, country_sel
    FROM table
    WHERE purchased = 'True'
    AND ((shipping IN ('US','U.S','USA') OR shipping IS NULL)
    OR (country IN ('US','U.S','USA') OR country IS NULL)
    OR (country_sel IN ('US','U.S','USA') OR country_sel IS NULL))
    EXCEPT
    SELECT email, shipping, country, country_sel
    FROM table
    WHERE purchased = 'True'
    AND ((shipping IS NOT NULL AND shipping NOT IN ('US','U.S','USA'))
    AND (country IS NOT NULL AND country NOT IN ('US','U.S','USA'))
    OR (country_sel IS NOT NULL AND country_sel NOT IN ('US','U.S','USA')));
 

Комментарии:

1. Возможно, вам потребуется повторить свою цель; » выберите ТОЛЬКО пользователей, у которых есть все варианты США, США, США в каждом из трех полей, например 1@ex.com и 2@ex.com.’ 2@ex.com не имеет значения(при условии, что оно равно НУЛЮ) в country поле. Это отличается от того, что вы утверждаете.

2. Вы правы. Я перефразировал цель. Цель состоит в том, чтобы привлечь всех пользователей, у которых есть США, США, США в любом или всех трех полях (доставка, страна и/или country_sel). И исключите пользователей, которые имеют значения, отличные от США, США, США, в любой комбинации этих полей, например 3@ex.com и 4@ex.com в приведенных данных примера.

Ответ №1:

Это то, что вы ищете —

 SELECT email, shipping, country, country_sel
    FROM table
    WHERE purchased = 'True'
    AND ((shipping IN ('US','U.S','USA') OR shipping IS NULL)
    AND (country IN ('US','U.S','USA') OR country IS NULL)
    AND (country_sel IN ('US','U.S','USA') OR country_sel IS NULL))
    -- above would pull even all three as blank (NULL); so, adding below filter
    AND (shipping IN ('US','U.S','USA') OR 
         country IN ('US','U.S','USA') OR
         country_sel IN ('US','U.S','USA'));
 

Кроме того, обратите внимание, что вы использовали » США; вместо «США»
Вам также нужно будет это исправить.

Ответ №2:

Используя боковые и кроме

 select  email, shipping, country, country_sel
from  tbl
cross join lateral (
    select count(*) n
    from (
       select * 
          from (values (shipping),(country),(country_sel)) t1(c)
          where c is not null
       except 
       select * 
       from (values ('US'),('U.S'),('USA')) t2(c)
    ) t
 ) t
 where t.n = 0;
 

db<>скрипка

Ответ №3:

Одним из методов является lateral join подсчет количества значений, не относящихся к США:

 SELECT email, shipping, country, country_sel
FROM table t CROSS JOIN LATERAL
     (SELECT COUNT(*) as cnt_non_us
      FROM (VALUES (shipping), (country), (country_sel)) v(country)
      WHERE v.country NOT IN ('US', 'U.S', 'USA')
     ) c
WHERE purchased = 'True' AND c.cnt_non_us = 0;
 

Ответ №4:

 SELECT email, shipping, country, country_sel
    FROM table
    WHERE purchased = 'True'
    AND ((shipping IN ('US','U.S','USA') OR shipping IS NULL)
    AND (country IN ('US','U.S','USA') OR country IS NULL)
    AND (country_sel IN ('US','U.S','USA') OR country_sel IS NULL))
    AND ( shipping IS Not Null OR country IS Not Null OR country_sel IS Not Null);
 

Комментарии:

1. Спасибо за помощь, но, похоже, мой первоначальный вопрос был сформулирован неправильно. Я обновил, какова цель для этого. Да, это решение действительно извлекает все поля со значением US, но я ищу поля, которые имеют комбинацию значений US. Кроме того, исключая любую комбинацию ценностей США и ценностей за пределами США.

2. ПРИВЕТ @LinaDee Я перечитал вашу цель и не понимаю, почему этот запрос не работает, он работает с вашими образцами. Пожалуйста, добавьте другой пример, который не работает с этим sql.