Гость
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Повторяющиеся значения в рамках одной группы / 13 сообщений из 13, страница 1 из 1
23.10.2020, 23:16
    #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
23.10.2020, 23:28
    #40011453
fkthat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Повторяющиеся значения в рамках одной группы
Милейший, я, может быть и помог бы, но неужели ты думаешь, что кто-то будет качать твой ексель-файл, открывать его (а мне, например, для этого еще надо его на онедрайв закидывать) и руками копировать оттуда данные в сиквел? Напиши тут текстом DDL создания таблицы и инсерты с данными, тогда, очень возможно, будет тебе и помощь. :)
...
Рейтинг: 0 / 0
24.10.2020, 00:01
    #40011459
Владислав Колосов
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Повторяющиеся значения в рамках одной группы
Palkin,

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

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


Это в рамках одного товара, а мне нужны клиенты, которые покупали 2 товара одновременно в одном чеке несколько раз
...
Рейтинг: 0 / 0
24.10.2020, 01:12
    #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
24.10.2020, 04:51
    #40011482
НеофитSQL
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Повторяющиеся значения в рамках одной группы
Palkin
Владислав Колосов
Palkin,

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


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


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

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

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

Пары неизвестны, там несколько миллионов строк.
...
Рейтинг: 0 / 0
24.10.2020, 10:39
    #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
24.10.2020, 10:55
    #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
24.10.2020, 12:18
    #40011517
Palkin
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Повторяющиеся значения в рамках одной группы
aleks222,

Спасибо, все получилось))))
...
Рейтинг: 0 / 0
24.10.2020, 14:19
    #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
26.10.2020, 09:45
    #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
26.10.2020, 10:58
    #40011794
fkthat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Повторяющиеся значения в рамках одной группы
Palkin
Выдает чеки, а не артикулы

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


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