powered by simpleCommunicator - 2.0.52     © 2025 Programmizd 02
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Повторяющиеся значения в рамках одной группы
13 сообщений из 13, страница 1 из 1
Повторяющиеся значения в рамках одной группы
    #40011449
Palkin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Народ, в очередной раз прошу помощи.
Задача следующая, выявить повторные покупки у одного клиента одинаковых товаров и одинаковые покупки в целом по всем клиентам.
Например один клиент покупает масло и хлеб постоянно, нужно по чекам посмотреть сколько таких чеков, в которых у одного клиента таких связок товаров (масло + хлеб) и в целом по всем продажам, сколько связок масло+хлеб у всех клиентов.
Пример таблицы в аттаче, а так же два варианта вывода, которые должны получиться. Вариант вывода 1 - по всем клиентам, вывод 2 - в разрезе клиента.

Я пробовал с помощью lag, но при проверке обычным join - данные не верные.

SELECT articul_,
d1,
MAX(row_n) et
FROM(
SELECT articul_,
d1,
ROW_NUMBER() OVER(PARTITION BY ARTICUL_,
d1
ORDER BY date_) Row_N
FROM(
SELECT *
FROM(
SELECT *,
LAG(articul_, 1) OVER(PARTITION BY client_id,
check_num
ORDER BY articul_) AS d1
FROM table) y) E) t
GROUP BY articul_,
d1
ORDER BY et DESC;
...
Рейтинг: 0 / 0
Повторяющиеся значения в рамках одной группы
    #40011453
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Милейший, я, может быть и помог бы, но неужели ты думаешь, что кто-то будет качать твой ексель-файл, открывать его (а мне, например, для этого еще надо его на онедрайв закидывать) и руками копировать оттуда данные в сиквел? Напиши тут текстом DDL создания таблицы и инсерты с данными, тогда, очень возможно, будет тебе и помощь. :)
...
Рейтинг: 0 / 0
Повторяющиеся значения в рамках одной группы
    #40011459
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Palkin,

почитайте насчёт having, отфильтруйте те, у которых count(*) > 1. Получите тех, кто больше одного раза в сумме покапал один и тот же товар.
...
Рейтинг: 0 / 0
Повторяющиеся значения в рамках одной группы
    #40011468
Palkin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Владислав Колосов
Palkin,

почитайте насчёт having, отфильтруйте те, у которых count(*) > 1. Получите тех, кто больше одного раза в сумме покапал один и тот же товар.


Это в рамках одного товара, а мне нужны клиенты, которые покупали 2 товара одновременно в одном чеке несколько раз
...
Рейтинг: 0 / 0
Повторяющиеся значения в рамках одной группы
    #40011470
Palkin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
fkthat
Милейший, я, может быть и помог бы, но неужели ты думаешь, что кто-то будет качать твой ексель-файл, открывать его (а мне, например, для этого еще надо его на онедрайв закидывать) и руками копировать оттуда данные в сиквел? Напиши тут текстом DDL создания таблицы и инсерты с данными, тогда, очень возможно, будет тебе и помощь. :)




CREATE TABLE sales
(
client_id NVARCHAR(10) NOT NULL,
date_ DATE NOT NULL,
articul NVARCHAR(10) NOT NULL,
check_num NVARCHAR(10) NOT NULL, );

INSERT INTO sales
(client_id,
date_,
articul,
check_num)
VALUES
(
'id1', '01.01.2020', 'машинка', 'check1'),
(
'id1', '01.01.2020', 'кукла', 'check1'),
(
'id2', '03.01.2020', 'хлеб', 'check2'),
(
'id2', '03.01.2020', 'масло', 'check2'),
(
'id2', '03.01.2020', 'огурец', 'check2'),
(
'id1', '01.06.2020', 'машинка', 'check15'),
(
'id1', '01.06.2020', 'кукла', 'check15'),
(
'id2', '03.05.2020', 'хлеб', 'check4'),
(
'id2', '03.05.2020', 'масло', 'check4'),
(
'id3', '03.05.2020', 'сигареты', 'check65'),
(
'id3', '03.05.2020', 'спички', 'check65');
...
Рейтинг: 0 / 0
Повторяющиеся значения в рамках одной группы
    #40011482
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Palkin
Владислав Колосов
Palkin,

