【问题标题】:2 orders with in 10 days in SQLSQL 10 天内有 2 个订单
【发布时间】:2020-04-15 09:22:04
【问题描述】:

需要SQL查询提取所有客户编号 在哪里 如果客户在 10 天内(45 天内)订购了至少 2 个订单

例如:在 01-01-2020 到 15-02-2020 之间,客户 1001 在 15-01-2020 和 20-01-2020 有订单,所以我们需要提取这条记录。

以上所有要求都在一个表中,custno、orderno、orderdate 输入表

ORDERNO CUSTID ORDERDT
A1001 1001 20200115
A1002 1001 20200120
A1003 1001 20200130
A1004 1004 20200102
A1005 1004 20200130
A1006 1006 20200125
A1007 1006 20200127
A1008 1006 20200130

输出

预期结果

ORDERNO CUSTID ORDERDT
A1001 1001 20200115
A1002 1001 20200120
A1006 1006 20200125
A1007 1006 20200227
A1008 1006 20200130

【问题讨论】:

  • 请提供样本数据和预期结果。还需要一个数据库标签(日期函数是高度特定于供应商的):mysql、oracle、sql-server...?
  • 看看LeadLag 分析函数(例如,获取优先顺序)

标签: sql


【解决方案1】:

你可以使用EXISTS:

with cte as (
  select orderno, custid,
    cast(cast(orderdt as char(8)) as datetime) orderdt
  from orders
)
select c1.* from cte c1
where c1.orderdt between '20200101' and '20200215'
and exists (
  select 1 from cte c2
  where c2.custid = c1.custid and c2.orderdt <> c1.orderdt
    and c2.orderdt between '20200101' and '20200215'
    and abs(datediff(day, c1.orderdt, c2.orderdt)) <= 10
)

此查询使用 SQL Server 函数 DATEDIFF(),但您可以使用适用于您的数据库的类似函数。
请参阅demo
结果:

> ORDERNO | CUSTID | ORDERDT   
> :------ | -----: | :---------
> A1001   |   1001 | 2020-01-15
> A1002   |   1001 | 2020-01-20
> A1003   |   1001 | 2020-01-30
> A1006   |   1006 | 2020-01-25
> A1007   |   1006 | 2020-01-27
> A1008   |   1006 | 2020-01-30

【讨论】:

  • 您好,先生,抱歉回复晚了。感谢您提供上述解决方案,但我遇到以下错误错误:“将表达式转换为数据类型日期时间的算术溢出错误”我的字段是日期字段声明为 - (orderdt decimal(9,0), not null)
  • 您的栏目不是日期。您应该将其声明为日期。
  • 对不起,我没听明白。我的错。我在声明日期字段的地方使用的表,其声明为 - orderdt decimal(9,0),不为空。注意:我正在获取数据的实时表。此外,我们表中的 orderno 和 custid 仅是 char。真的很抱歉我现在要强调。此表单的新手。
  • 先生,非常感谢。有效。请不要介意。即将到来的数据是正确的,但它也带有额外的数据,我没有通知你。即使客户在一天内订购了超过 2 个订单,查询也会提取数据,但我们不希望这样。我们需要在 10 天内在不同日期订购的客户。抱歉,对此要求的最后帮助。
  • 先生,谢谢一百万。衷心感谢您的耐心帮助。它按预期工作。
【解决方案2】:

您可以使用lead()

SELECT t.*
FROM (SELECT t.*,
             DATEDIFF(DAY, ORDERDT, LEAD(ORDERDT) OVER (PARTITION BY CUSTID ORDER BY ORDERNO)) AS DAYS_DIFF
      FROM table t
     ) t
WHERE DAYS_DIFF <= 10;

【讨论】:

  • 您好,先生,抱歉回复晚了。感谢您提供上述解决方案,但我遇到以下错误错误:“将表达式转换为数据类型日期时间的算术溢出错误”我的字段是日期字段声明为 - (orderdt decimal(9,0), not null)
【解决方案3】:

如果你想要原始行,你可以同时使用lag()lead()

select t.*
from (select t.*
             lag(orderdt) over (partition by custid order by orderdt) as prev_orderdt,
             lead(orderdt) over (partition by custid order by orderdt) as next_orderdt
      from t
     ) t
where prev_orderdt > dateadd(day, -10, orderdt) or
      next_orderdt < dateadd(day, 10, orderdt)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-24
    • 1970-01-01
    • 2015-06-19
    • 1970-01-01
    • 2021-02-06
    相关资源
    最近更新 更多