选择购买了一种特定产品的客户

时间:2019-04-22 16:25:55

标签: sql sql-server

我们有两个表:

  1. 客户:

enter image description here

  1. 产品:

enter image description here

目标是选择购买牛奶 AND 且未购买面包的客户的[Id]和[CustomerName]。在这种情况下,正确的查询应返回ID为2(Ann)的客户。

我想到的(显然是错误的)查询是:

select CustomerName from dbo.Customers
where Id in 
(
  select CustomerId from dbo.Products
  where ProductName = 'Milk' and ProductName != 'Bread'
)

它将返回两个客户:1(John)和2(Ann)。 如何重写查询,使其仅返回ID为2的客户?

5 个答案:

答案 0 :(得分:3)

您可以在下面尝试查询

SELECT CustomerName 
FROM dbo.Customers c
WHERE EXISTS (
    SELECT 1
    FROM dbo.Products
    WHERE CustomerId = c.Id
        AND ProductName = 'Milk'
) AND NOT EXISTS (
    SELECT 1
    FROM dbo.Products
    WHERE CustomerId = c.Id
        AND ProductName = 'Bread'
)

答案 1 :(得分:1)

您不需要使用两个exists,只需将where子句与not exists一起使用:

select c.*
from customer c
where ProductName = 'Milk' and
      not exists (select 1 from Products p where p.CustomerId = c.id and p.ProductName = 'Bread');

答案 2 :(得分:1)

我倾向于为此使用聚合。这是一种方法:

select c.customerId
from dbo.Products p
where p.productName in ('Milk', 'Bread')
group by c.customerId
having sum(case when p.productName = 'Milk' then 1 else 0 end) > 0 and
       sum(case when p.productName = 'Bread' then 1 else 0 end) = 0 ;

如果确实需要,可以添加join以获取客户名称。

基本上,这将计算具有'Milk'的每个客户的行数。 > 0表示至少有一个。然后,它计算具有'Bread'的行数。 = 0说没有。

答案 3 :(得分:0)

SELECT P.Id ,C.Customers 
FROM Customers AS C , Product AS P
WHERE (C.Id = P.CustomerId)
AND (P.ProductName = 'Milk') 
AND NOT EXISTS (
    SELECT 1
    FROM Products
    WHERE CustomerId = C.Id
        AND ProductName = 'Bread'
)

答案 4 :(得分:0)

如果不是归一化的话,效率也不是。在这里,您去了:

router.get('/', function (req, res, next) {
  var session = req.session;
  console.log(session);
  var hash = crypto.createHmac('sha512', 'ABCD').update(session).digest('hex');
  res.cookie( 'X-XSRF-TOKEN', hash,{ maxAge: 1000 * 60 * 10, httpOnly: true });
  res.render('signup', { title: 'signup section' });
});

啊。刚刚看到它可以被认为是埃里克答案的重复。确实,使用存在可能会更快一些。

相关问题