SQL不存在问题

时间:2010-11-25 18:34:53

标签: sql exists

在查询中处理not exists子句时遇到一些麻烦。

我有三张桌子:

膳食

no_meal integer
type_meal varchar(255)

消耗

no_meal integer
designation varchar(255)
quantity integer

食品

designation varchar(255)
quantity integer
type varchar(255)

食物中的数量是储存的数量,消耗的数量是消耗的数量,因此,它们会有所不同,因此自然的内部连接不会削减它。

  • 食物类型可以是'喝''肉''鱼'等。
  • 用餐类型可以是'早餐''午餐''晚餐'

我想要一个查询,告诉我所有类型的膳食中已经消耗的饮料。

我一直在切换和测试代码,但无法做到正确。目前我正在尝试这个:

SELECT Consumed.designation
FROM Consumed
WHERE NOT EXISTS

(SELECT type_meal
 FROM Consumed, Food, Meal
 WHERE Consumed.designation = Food.designation
 AND Consumed.no_meal = Meal.no_meal
 AND type = 'Drink'
 ORDER BY Food.designation)

EXCEPT

(SELECT type_meal
 FROM Meal);

我该怎么办呢?

感谢您提供意见。

修改

我会添加一些数据以使其更清晰。

食品

Steak   100    Meat
Water   200    Drink
Coca cola    300   Drink

膳食

0001     Breakfast
0002     Lunch
0003     Dinner

消耗

0001     Water       50
0002     Steak       20
0001     Coca cola   20
0003     Water        5
0002     Water       15

现在,我想知道每顿饭都喝了哪种饮料,这只会给水。

希望我清楚一些关于这个问题的想法

5 个答案:

答案 0 :(得分:1)

现在我明白了你想要的......

SELECT designation
FROM Food
WHERE designation IN (
    SELECT designation 
    FROM Consumed
    GROUP BY designation
    HAVING Count(DISTINCT no_meal) = (
        SELECT Count(*) FROM Meal
    )
)
WHERE type = 'Drink'

答案 1 :(得分:1)

  

我想要一个查询,告诉我所有类型的膳食中已经消耗的饮料。

您的编辑确实清楚了。请注意,如果Designation, Type中的Consumed组合不是唯一的,但我猜它会是。

SELECT  
    c.Designation
FROM
    (SELECT  
         c.Designation
     FROM    
         Consumed c
     INNER JOIN 
         Meal m ON m.no_meal = c.no_meal
     GROUP BY
         c.Designation
     HAVING  
         COUNT(*) = (SELECT COUNT(*) FROM Meal)) c
INNER JOIN 
    Food f ON f.Designation = c.Designation
WHERE
    f.Type = 'Drink'                  

答案 2 :(得分:1)

稍微扭动一下你的想法,并考虑双重否定......

  

我想要在所有类型的饭菜中消费的饮料。

您希望所有饮品类型的饮品都不属于餐饮类型:

select distinct f.designation 
from food f 
where 
  type = 'Drink' and 
  not exists (
    select * 
    from meal m1
    where not exists (
      select *  
      from meal m2
      join consumed c on c.no_meal = m2.no_meal
      where 
        m1.no_meal = m2.no_meal and
        c.designation = f.designation
    )
  ) 

这称为relational division

答案 3 :(得分:0)

select *
from food f inner join
     consumed c_1 on c_1.designation = f.designation
where type='Drink' and
not exists -- to filter out drinks that are not a part of all the meals
(select 1 
from consumed c_2 inner join
     meal m_1 on m_1.no_meal = c_2.no_meal
where c_1.no_meal = c2.no_meal and
      c_1.designation = c2.designation and
 not exists (select 1 
               from meal m_2
              where m_1.no_meal = m_2.no_meal))

答案 4 :(得分:0)

我想要一个查询,告诉我所有类型的膳食中已经消耗的饮料。

以下是您建议的模型结构和插入内容:

USE SqlTests
GO

CREATE TABLE Meal (
    no_meal int
    , type_meal nvarchar(255)
)
GO

insert into Meal (no_meal, type_meal)
    values (1, N'Breakfast')
GO
insert into Meal (no_meal, type_meal)
    values(2, N'Lunch')
GO
insert into Meal (no_meal, type_meal)
    values(3, N'Dinner')
GO

CREATE TABLE Consumed (
    no_meal int
    , designation nvarchar(255)
    , quantity int
)
GO

insert into Consumed (no_meal, designation, quantity)
    values (1, N'Water', 50)
GO
insert into Consumed (no_meal, designation, quantity)
    values (2, N'Steak', 20)
GO
insert into Consumed (no_meal, designation, quantity)
    values (1, N'Coca cola', 20)
GO
insert into Consumed (no_meal, designation, quantity)
    values(3, N'Water', 5)
GO
insert into Consumed (no_meal, designation, quantity)
    values(2, N'Water', 15)
GO

CREATE TABLE Food (
    designation nvarchar(255)
    , quantity int
    , [type] nvarchar(255)
)
GO

insert into Food (designation, quantity, [type])
    values (N'Water', 200, N'Drink')
GO
insert into Food (designation, quantity, [type])
    values (N'Steak', 100, N'Meat')
GO
insert into Food (designation, quantity, [type])
    values (N'Coca cola', 200, N'Drink')
GO

然后,选择建议的SELECT

select c.designation
    from Consumed c
        inner join Meal m on m.no_meal = c.no_meal
        inner join Food f on f.designation = c.designation and f.[type] LIKE N'Drink'
    group by c.designation 
        having COUNT(c.designation) = (select COUNT(type_meal) from Meal)

返回(至少在我的数据库引擎(SQL Server Express 2005)

上)

Water

我的信息数据是否正确?