如何创建复杂的嵌套 select 视图?

How to create a complex nested select view?

例如这是餐厅的数据库,类型 1 表示餐厅内,类型 2 表示订单,类型 3 表示餐厅外。

我想创建一个视图来查看每个 table 的总金额。总金额是指(类型 1)餐厅内时间和(类型 3)餐厅外时间之间的金额。有什么制作方法吗?

现有Table:

Table_No|Type   |Amount     |Time
1       |1      |NULL       |2015-9-17 01:40
1       |2      |5.0        |2015-9-17 01:42
2       |1      |NULL       |2015-9-17 01:43
2       |2      |4.0        |2015-9-17 01:48
1       |2      |5.5        |2015-9-17 01:51
1       |2      |4.0        |2015-9-17 01:52
1       |3      |NULL       |2015-9-17 01:53
2       |2      |3.0        |2015-9-17 01:58
2       |3      |NULL       |2015-9-17 02:00
1       |1      |NULL       |2015-9-17 02:02
1       |2      |4.5        |2015-9-17 02:05
1       |3      |NULL       |2015-9-17 02:10

预期结果:

Table_No|Count  |Total_Amount   |Time
1       |3      |14.5           |2015-9-17 01:40
2       |2      |7.0            |2015-9-17 01:43
1       |1      |4.5            |2015-9-17 02:02

这是一个复杂的查询,所以我不会 post 整个查询。您需要做的是识别每位到达的客人,这是 Table_No, Type=1, Time 的唯一组合。所以你需要这样的子查询。

SELECT Table_No, Time
FROM restaurant_table
WHERE Type = 1

对于每位客人,您需要在 table 中获取相应的订单行。即,一个或多个 type=2 行。如果当然,对于单个 table,有许多 "type-2",属于其他客户。因此,对于每个到达的客户,您还需要相同的下一个客户的到达时间 table。您可以通过将每个到达的客户与相同 table 的所有其他到达客户进行比较并为所有 Time_othter_customer > Time_current_costomer 选择 min(Time) 来解决这个问题。让我们调用上面的视图 Arrival

SELECT My.Table_No AS Table_No,
       My.Time AS Arrival_Time,
       min(Other.Time) AS Arrival_Next_Customer
FROM Arrival AS My, Arrival AS Other
WHERE My.Table_No = Other.Table_No
      AND Other.Time > My.Time
GROUP BY My.Table_No, My.Time

(注意,每个table的最后一个客户,这里不会产生结果,因为后面到达的同一个table没有其他定制。)

因此,您还需要分别为每个 table 识别最后一个客户。

SELECT Table_No, max(Time) AS Arrival_Time
FROM Arrival
GROUP BY Table_No

(注意,两个查询没有任何重叠的结果。)

现在您可以 select 每个到达客户的 "type-2" 个条目。我们将上面的视图称为 ArrivalNextArrivalLast

SELECT Arrival.Table_No,
       Arrival.Time,
       restaurant_table.Type
       restaurant_table.Amount
FROM ArrivalNext, ArrivalLast, restaurant_table
WHERE (ArrivalNext.Table_No = restaurant_table.Table_No
      AND restaurant_table.Time BETWEEN ArrivalNext.Arrival_Time AND ArrivalNext.Arrival_Next_Customer)
      OR
      (ArrivalLast.Table_No = restaurant_table.Table_No
      AND restaurant_table.Time > ArrivalLast.Arrival_Time)
      AND restaurant_table.Type = 2

连接谓词很棘手。如果在 ArrivalNext 中有一行,则订单的时间必须在客户到达时间和下一个客户到达时间(相同 table)之间,因为可能会有不同其他客户的订单也是如此。对于这种情况,我们知道 ArrivalLast 中不会有条目。另一方面,如果客户是 table 的最后一个客户,则 ArrivalNext 中没有条目,但 ArrivalLast 中没有条目,因此订购时间必须大于到达时间,因为最后一个客户到货时间戳越大的订单都属于最后一个客户。

现在您可以计算 "type-2" 个条目并计算您的订单金额。让我们调用上面的视图 Customers:

SELECT Table_No
       count(*) AS Count
       sum(Amount) AS Total_Amount
       Time
FROM Customers
WHERE Type = 2
GROUP BY Table_No, Time

当然,你现在需要把它们放在一起......(我希望我做对了;至少它应该有助于得出正确的解决方案。)