如何编写SQL查询来计算满足多列排除条件的多个列条件的值?

时间:2017-04-13 17:22:09

标签: mysql sql

我正在使用MySQL作为数据库。

我有一个连接表,其中包含两个适用于此查询的字段ItemGroupID和CheckNumber。

CheckNumber可以包含多个ItemGroupID,而ItemGroupID可以包含多个CheckNumbers

我正在尝试计算满足多个条件的支票数量(包含项目组281和项目组274,但在任何记录中都没有项目组280或34。这是联接表格的片段。

ItemGroupID | CheckNumber
-----------   -----------
    281           101
    274           101
    103           101
    281           101
    280           102
    281           102
    274           102
    281           103

对于上表,查询应仅返回CheckNumber 101的计数1,因为它同时具有id 281和274,并且它不包含280或34.其他检查号不应返回计数。 CheckNumber 102在检查中排除了GroupID。 CheckNumber 103不包含281 AND 274。

以下是我写的查询。查询的问题是它不排除使用ItemGroupID 280或34的检查。我认为这是GROUP BY中的Count函数的问题。但我不确定如何重写它来解决这个问题。

SELECT COUNT(id.CheckNumber) AS Total
FROM ItemGroupMember igm
    INNER JOIN ItemDetail id ON igm.ItemID = id.ItemID
WHERE igm.ItemGroupID IN (281,274)
    AND NOT igm.ItemGroupID IN (280,34)
    AND id.DOB BETWEEN 3/14/2017 AND 3/14/2017
    AND id.LocationID = 22
GROUP BY id.CheckNumber HAVING COUNT(DISTINCT igm.ItemGroupID) = 2

感谢帮助。

2 个答案:

答案 0 :(得分:1)

怎么样:

数据:

create table exp (
  ItemGroupID int,
  CheckNumber int
  );

  Insert into exp values (281, 101) ;
  Insert into exp values (274, 101) ;
  Insert into exp values (103, 101) ;
  Insert into exp values (281, 101) ;
  Insert into exp values (280, 102) ;
  Insert into exp values (281, 102) ;
  Insert into exp values (274, 102) ;
  Insert into exp values (281, 103) ;

查询:

Select checknumber, count(*)
From exp
Where
exists (Select e1.ItemGroupID From exp e1 Where e1.checknumber = exp.checknumber and e1.ItemGroupID in (281))
and exists (Select e1.ItemGroupID From exp e1 Where e1.checknumber = exp.checknumber and e1.ItemGroupID in (274))
and not exists (Select e1.ItemGroupID From exp e1 Where e1.checknumber = exp.checknumber and e1.ItemGroupID in (280, 34))
Group by checknumber

真实数据:

Select checknumber, count(*)
From (Select * From ItemGroupMember igm INNER JOIN ItemDetail id ON igm.ItemID = id.ItemID WHERE id.DOB BETWEEN 3/14/2017 AND 3/14/2017 AND id.LocationID = 22) exp
Where
    exists (Select e1.ItemGroupID From (Select * From ItemGroupMember igm INNER JOIN ItemDetail id ON igm.ItemID = id.ItemID WHERE id.DOB BETWEEN 3/14/2017 AND 3/14/2017 AND id.LocationID = 22) e1 Where e1.checknumber = exp.checknumber and e1.ItemGroupID in (281))
    and exists (Select e1.ItemGroupID From (Select * From ItemGroupMember igm INNER JOIN ItemDetail id ON igm.ItemID = id.ItemID WHERE id.DOB BETWEEN 3/14/2017 AND 3/14/2017 AND id.LocationID = 22) e1 Where e1.checknumber = exp.checknumber and e1.ItemGroupID in (274))
    and not exists (Select e1.ItemGroupID From (Select * From ItemGroupMember igm INNER JOIN ItemDetail id ON igm.ItemID = id.ItemID WHERE id.DOB BETWEEN 3/14/2017 AND 3/14/2017 AND id.LocationID = 22) e1 Where e1.checknumber = exp.checknumber and e1.ItemGroupID in (280, 34))
Group by checknumber

答案 1 :(得分:0)

SELECT COUNT(id.CheckNumber) AS Total
FROM ItemDetail id
JOIN ItemGroupMember igm ON igm.ItemID = id.ItemID AND igm.ItemGroupID IN (281,274)
LEFT JOIN ItemGroupMember igm2 ON igm2.ItemID = id.ItemID AND igm2.ItemGroupID IN (280,34)
WHERE 
    id.DOB BETWEEN 3/14/2017 AND 3/14/2017
    AND id.LocationID = 22
    AND igm2.ItemID is null -- Make sure that you exclude any where the groupID is 280 or 34
group by id.CheckNumber having Total = 2;