正确的方法来计算2个项目列表中一个项目一起订购的次数

时间:2018-12-23 12:45:04

标签: sql firebird

我目前正在自学SQL,因此对于大多数人来说,这似乎是一个简单的问题(如果我正确表达的话)。

我有一个表格“订单”,如下所示:

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

我想做的是计算所有Ordmids的2个项目列表中的任何一个项目(如IN(itmsid1,itmsid2)共存)的次数。

例如,如果我查询(12,99)中的itemsid以及(22,57)中的itemsid,那么最后我将得到1。

我该怎么做?

编辑:我必须说这个社区很棒!闪电般的快速反应,甚至非常有帮助。非常感谢您。我欠你!

3 个答案:

答案 0 :(得分:1)

您可以使用group byhaving

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 ;

答案 1 :(得分:1)

我将您的问题解释为:

一个Ormid小组将项ID 12或99与项ID 22或57相结合的次数是多少。

意思是,一个ormid组应该具有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的ormid的清单。另一个拉取所有具有22或57的ormid的清单。

将这些列表连接在一起时,只有相等的ormid才能生存成为连接的结果

因此,我们最终只列出了具有12或99的Ormid以及22或57的那些Ormid。对此进行计数(以防止将12,99,22的Ormid计为2,或者其中有12,22,57,99个项目的残次被计为4)提供了答案。

如果您需要更多详细信息,为什么为什么使用id为12,99,22,57的ormid导致计数为4,请告诉我。您可能已经知道,我不会马上谈论笛卡尔积。.

有几种解决这类问题的方法,我之所以选择这种方法,是因为它很容易解释,因为查询逻辑与人们可能会思考的方式非常吻合

答案 2 :(得分:0)

您只希望订购从set1中至少订购一个且从set 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)
)

或者,您可以使用量化的比较谓词(ANYSOME)(另请参见Quantified Subquery Predicates in the Firebird 2.5 Language Reference)。与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)
)