SQL:如何只选择每三周发生一次的订单?

Posted

技术标签:

【中文标题】SQL:如何只选择每三周发生一次的订单?【英文标题】:SQL: How to select ONLY orders that occur every three weeks? 【发布时间】:2020-08-28 16:28:50 【问题描述】:

我有一个订单表,每个星期四都会下订单。因此,每个订单都有 1 到 52 之间的 fiscal_week_number 与之关联。

每个订单都按批次分组,其中一个订单可以包含多笔交易,每笔交易都在单独的一周内计费。例如,order_number0001 在fiscal_week_numbers 4、5、6、7 上计费,并有transaction_numbers100000001、100000002、100000003、100000004。假设 transaction_numbers 是非连续的和随机的。

有些订单每周结算一次,有些每两周结算一次,有些每 3 周结算一次,等等。如何查询表以仅显示每 X 周结算一次的订单?

例如,我想知道每 6 周有多少订单(即不同的order_ids)计费,但我不知道 SQL。

例如,假设我只想从以下数据集中获取每三周发生一次的订单。我希望只收到订单00003。是否所有订单数据都在那里或只有 id 并不重要。

|00003   |319229           |20            |
|00003   |319230           |23            |
|00003   |238678           |26            |
|00003   |319231           |29            |
|00003   |190659           |32            |
+--------+-----------------+--------------+
|order_id|transactionnumber|fiscal_week_no|
+--------+-----------------+--------------+
|00001   |278100           |1             |
|00001   |278101           |2             |
|00001   |278102           |3             |
|00001   |278103           |4             |
|00001   |278104           |5             |
|00002   |319224           |10            |
|00002   |319225           |12            |
|00002   |319226           |14            |
|00002   |319227           |16            |
|00002   |319228           |18            |
|00003   |319229           |20            |
|00003   |319230           |23            |
|00003   |238678           |26            |
|00003   |319231           |29            |
|00003   |190659           |32            |
|00004   |319232           |26            |
|00004   |190660           |30            |
|00004   |190661           |34            |
|00004   |190662           |38            |
|00004   |319233           |42            |
|00005   |190663           |40            |
|00005   |319234           |45            |
|00005   |190664           |50            |
|00005   |190665           |3             |
|00005   |190666           |8             |
|00006   |319235           |10            |
|00006   |190667           |16            |
|00006   |190668           |22            |
|00006   |319236           |28            |
|00006   |190669           |34            |
|00007   |319237           |20            |
|00007   |190670           |28            |
|00007   |190671           |36            |
|00007   |319238           |44            |
|00007   |190672           |52            |
|00007   |190673           |8             |
+--------+-----------------+--------------+

【问题讨论】:

我删除了不一致的数据库标签。请仅使用您真正使用的数据库进行标记。 你的数据和你的解释不匹配,这让你更难理解你真正想要什么。请向我们展示您想要的样本数据结果。 @GMB 添加了更多解释。 是否有第 53 个财政周? (52 * 7 = 364 导致每隔几年增加一周。闰日也会影响组合。)是否有超过一年的数据? @HABO 是的,有超过一年的数据,令我惊讶的是,许多订单的会计周为 53。 【参考方案1】:

根据您的描述,如果fiscal_week_no 列始终相同,以 3 为模,则订单每三周计费一次。因此,一种方法是:

select order_id
from t
group by order_id
having min(fiscal_week_no % 3) = max(fiscal_week_no % 3);

请注意,这并不能保证每三周对其进行一次计费(我们可以为此添加额外检查。但这些订单将是同一计费周期内的订单。

【讨论】:

这是一个非常优雅的解决方案...您将如何为连续的账单周期添加该检查? 在财政周523 发货的订单失败:52 % 3 = 13 % 3 = 0。因为52 不是3 的倍数,所以跨年是个问题。 (等待 OP 确认可能存在多年的数据。或者时不时地等待第 53 周。) @qotsa42 。 . .对于连续的账单周期,我只会使用count(*) = max(fiscal_week_no) - min(fiscal_week_no)【参考方案2】:

我认为这段代码也很有用。这将返回 @bill_freq 变量中设置的任何交易数量的 order_id。我用了编造的数据。

declare @bill_freq          int=2;

;with rn_cte(order_id, transactionnumber, fiscal_week_no, wk_rn) as (
    select *, row_number() over (partition by order_id order by order_id, fiscal_week_no) wk_rn
    from (values ('00001', 278100, 1),
                 ('00001', 278101, 2),
                 ('00002', 278102, 3),
                 ('00002', 278103, 4),
                 ('00003', 278104, 5),
                 ('00004', 278105, 7),
                 ('00004', 278106, 9)) v(order_id, transactionnumber, fiscal_week_no))
select order_id
from rn_cte
group by order_id
having max(wk_rn)=@bill_freq;

结果

order_id
00001
00002
00004

【讨论】:

以上是关于SQL:如何只选择每三周发生一次的订单?的主要内容,如果未能解决你的问题,请参考以下文章

如何在outlook中发送定期的提醒邮件?例如每月一次或者每两周一次的邮件?

iOS 11-每 x 分钟重复一次的用户本地通知

如何防止气流回填 dag 运行?

如何防止气流回填dag运行?

如何制作每15分钟运行一次的功能?

如何每 100 毫秒执行不超过一次的某些类方法?