Правильный способ подсчитать, сколько раз предмет из двух списков предметов заказывается вместе - PullRequest
0 голосов
/ 23 декабря 2018

Я в настоящее время самообучающийся SQL, поэтому для большинства из вас это, вероятно, будет казаться простым вопросом (если я его правильно выразил).

У меня есть таблица 'orders', которая выглядит следующим образом:

Orddid(Uid)    Ordmid      Odate        Itmsid
-----------    ------      -----        ------
  100101       100101    01.12.2018       12
  100102       100101    01.12.2018       88
  100103       100101    01.12.2018       57
  100104       100102    01.12.2018       12

То, что я хочу сделать, это подсчитать, сколько раз любой элемент из 2 списков элементов (как в IN (itmsid1, itmsid2) сосуществует для всех Ordmids.

Например,если бы я запросил около itemsid в (12,99), а также itemsid в (22,57), я бы получил счет в конце.

Как мне это сделать?

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

Ответы [ 3 ]

0 голосов
/ 23 декабря 2018

Я интерпретирую ваш вопрос как:

Сколько раз группа Ормид имеет элемент itemid 12 или 99 в сочетании с itemid 22 или 57 ..

ЗначениеОрмидная группа должна иметь либо 12 и 22, либо 12 и 57, либо 99 и 22, либо 99 и 27 (по крайней мере .. 12,22,57 и т. д. также будет разрешено).На простом английском языке это может быть выражено как «Сколько раз кто-то покупал (клавиатуру или мышь) в сочетании с (карта памяти или картридж принтера)» - чтобы получить специальное предложение, кто-то должен купить хотя бы одинэлемент из группы 1 и один элемент из группы 2

Много способов сделать, вот один из них:

SELECT COUNT(distinct t_or_nn.ormid) FROM

(SELECT ormid FROM orders WHERE itemid in (12,99)) t_or_nn
INNER JOIN
(SELECT ormid FROM orders WHERE itemid in (22,57)) tt_or_fs
ON t_or_nn.ormid = rr_or_fs.ormid

Как это работает:

Два подзапроса;один тянет список всех ормид, имеющих 12 или 99. Другой тянет список всех ормид, имеющих 22 или 57.

Когда эти списки объединяются, только равные ормиды будутвыжить, чтобы стать результатом объединения

Таким образом, мы получаем список только тех ормид, которые имеют 12 или 99, в сочетании с 22 или 57. Считая это (отчетливо, чтобы предотвратить ормиду с12,99,22 считается как 2, или ормида из 12,22,57,99 элементов считается как 4) дает наш ответ.

Если вам нужно больше подробностей о том, почему наличие ормиды с предметами 12, 99,22,57 приводит к подсчету 4, дайте мне знать.Я не стану сразу говорить о декартовых произведениях, как вы, возможно, уже знаете ..

Есть несколько способов решения таких проблем, я выбрал этот способ, поскольку его довольно легко объяснить, потому чтологика запроса довольно хорошо согласована с тем, как человек может думать об этом

0 голосов
/ 23 декабря 2018

Требуются только заказы, которые заказывают, по крайней мере, одну из набора 1 и, по крайней мере, одну из набора 2. Это означает, что вам нужно выбрать все записи, в которых выполняются оба условия, а затем подсчитать различные заказы:

ДляНапример, вы можете использовать exists, чтобы проверить для каждого заказа, есть ли у него запись в любом наборе:

select count(distinct ordmid)
from orders o
where exists (
  select * 
  from orders 
  where ordmid = o.ordmid and itmsid in (12, 99)
)
and exists (
  select *
  from orders
  where ordmid = o.ordmid and itmsid in (22, 57)
)

В качестве альтернативы, вы можете использовать количественный предикат сравнения (ANY или SOME) (см. также Количественные предикаты подзапросов в справочнике по языку Firebird 2.5 ).В отличие от решения exists это устраняет необходимость в коррелированном подзапросе.

select count(distinct ordmid)
from orders o
where ordmid = any(
  select ordmid 
  from orders 
  where itmsid in (12, 99)
)
and ordmid = any(
  select ordmid 
  from orders 
  where itmsid in (22, 57)
)
0 голосов
/ 23 декабря 2018

Вы можете использовать group by и having:

select o.ordmid
from orders o
where o.itmid in (12, 99)
group by o.ordmid
having count(distinct o.itmid) = 2;  -- number of items in the list

Если элементы не могут повторяться в пределах заказа, тогда используйте count(o.itmid) в having вместо count(distinct).

Если вам нужно число ordmid с, где это происходит, просто используйте это как подзапрос и используйте count():

select count(*)
from (select o.ordmid
      from orders o
      where o.itmid in (12, 99)
      group by o.ordmid
      having count(distinct o.itmid) = 2;  -- number of items in the list
    ) o;

РЕДАКТИРОВАТЬ:

Если у вас естьдва отдельных списка, и вы хотите, чтобы заказы имели как минимум один элемент из каждого списка, который вы можете сделать:

select o.ordmid
from orders o
group by o.ordmid
having sum(case when o.itmid in (<list 1>) then 1 else 0 end) > 0 and
       sum(case when o.itmid in (<list 2>) then 1 else 0 end) > 0 ;
...