【问题标题】:Fairly basic query (maybe needs subquery and or outer join)?相当基本的查询(可能需要子查询和/或外连接)?
【发布时间】:2020-02-22 04:15:11
【问题描述】:

我不确定为什么我的大脑现在无法处理这个问题,但看起来这将是一个很容易编写的查询。

我有 2 张桌子:

- Orders
(pk)orderID
customername
orderDate
- OrderDetails
(pk)detailsID
orderID
productName

因此,当下新订单时,订单中会添加一行客户信息,并在 orderDetails 表中为订购的每个产品添加一行。

想象一下这两种布局:

ORDERS
orderID     customerName    orderDate
1           John Smith       2/21/2020
2           Bill Adams       2/21/2020
3           Susan Conrad     2/21/2020
4           Amy Fetcher      2/21/2020
ORDERDETAILS
detailsID  orderID  productName
1             1      pillow
2             1      mattress
3             2      pillow
4             3      sheets
5             3      headboard
6             3      mattress
7             4      pillow
8             4      framed art
9             4      decals
10            4      plant stand

在我的查询中,我想从日期 = 今天的订单中选择所有。我加入 ORDERDETAILS 表是因为我想知道我在结果中售出枕头的任何时间。

我只想在结果中显示每个订单的 1 行,例如,在 orderID 1 中,他们订购了枕头和床垫。在该行的 productName 下的结果中,我希望它显示枕头。

如果有人没有订购枕头,我今天仍然需要为他们的订单显示该行,并且在 productName 下,如果不是枕头,我不在乎它显示什么。它不能显示任何内容或他们订购的其他产品名称之一。

我知道这行不通:

SELECT ORDERS.*, ORDERDETAILS.*
FROM ORDERS INNER JOIN ORDERDETAILS ON ORDERS.orderID = ORDERDETAILS.orderID
WHERE productName = "pillow"

我不确定我是否需要子查询或某种外部左连接可能两者都需要?

非常感谢任何帮助,谢谢!

【问题讨论】:

  • 我刚刚发现了 SQL 案例语句:mode.com/sql-tutorial/sql-case,如果得到正确的结果,这对我来说可能是最简单的方法,现在就试试吧!
  • 嗯,这是一个很酷的功能,但不是我想要的

标签: sql vbscript


【解决方案1】:

你可以这样做

select detailsID, a.orderID, productName, customerName, orderDate from 
(
    select detailsID, orderID, productName from ORDERDETAILS where productName = 'pillow'
    union 
    select detailsID, orderID, productName from
    (
    select detailsID, orderID, productName, rank()over(partition by orderID order by detailsID) as _Rank from ORDERDETAILS  
    )a where _Rank = 1
    and orderID not in (select orderID from ORDERDETAILS where productName = 'pillow')
) a
inner join Orders b on a.orderID = b.orderID

输出:

detailsID   orderID productName customerName    orderDate
1   1   pillow  John Smith  2/21/2020
3   2   pillow  Bill Adams  2/21/2020
4   3   sheets  Susan Conrad    2/21/2020
7   4   pillow  Amy Fetcher 2/21/2020

【讨论】:

    【解决方案2】:

    由于您只对 一些 订单详细信息感兴趣,而对 所有 标题感兴趣,因此您需要 LEFT JOIN。由于您只想过滤来自ORDERDETAILS 的结果,因此您需要将过滤条件放在JOIN 中,而不是放在同样适用于ORDERS 表的WHERE 子句中。

    SELECT ORDERS.*, ORDERDETAILS.*
    FROM 
      ORDERS 
    LEFT JOIN ORDERDETAILS 
      ON ORDERS.orderID = ORDERDETAILS.orderID
      AND productName = "pillow"
    

    这应该可以让你大部分时间到达那里。如果每个订单有可能包含多个详细记录,其中包括 pillow,那么您将需要对详细信息表使用子查询,以进一步精简到您感兴趣的信息。并且在那时,我会将过滤器移到子查询中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-04-16
      • 2011-02-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-17
      • 2016-06-04
      • 2023-03-29
      相关资源
      最近更新 更多