Запрос подмножества - PullRequest
       4

Запрос подмножества

1 голос
/ 20 апреля 2019

Я хочу написать запрос SQL, чтобы найти записи, которые содержат определенный столбец, и из этого подмножества хочу найти записи, которые не содержат какого-либо другого значения. Как вы пишете запрос для этого?

cid  id2  attribute
--------------------------------
 1  100  delete 
 1  100  payment
 1  100  void
 2  100  delete
 2  102  payment
 2  102  void
 3  102  delete
 3  103  payment

В приведенном выше примере я хочу перечислить cid, для которого существуют атрибуты payment и delete, но атрибут void не существует. Так что он должен перечислить 3 из приведенного выше примера, потому что у него нет атрибута void.

Забыл упомянуть, что может быть больше атрибутов. Однако мне нужно перечислить записи, для которых существует удаление и оплата, независимо от других атрибутов, но void не делает.

Ответы [ 4 ]

1 голос
/ 21 апреля 2019

Я называю это запросом "набор в наборе", потому что вы ищете определенные наборы атрибутов в каждом cid.

Я бы выразил это с помощью group by и условий в having:

select cid
from t
group by cid
having sum(case when attribute = 'payment' then 1 else 0 end) > 0 and
       sum(case when attribute = 'delete' then 1 else 0 end) > 0 and
       sum(case when attribute = 'void' then 1 else 0 end) = 0 ;

В некоторых базах данных вы можете упростить это с помощью агрегирования строк - при условии, что для cid s нет повторяющихся атрибутов. Например, используя функцию MySQL:

select cid
from t
where attribute in ('payment', 'delete' 'void')
group by cid
having group_concat(attribute order by attribute) = 'delete,payment';
1 голос
/ 20 апреля 2019

Вы можете использовать условное агрегирование:

select cid
from tablename
where attribute in ('delete', 'payment', 'void')
group by cid
having
  count(distinct attribute) = 2
  and  
  sum(
    case attribute 
      when 'void' then 1
      else 0
    end 
  ) = 0

Если атрибутов не больше, чем этих 3, вы можете опустить предложение WHERE.
См. Демоверсию .
Результаты:

| cid |
| --- |
| 3   | 
0 голосов
/ 20 апреля 2019

Я предполагаю, что есть только три атрибута, поэтому логика этого запроса:

Сначала COUNT количество атрибутов GROUP BY cid, а затем LEFT JOIN исходная таблица ON атрибут void .Вы должны получить cid, который имеет ровно 2 атрибута и не имеет значения void .

Исходная таблица называется temp:

SELECT
    subq2.result_cid
FROM (
    SELECT
        *
    FROM (
      SELECT
          T.cid AS result_cid,
          COUNT(T.attribute) AS count
      FROM
          temp AS T
      GROUP BY
          T.cid
    ) AS subq
    LEFT OUTER JOIN temp AS T2 ON subq.result_cid = T2.cid AND T2.attribute = 'void'
) AS subq2
WHERE subq2.count = 2 AND subq2.id2 IS NULL
0 голосов
/ 20 апреля 2019

использовать связанный подзапрос, используя not exists

     select t1.* from tablename t1
     where not exists( select 1 from tablename t2 
                 where t1.cid=t2.cid and attribute='void'

                 ) 
                 and exists ( select 1 from tablename t2 
                               where t1.cid=t2.cid
                             having count(distinct attribute)=2
                            )
                            and attribute in ('payment','delete')

демо онлайн

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...