почитайте насчёт having, отфильтруйте те, у которых count(*) > 1. Получите тех, кто больше одного раза в сумме покапал один и тот же товар.


Это в рамках одного товара, а мне нужны клиенты, которые покупали 2 товара одновременно в одном чеке несколько раз


Вам уже известны пары (тройки, группки) товаров которые вы ищете, или вам также нужно найти популярные комбинации, заранее неизвестные? (Веревка, мыло)

Если первое, то присутствие пары можно представить как новый товар, и искать его.

Если второе, то задача недостаточно очерчена.
...
Рейтинг: 0 / 0
Повторяющиеся значения в рамках одной группы
    #40011490
Palkin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
НеофитSQL,

Пары неизвестны, там несколько миллионов строк.
...
Рейтинг: 0 / 0
Повторяющиеся значения в рамках одной группы
    #40011500
aleks222
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Palkin
Вариант вывода 1 - по всем клиентам, вывод 2 - в разрезе клиента.

Я пробовал с помощью lag, но при проверке обычным join - данные не верные.


Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
-- Тупо и прямолинейно - это так. Но если вспомнить азы математики... то можно быстрее.
declare @sales table
(
 rowid int identity,
 client_id NVARCHAR(10) NOT NULL, 
 date_ DATE NOT NULL, 
 articul NVARCHAR(10) NOT NULL, 
 check_num NVARCHAR(10) NOT NULL );

INSERT INTO @sales
(client_id, 
 date_, 
 articul, 
 check_num)
VALUES
(
 'id1', '01.01.2020', 'машинка', 'check1'),
(
 'id1', '01.01.2020', 'кукла', 'check1'),
(
 'id2', '03.01.2020', 'хлеб', 'check2'),
(
 'id2', '03.01.2020', 'масло', 'check2'),
(
 'id2', '03.01.2020', 'огурец', 'check2'),
(
 'id1', '01.06.2020', 'машинка', 'check15'),
(
 'id1', '01.06.2020', 'кукла', 'check15'),
(
 'id2', '03.05.2020', 'хлеб', 'check4'),
(
 'id2', '03.05.2020', 'масло', 'check4'),
(
 'id3', '03.05.2020', 'сигареты', 'check65'),
(
 'id3', '03.05.2020', 'спички', 'check65'); 

 -- уникальные пары 
 with t as ( select * from @sales )
   select t1.articul, t2.articul, check_num = min(t1.check_num)
     from t as t1 inner join t as t2 on t1.client_id = t2.client_id and t1.check_num < t2.check_num and t1.articul < t2.articul
     group by t1.articul, t2.articul
;

 -- пары + кол-во таких пар
 with t as ( select * from @sales )
    , t1 as ( select articul1 = t1.articul, articul2 = t2.articul, check_num = min(t1.check_num)
                 from t as t1 inner join t as t2 on t1.client_id = t2.client_id and t1.check_num < t2.check_num and t1.articul < t2.articul
                 group by t1.articul, t2.articul
            )
   select articul1, articul2, count(*) as cnt
     from t1 
          inner join t as t2 on t2.check_num >= t1.check_num and t2.articul = t1.articul1
          inner join t as t3 on t2.client_id = t3.client_id and t3.check_num = t2.check_num and t3.articul = t1.articul2
     group by t1.articul1, t1.articul2
     --having count(*) > 1
     order by cnt desc
