0

我有客户、工作、订单和日期作为列。每个工作客户可以有多个订单,当然在特定日期范围内可以有多个工作。
我要做的是弄清楚在某个日期范围内有多少“新”订单。意思是,如果一个作业有 5 个订单,它应该只返回 1 个订单。这是一个简短的数据库表示例,所需的结果,以及到目前为止我一直在尝试使用的查询。

+-------+-------+---------+------------+
| CusID | JobID | OrderNo |  OrderDate |
+-------+-------+---------+------------+
|   1   |   10  |    25   | 2021-12-22 |
|   1   |   10  |    26   | 2022-02-09 |
|   3   |   5   |    28   | 2022-01-10 |
|   3   |   6   |    29   | 2022-01-11 |
+-------+-------+---------+------------+

有 4 行订单及其相关联JobID。查询应该返回 2 行,因为订单 25 和订单 26 都与JobID10 相关联,只有 1 可以算作“新”,而OrderNo25 不在外部查询日期范围内。
这是我尝试使用的查询,根据日期是>=一年的第一天。我希望能够使用OrderDate来自外部查询的,与OrderDate来自内部查询的比较。如果 a小于当前行JobID,则 order 不是新的,应该返回,从而使内部查询为 false 并过滤掉该行。OrderDateOrderDateJobID

SELECT * FROM orders
WHERE OrderDate >= '2022-01-01' 
AND JobID NOT IN 
(SELECT JobID FROM orders WHERE inner.OrderDate < outer.OrderDate)

预期结果

|   3   |   5   |    28   | 2022-01-10 |
|   3   |   6   |    29   | 2022-01-11 |
4

2 回答 2

0

您的查询正朝着正确的方向前进,您只需将别名应用于外部表,以便它是唯一可识别的 -

SELECT *
FROM orders `outer`
WHERE OrderDate >= '2022-01-01'
AND JobID NOT IN
    (SELECT JobID FROM orders WHERE OrderDate < `outer`.OrderDate);

根据您的时间范围内包含的行数以及每个作业的平均订单数,您可能需要先聚合 -

SELECT *
FROM (
    SELECT JobID, MIN(OrderDate) AS MinOrderDate
    FROM orders
    WHERE OrderDate >= '2022-01-01'
    GROUP BY JobID
) o
WHERE JobID NOT IN
    (SELECT JobID FROM orders WHERE OrderDate < o.MinOrderDate);

假设一项工作可能在一个日期有多个订单,您可能需要考虑使用 OrderNo 而不是 OrderDate 进行比较 -

SELECT *
FROM orders `outer`
WHERE OrderDate >= '2022-01-01'
AND JobID NOT IN
    (SELECT JobID FROM orders WHERE OrderNo < `outer`.OrderNo);
于 2022-02-27T11:07:40.050 回答
0

用于row_number对每个作业的订单进行排名。把它放在子查询中并且只接受最新最旧的?每项工作的订单。

select custid, jobid, orderNo, orderDate
from (
  select
    *,
    row_number() over ( partition by jobid order by orderDate asc ) as oldest
  from orders
) a
where a.oldest = 1
  and orderDate >= '2022-01-01'

示范

于 2022-02-27T01:33:38.257 回答