我必须编写一个具有以下要求的查询:
该查询应返回名为“降职”的客户的所有条目值的列表,并返回所显示的每个日期(如果可用)的该日期的最新状态详细信息。
客户表
CustomerID | CustomerName 1 | Steve 2 | John
录入表
CustomerID | EntryDate | EntryValue 1 | 5/4/2010 | 200.0 1 | 4/4/2010 | 100.0 1 | 3/4/2010 | 150.0 1 | 2/4/2010 | 170.0 2 | 5/4/2010 | 220.0
状态表
CustomerID | StatusDate | Detail 1 | 5/28/2010 | D 1 | 4/24/2010 | S 1 | 4/5/2010 | P 1 | 2/28/2010 | A
预期的输出是:
CustomerName | Date | OrderCost | Detail Steve | 5/4/2010 | 200.0 | S Steve | 4/4/2010 | 100.0 | A Steve | 3/4/2010 | 75.0 | A Steve | 3/4/2010 | 75.0 | <null>
我认为预期的输出可能是错误的,实际上应该是:
CustomerName | Date | OrderCost | Detail Steve | 5/4/2010 | 200.0 | S Steve | 4/4/2010 | 100.0 | A Steve | 3/4/2010 | 150.0 | A Steve | 2/4/2010 | 170.0 | <null>
给定要求,我不明白为什么3/4/2010日期会出现两次,而第二次会有“详细信息”。我写了以下查询:
我写了以下查询:
SELECT Customers.CustomerName, Entries.EntryDate, Entries.EntryValue, Status.Detail FROM Customers INNER JOIN Entries ON Customers.CustomerID = Entries.CustomerID LEFT OUTER JOIN Status ON Status.CustomerID = Customers.CustomersID AND Status.StatusDate <= Entries.EntryDate WHERE (Customers.CustomerName = 'Steve')
我的查询结果是这样的:
CustomerName| EntryDate | EntryValue | Detail Steve | 5/4/2010 | 200.00 | S Steve | 5/4/2010 | 200.00 | P Steve | 5/4/2010 | 200.00 | A Steve | 4/4/2010 | 100.00 | A Steve | 3/4/2010 | 150.00 | A Steve | 2/4/2010 | 170.00 | NULL
关于我在这里做错什么的任何提示吗?我不知道…
更新 我已将订单更改为输入,因此不会给我们造成太大的困扰。
由于状态表中的许多行都满足第二个JOIN条件,因此您得到的结果超出了预期(例如,有3个statusDate早于5/4,因此该日期在结果集中出现3次)。
您需要加入状态表,但只能获得一个匹配项(最新的)。这可以通过多种方式完成,AFIAK通常使用子查询。我认为您的情况相当复杂- 我使用了一个临时表。希望对您有帮助…(我目前没有数据库可以对此进行测试,希望不会有任何愚蠢的语法错误)。
DROP TABLE IF EXISTS temp; CREATE TABLE temp AS -- This temp table is basically the result set you got (SELECT c.CustomerName, e.EntryDate, e.EntryValue, s.Detail, s.StatusDate FROM Customers c INNER JOIN Entires e ON c.CustomerID = e.CustomerID LEFT OUTER JOIN Status s ON s.CustomerID = c.CustomersID AND s.StatusDate <= e.EntryDate WHERE (c.CustomerName = 'Steve') ); SELECT t.CustomerName, t.EntryDate, t.EntryValue, t.Detail FROM temp t WHERE t.StatusDate = (SELECT MAX(t2.StatusDate) FROM temp t2 WHERE t2.EntryDate = t.EntryDate);
为了避免创建临时表,我相信这会起作用(请尝试并让我知道!)
SELECT t.CustomerName, t.EntryDate, t.EntryValue, t.Detail FROM (SELECT c.CustomerName, e.EntryDate, e.EntryValue, s.Detail, s.StatusDate FROM Customers c INNER JOIN Entries e ON c.CustomerID = e.CustomerID LEFT OUTER JOIN Status s ON s.CustomerID = c.CustomersID AND s.StatusDate <= e.EntryDate WHERE c.CustomerName = 'Steve') AS t WHERE t.StatusDate = (SELECT MAX(t2.StatusDate) FROM temp t2 WHERE t2.EntryDate = t.EntryDate);