;
-- пары с клиентами + кол-во таких у клиента
 with t as ( select * from @sales )
    , t1 as ( select articul1 = t1.articul, articul2 = t2.articul, check_num = min(t1.check_num)
                 from t as t1 inner join t as t2 on t1.client_id = t2.client_id and t1.check_num < t2.check_num and t1.articul < t2.articul
                 group by t1.articul, t2.articul
            )
   select articul1, articul2, count(*) as cnt, t2.client_id
     from t1 
          inner join t as t2 on t2.check_num >= t1.check_num and t2.articul = t1.articul1
          inner join t as t3 on t2.client_id = t3.client_id and t3.check_num = t2.check_num and t3.articul = t1.articul2
     group by t1.articul1, t1.articul2, t2.client_id
     --having count(*) > 1
     order by t1.articul1, t1.articul2, cnt desc, t2.client_id
...
Рейтинг: 0 / 0
Повторяющиеся значения в рамках одной группы
    #40011501
aleks222
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А это, если я правильно вспомнил математику...

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
 -- пары 
 with t as ( select * from @sales )
   select t1.articul, t2.articul, ( sqrt(8*count(*) + 1 ) + 1 ) /2 as cnt
     from t as t1 inner join t as t2 on t1.client_id = t2.client_id and t1.check_num < t2.check_num and t1.articul < t2.articul
     group by t1.articul, t2.articul
 ----    having count(*) > 1
     order by cnt desc
;
-- клиенты c парами
 with t as ( select * from @sales )
   select t1.articul, t2.articul, ( sqrt(8*count(*) + 1 ) + 1 ) /2 as cnt, t1.client_id
     from t as t1 inner join t as t2 on t1.client_id = t2.client_id and t1.check_num < t2.check_num and t1.articul < t2.articul
     group by t1.articul, t2.articul, t1.client_id
 --    having count(*) > 1
     order by t1.articul, t2.articul, cnt desc, client_id
...
Рейтинг: 0 / 0
Повторяющиеся значения в рамках одной группы
    #40011517
Palkin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
aleks222,

Спасибо, все получилось))))
...
Рейтинг: 0 / 0
Повторяющиеся значения в рамках одной группы
    #40011535
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
У меня как-то так:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
;with
checks as (
   select distinct check_num, client_id from @sales
),
items as (
   select check_num, articul from @sales
),
check_pairs as (
   select c1.client_id, c1.check_num check_num_1, c2.check_num check_num_2
    from checks c1 join checks c2 on c1.client_id = c2.client_id
    where c1.check_num < c2.check_num
)
select * from check_pairs cp
  where not exists (
    select * from
      (select * from items where check_num = cp.check_num_1) i1
      full outer join
      (select * from items where check_num = cp.check_num_2) i2
      on i1.articul = i2.articul
      where i1.check_num is null or i2.check_num is null
  )
...
Рейтинг: 0 / 0
Повторяющиеся значения в рамках одной группы
    #40011780
Palkin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
fkthat
У меня как-то так:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
;with
checks as (
   select distinct check_num, client_id from @sales
),
items as (
   select check_num, articul from @sales
),
check_pairs as (
   select c1.client_id, c1.check_num check_num_1, c2.check_num check_num_2
    from checks c1 join checks c2 on c1.client_id = c2.client_id
    where c1.check_num < c2.check_num
)
select * from check_pairs cp
  where not exists (
    select * from
      (select * from items where check_num = cp.check_num_1) i1
      full outer join
      (select * from items where check_num = cp.check_num_2) i2
      on i1.articul = i2.articul
      where i1.check_num is null or i2.check_num is null
  )



Выдает чеки, а не артикулы
...
Рейтинг: 0 / 0
Повторяющиеся значения в рамках одной группы
    #40011794
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Palkin
Выдает чеки, а не артикулы

Да, клиентов и пары совпадающих чеков. Я думал именно это нужно. Но по чекам получить уже артикулы ведь совсем уже легко.
...
Рейтинг: 0 / 0
13 сообщений из 13, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Повторяющиеся значения в рамках одной группы
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]