Count()其中项目计数是JOIN回到另一个表

时间:2017-02-14 19:30:52

标签: sql sql-server tsql

我很确定我可以用这篇文章的标题做得更好。我不知道如何将这个问题缩小为一个有效的标题......

我有两张桌子。 BillItems和SubItems。

子项:

SubItemId    ItemId    MasterItemId
-----------------------------------
    1          50          10
    2          50          11
    3          60          10
    4          60          12
    5          70          10

BillItems:

BillItemId    ItemId
---------------------
    1           10
    2           11
    3           50
    4           60
    5           70

好的,现在,我需要知道BillItems是否包含多个MasterItem的子项,其中MasterItem也在BillItems表中。我知道这听起来令人困惑,所以我举个例子:

项目50是项目10和项目11的子项目。项目10和项目11都在BillItems表中。所以,我需要在查询中显示第50项。

项目60是项目10和项目12的子项目。项目10在BillItems表中,但项目12不是。所以我不希望Item 60显示在查询中。

项目10和11不是SubItems中的子项。所以我不希望它出现在查询中。

修改

使用上述数据,所需的输出将是:

ItemId
------
  50

7 个答案:

答案 0 :(得分:5)

希望我能正确理解你的问题。

请查看以下查询

select a.ItemId ItemId_a
    --, count(distinct a.MasterItemId) , count(distinct b.ItemId)
    from SubItems a left join BillItems b
    on a.MasterItemId = b.ItemId
    group by a.ItemId
    having count(distinct a.MasterItemId)  = count(distinct b.ItemId)
    and count(distinct a.MasterItemId)>1
    ;

答案 1 :(得分:3)

你可以这样做:

var result=from b in context.BillItems
           let masters=context.SubItems.Where(s=>s.ItemId==b.ItemId).Select(s=>s.MasterItemId)
           where masters.All(e=>context.BillItems.Any(x=>x.ItemId==e))
           select b.ItemId;

我后来注意到这是一个sql问题:),但是@Casey希望在Linq看看如何做到这一点。另一种解决方案(如果您使用EF和导航属性)可以是:

var result=context.BillItems.Where(b=>b.SubItems.All(s=>context.BillItems.Any(x=>x.ItemId==s.MasterItemId))
                            .Select(e=>e.ItemId);

或者也进行小组加入:

var result=from b in context.BillItems
           join s in context.SubItems on b.ItemId equals s.ItemId into g
           where g.All(e=>context.BillItems.Any(x=>x.ItemId==e.MasterItemId))
           select b.ItemId;

答案 2 :(得分:3)

我相信这就是你要找的东西:

SELECT si.ItemId
FROM SubItems si
WHERE EXISTS (SELECT 1 -- This EXISTS may be omitted if SubItems.ItemId has an enforced FOREIGN KEY reference to BillItems.ItemId
              FROM BillItems bi
              WHERE bi.ItemId = si.ItemId) 
  AND EXISTS (SELECT 1
              FROM BillItems bi
              WHERE bi.ItemId = si.MasterItemId)
GROUP BY si.ItemId
HAVING COUNT(DISTINCT si.MasterItemId) > 1;

答案 3 :(得分:3)

您可以使用相关的子查询来检查billitems表中是否存在masteritemid。对于不存在的ID,您将获得0的计数。然后,您可以group by itemid并删除所有缺少项目以及itemid组中有多个项目的项目。

select itemid 
from (select itemid,(select count(*) from billitems where s.masteritemid=itemid) as present_or_not
      from subitems s
      ) x 
group by itemid 
having count(case when present_or_not=0 then 1 end)=0 and count(*) > 1

答案 4 :(得分:2)

我的两分钱:

/*
create table BillItems (BillItemId int, ItemId int)
create table Subitems (SubitemId int, ItemId int, MasterItemId int)

insert BillItems values (1,10)
insert BillItems values (2,11)
insert BillItems values (3,50)
insert BillItems values (4,60)
insert BillItems values (5,70)

insert Subitems values(1,50,10)
insert Subitems values(2,50,11)
insert Subitems values(3,60,10)
insert Subitems values(4,60,12)
insert Subitems values(5,70,10)
*/

;with x as (select itemId from subitems group by itemId having count(*) > 1)
, y as (select s.ItemId, b.BillItemId from x join subitems s on x.itemid = s.itemid left join Billitems b on s.MasterItemId = b.ItemID)
select distinct itemid from y
except 
select itemid from y where billitemid is null

答案 5 :(得分:1)

你需要这样的东西:

SELECT * FROM
    (SELECT DISTINCT ItemId FROM TABLE1 t WHERE t.MasterId IN (SELECT ItemId FROM TABLE2)) as MasterInTable2
    EXCEPT
    (SELECT DISTINCT ItemId FROM TABLE1 t WHERE t.MasterId NOT IN (SELECT ItemId FROM TABLE2)) as
    MasterNotInTable2

答案 6 :(得分:1)

CREATE TABLE #SubItems (
                            id INT IDENTITY(1,1),
                            subItemID   INT,
                            ItemID      INT,
                            MasterItemID INT
                        )

INSERT INTO #SubItems
VALUES(1,50,10) 
INSERT INTO #SubItems
VALUES(2,50,11) 
INSERT INTO #SubItems
VALUES(3,60,10) 
INSERT INTO #SubItems
VALUES(4,60,12) 
INSERT INTO #SubItems
VALUES(5,70,10) 

CREATE TABLE #BillItems (
                            id INT IDENTITY(1,1),
                            BillItemID  INT,
                            ItemID      INT
                        )

INSERT INTO #BillITems
VALUES(1,10)    
INSERT INTO #BillITems
VALUES(2,11)    
INSERT INTO #BillITems
VALUES(3,50)    
INSERT INTO #BillITems
VALUES(4,60)    
INSERT INTO #BillITems
VALUES(5,70)    


SELECT A.ItemID
FROM (
        SELECT bi.ItemID, COUNT(*) AS CountBill
        FROM #BillItems bi
        JOIN #SubItems si ON
            bi.ItemID = si.ItemID
        GROUP BY bi.ItemID
     ) A 
        JOIN #SubItems si ON
            A.ItemID = si.ItemID
WHERE si.MasterItemID IN (SELECT ItemID FROM #BillItems)
GROUP BY A.ItemID
HAVING COUNT(*) > 1



DROP TABLE #SubItems
DROP TABLE #BillItems