2016-11-08 88 views
0

我已经简化了一个表为例过滤掉行

tray| food 
-------+------- 
    1 | fruit 
    2 | veg 
    2 | fruit 
    2 | meat 
    3 | meat 
    4 | bread 

我想找到每个水果,是只包含该类食品的托盘的数量。所以输出应该是这样的:

food| count 
-------+------- 
fruit | 1 
    veg | 0 
    meat | 1 
bread | 1 

我试着写一个查询:

SELECT fruit, COUNT(*) 
FROM Inventory 
WHERE NOT EXISTS (SELECT * 
        FROM Inventory I 
        WHERE I.tray = tray AND I.fruit<>fruit) 
GROUP BY fruit; 

但是返回的表是不正确的,它看起来像我的子查询是错误的,但它使逻辑意义,我。

food | count 
-------+------- 
fruit |  2 
veg |  1 
bread |  1 
meat |  2 

它看起来像托盘2计数一次的水果,肉类和蔬菜,当它不应该。但是,不应该由我的NOT EXISTS子查询排除吗?我该如何解决?

+0

如果我在读你的问题吧,你想按盘数,然后检查'HAVING COUNT(*)= 1'。 – jpmc26

+0

无关,但是:您需要完全限定子查询中的所有列名:'where i.tray = inventory.tray' –

回答

0

聪明的小问题。这里是一个解决方案:

select f.food, count(t.tray) 
from (select distinct food from t 
    ) f left join 
    (select t.tray, min(food) as minfood, max(food) as maxfood 
     from tray t 
     group by tray 
    ) t 
    on f.food = t.minfood and f.food = t.maxfood 
group by f.food; 

获得零的计数显示的查询,其中left joingroup by将是有益的。

0
select i1.food, 
     count(ft.tray) 
from inventory i1 
    left join (
    select i1.tray, 
      count(distinct i1.food) as num_food 
    from inventory i1 
    group by i1.tray 
) ft on i1.tray = ft.tray and num_food = 1 
group by i1.food; 

内部查询(ft)计算每个托盘中不同食物的数量。外部(主要)查询计算仅包含单一类型食物的那些托盘的每个食物托盘的数量。

在线例如:http://rextester.com/PUN27611

+0

我试过了您的查询,但我收到错误消息说列i1.food不存在 – tenkii

+0

@tenkii那么在你的问题中,你声称你有一个专栏'食物',然后你在SQL示例中使用'fruit' - 这是哪一个? “inventory”的'create table'语句是什么?我在我的在线示例 –

+0

中使用了'食物',对不起,决赛桌假设是水果,我把它写在我的例子中。在我设法修复原始查询时,我会再次尝试您的查询。 – tenkii