#sql #sql-server #tsql
#sql #sql-сервер #tsql
Вопрос:
У меня есть таблица заказов, в которой заказы размещаются каждый четверг. Соответственно, с каждым заказом связано fiscal_week_number
от 1 до 52.
Каждый заказ группируется в пакеты, где один заказ может содержать несколько транзакций, каждая из которых оплачивается за отдельную неделю. Например, order_number
0001 выставил счет за fiscal_week_numbers
4, 5, 6, 7 и имел transaction_numbers
100000001, 100000002, 100000003, 100000004. Предположим, что transaction_numbers не являются последовательными и случайными.
Некоторые заказы выставляются каждую неделю, некоторые — каждые две недели, некоторые — каждые 3 недели и т.д. Как я могу запросить таблицу, чтобы показывать только заказы, которые выставляются каждые X недель?
Например, я хотел бы узнать, сколько заказов (то есть различных order_ids
) выставляется каждые 6 недель, но я не могу определить SQL.
Например, скажем, я хотел захватить только заказы, которые выполняются каждые три недели, из следующего набора данных. Я ожидал бы получить только заказ 00003
. На самом деле не имеет значения, есть ли все данные заказа или только идентификатор.
|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 |
-------- ----------------- --------------
Комментарии:
1. Я удалил несовместимые теги базы данных. Пожалуйста, помечайте только ту базу данных, которую вы действительно используете.
2. Ваши данные и ваше объяснение не совпадают, что затрудняет понимание того, чего вы действительно хотите. Пожалуйста, покажите нам результат, который вы хотите для своих выборочных данных.
3. @GMB добавил еще несколько пояснений.
4. Существует ли когда-либо 53-я финансовая неделя? (52 * 7 = 364, что приводит к дополнительной неделе каждые несколько лет. И високосные дни также влияют на сочетание.) Могут ли быть данные более чем за один год?
5. @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);
Обратите внимание, что это не гарантирует, что они выставляются каждые три недели (мы могли бы добавить дополнительную проверку для этого. Но это будут заказы в одном и том же платежном цикле.
Комментарии:
1. Это действительно элегантное решение… Как бы вы добавили эту проверку для последовательных циклов выставления счетов?
2. Заказ, который отправляется в течение финансовых недель
52
и3
завершается неудачно:52 % 3 = 1
,3 % 3 = 0
. Поскольку52
количество пересечений не превышает3
количества лет, это проблема. (Ожидание подтверждения OP, что могут существовать данные за несколько лет. Или 53 недели время от времени.)3. @qotsa42 . . . Для последовательных циклов выставления счетов я бы просто использовал
count(*) = max(fiscal_week_no) - min(fiscal_week_no)
.
Ответ №2:
Я думаю, что этот код тоже может быть полезен. Это вернет order_id для любого количества транзакций, установленного в переменной @bill_freq. Я использовал составленные данные.
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