基于多个表和条件进行过滤的SQL命令

时间:2019-11-03 00:40:13

标签: sql sql-server-2017

我正在尝试学习sql,它使我发疯。我似乎无法掌握实现所需输出的正确语法。我正在观看有关udemy的视频并阅读了有关尝试自学的基本sql的书籍,但似乎它们都不足以帮助我弥合我似乎无法克服的差距。

我对SELECT,FROM,WHEN命令的基础知识有很好的了解。我似乎在了解使用聚合函数的知识,但我绝不是专家。

我有两个表“ Orders”和“ OrderDet”。 “订单”包含CustomerName和OrderNo,而OrderDet包含其他所有内容,例如PartNo,DateFinished,OrderNo等。

我遇到这样的情况,我可以让多个客户订购相同的部件号。我想显示所有客户下的所有最新订单。

例如

SELECT Orders.CustDesc, OrderDet.OrderNo, OrderDet.PartNo, OrderDet.DateFinished
FROM Orders
JOIN OrderDet ON Orders.OrderNo = OrderDet.OrderNo
ORDER BY OrderDet.PartNo, OrderDet.DateFinished

此查询返回:

Customer   OrderNo   PartNo     Date Finished
--------------------------------------------------------
Cust 1      5032    12345678-1  NULL
Cust 2     10032    12345678-1  2019-06-05 14:54:25.853
Cust 2      1048    12345678-1  2019-07-08 00:00:00.000
Cust 1      5028    12345678-1  2019-09-30 11:45:45.960
Cust 1      5029    12345678-1  2019-09-30 12:49:35.713
Cust 1      5030    12345678-1  2019-09-30 13:04:57.333
Cust 1      5031    12345678-1  2019-10-10 13:58:22.653

我仍在学习何时以及如何使用聚合函数,但是似乎无法完全理解该概念。我尝试在“日期”列上使用MAX,并在“客户和零件号”上使用GROUP,但是除非删除订单号,否则输出永远不会折叠到我想要的值。

例如我用过:

SELECT Orders.CustDesc, OrderDet.PartNo, MAX(OrderDet.DateFinished)
FROM Orders
JOIN OrderDet ON Orders.OrderNo = OrderDet.OrderNo
GROUP BY Orders.CustDesc, OrderDet.PartNo
ORDER BY OrderDet.PartNo

从SELECT中删除OrderDet.OrderNo,并从Order By中删除OrderDet.DateFinished。 这将返回我想要的行输出,但是缺少我想要的所有列。

Customer  PartNo     Date Finished
--------------------------------------------
Cust 2  12345678-1  2019-07-08 00:00:00.000
Cust 1  12345678-1  2019-10-10 13:58:22.653

一旦我尝试将OrderNo重新添加到混合中,我将获得与第一个相同的输出。我想我理解为什么会这样,因为所有的OrderNo都是唯一的并且无法分组,但是我无法掌握如何克服这个问题。

我理解这是一个基本的SQL命令,但是我似乎无法理解如何获取所需的输出。在此示例中,我只想根据PartNo的最后日期看到两行唯一的客户,但要显示整行的内容。不只是三列。

同样,我正在尝试学习这些内容,并且我只能阅读和重新阅读相同的基本内容,以学习这么长时间。我阅读的所有内容似乎都缺少那一刻“ AH HA”所需的信息。

也许有人可以帮助弥合这种差距?

1 个答案:

答案 0 :(得分:1)

我将您的问题解释为想要给定客户的每个订购部分的最新订单。

为此,我建议使用窗口功能:

select CustDesc, OrderNo, od.DateFinished
from (select o.custdesc, od.orderno, od.partno, od.datefinished,
             row_number() over (partition by o.custdesc, od.partno order by od.datefinished desc) as seqnum
      from Orders o join
           orderdet od
           on o.OrderNo = od.OrderNo
     ) od
where seqnum = 1;
order by od.PartNo, od.DateFinished