Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL:如何根据订单详细信息提取特定订单?_Sql_Sql Server_Sql Server 2008 - Fatal编程技术网

SQL:如何根据订单详细信息提取特定订单?

SQL:如何根据订单详细信息提取特定订单?,sql,sql-server,sql-server-2008,Sql,Sql Server,Sql Server 2008,我有四个表,即客户、订单、订单详情和产品 客户表 cId cName 1 James 2 Adam 3 Ed 订单表 oId cId 1 1 2 2 3 3 OrderDetails表 oId odId pId Quantity 1 1 1 50 1 2 2 45 2 3 2 52 3 4 1 44 产品表 pId PName 1 Apple 2 Orange 我要一份从

我有四个表,即客户、订单、订单详情和产品

客户表

cId cName
1   James
2   Adam
3   Ed
订单表

oId cId
1   1
2   2
3   3
OrderDetails表

oId odId    pId Quantity
1   1       1   50
1   2       2   45
2   3       2   52
3   4       1   44
产品表

pId PName
1   Apple
2   Orange
我要一份从未点过橘子的顾客名单。我能够提取订单详细信息中没有橙子的客户的记录。但在其中一个案例中,詹姆斯同时点了苹果和桔子。因此,这个问题不应该牵扯到詹姆斯。我可以通过一个更大的查询来实现这一点。但我想用一个较小的查询来说明我遗漏了什么

SQL


使用
不存在

 SELECT *
 FROM Customers c
 WHERE NOT EXISTS (
       SELECT 1 FROM orders o
       JOIN orderDetails od ON o.oId = od.oId
       JOIN products p ON od.pId = p.pId 
       WHERE p.pName = 'oranges' AND c.cId = o.cId
 )

使用
不存在

 SELECT *
 FROM Customers c
 WHERE NOT EXISTS (
       SELECT 1 FROM orders o
       JOIN orderDetails od ON o.oId = od.oId
       JOIN products p ON od.pId = p.pId 
       WHERE p.pName = 'oranges' AND c.cId = o.cId
 )

我会使用
不存在

with has_oranges as (
      select o.*
      from orders o join
           orderlines ol
           on o.oid = ol.oid
      where ol.pid = 2
     )
select c.*
from customers c
where not exists (select 1
                  from has_oranges ho
                  where ho.cid = c.cid
                 );
如果您想要客户信息,我看不出
oid
与任何事情都有什么关系

注:

  • CTE决定谁有橙子
  • 您不需要
    products
    表,因为您使用的是
    pid

我会使用不存在的
来执行此操作:

with has_oranges as (
      select o.*
      from orders o join
           orderlines ol
           on o.oid = ol.oid
      where ol.pid = 2
     )
select c.*
from customers c
where not exists (select 1
                  from has_oranges ho
                  where ho.cid = c.cid
                 );
如果您想要客户信息,我看不出
oid
与任何事情都有什么关系

注:

  • CTE决定谁有橙子
  • 您不需要
    products
    表,因为您使用的是
    pid
这将退回未订购橙子的客户。 这是SQLFIDLE链接:

这将退回未订购橙子的客户。
这是sqlfiddle链接:

您想要的是所有从未订购过橙子的客户。因此,选择订购橙子的所有客户ID,并仅显示不在此数据集中的客户

select * 
from customers c
where cid not in 
(
  select cid
  from orderdetails
  where pid = (select pid from products where pname = 'Orange'
);

您希望所有从未订购过橙子的客户。因此,选择订购橙子的所有客户ID,并仅显示不在此数据集中的客户

select * 
from customers c
where cid not in 
(
  select cid
  from orderdetails
  where pid = (select pid from products where pname = 'Orange'
);

SQLServer2008引入了EXCEPT和INTERSECT关键字来执行这类操作。我倾向于发现查询比使用CTE时更清晰

您可以通过在查询的后半部分连接到Customer表,将名称添加到结果集中:

select c.cId, c.cName
from Customer c
except
select o.cId, c.cName
from Orders o
join OrderDetail od on o.oId = od.oId
join Customer c on c.cId = o.cId
and od.pId = 2

cId         cName
----------- --------------------
3           Ed

SQLServer2008引入了EXCEPT和INTERSECT关键字来执行这类操作。我倾向于发现查询比使用CTE时更清晰

您可以通过在查询的后半部分连接到Customer表,将名称添加到结果集中:

select c.cId, c.cName
from Customer c
except
select o.cId, c.cName
from Orders o
join OrderDetail od on o.oId = od.oId
join Customer c on c.cId = o.cId
and od.pId = 2

cId         cName
----------- --------------------
3           Ed

我们必须排除那些使用橙色的用户。所以在下面的查询中,我使用了子查询

Select C.Cname,OH.oid,PM.Pname,OD.Quantity from Customers C 
inner join OrderHeader OH ON C.cid=OH.Cid
inner join OrderDetails OD on oh.oid=od.oid
inner join ProductMast PM on PM.pid=OD.pid where OH.oid not in (select oid 
from OrderDetails  where pid = 2)

我们必须排除那些使用橙色的用户。所以在下面的查询中,我使用了子查询

Select C.Cname,OH.oid,PM.Pname,OD.Quantity from Customers C 
inner join OrderHeader OH ON C.cid=OH.Cid
inner join OrderDetails OD on oh.oid=od.oid
inner join ProductMast PM on PM.pid=OD.pid where OH.oid not in (select oid 
from OrderDetails  where pid = 2)

WHERE子句使第二个左连接作为常规内部连接。WHERE子句使第二个左连接作为常规内部连接。我收到一个错误。我认为这里显式连接优先于隐式连接。您的SQL正在提取customers表的所有记录。(相当于“从客户中选择*”)@madhukar my query相当于您接受的Gordon Linoff解决方案。您可能没有订购“橙子”的客户。将
p.pName='oranges'
替换为
ol.pid=2
,是否正常?是。如果我将名称替换为Id,它将起作用。Thanks@Madhukar好的,好的。我有一个错误。我认为这里显式连接优先于隐式连接。您的SQL正在提取customers表的所有记录。(相当于“从客户中选择*”)@madhukar my query相当于您接受的Gordon Linoff解决方案。您可能没有订购“橙子”的客户。将
p.pName='oranges'
替换为
ol.pid=2
,是否正常?是。如果我将名称替换为Id,它将起作用。Thanks@Madhukar好的,很好。工作!谢谢你的工作!非常感谢。