Бред

Ответить в тред Ответить в тред
Check this out!
Аноним # OP 02/07/21 Птн 00:09:27 2500940951
screenshot[1].png 76Кб, 1000x1000
1000x1000
Помощи с SQL тред

Привет, ночной. Решаю некоторые задачи по SQL, а точнее sqlite3. Сам знаю язык на уровне select, join и немного оконных функций. Поэтому моих знаний не хватает и прошу помощи или совета по вопросу у анона.

Задача: есть столбцы client_id и date. В date хранятся даты в интервале от 01.02.2019 до 01.02.2020 т.е ровно за год. Каждая дата начинается только с первого числа месяца, например 01.02.2019, 01.03.2019, 01.04.2019 и т.д. Нужно найти все client_id, у которых есть дата для каждого месяца прошедшего интервала, т.е каждый из 13 месяцев.
Я думаю это делать через group_by по клиентам и посчитать количество уникальных дат, соответственно у кого оно будет равно 13, тот подходит. Решение, очевидно, кривое, но другого пока не могу придумать.

спасибо абу за новую капчу
Аноним # OP 02/07/21 Птн 00:14:14 2500943162
Бамп
Аноним 02/07/21 Птн 00:15:38 2500943733
>>250094095 (OP)
Дай скрин примера таблицы. Не могу понять как у тебя данные в поле client_id записаны
Аноним 02/07/21 Птн 00:17:57 2500944604
Если я просто пишу select from where. То я полный долбоёб?
Аноним # OP 02/07/21 Птн 00:19:05 2500945185
myIVe9X[1].png 27Кб, 322x921
322x921
Аноним # OP 02/07/21 Птн 00:21:22 2500946166
gnEKzjM[1].png 18Кб, 531x656
531x656
В целом работает, но выглядит запрос как говно
Аноним 02/07/21 Птн 00:24:34 2500947497
Встречный вопрос вселенской важности: сколько учился, стаж и зп?0))0)
Аноним 02/07/21 Птн 00:25:54 2500948008
>>250094518
Там где у тебя HAVING кококо сравнивай не с 13 как дебил, а с
count(SELECT DISTINCT date FROM Table)
Аноним # OP 02/07/21 Птн 00:25:58 2500948049
>>250094749
Учился в шараге, в сфере стаж чуть больше года, зп 130.
Около айти, я не разработчик и какой-нибудь sql engineer
Аноним 02/07/21 Птн 00:26:52 25009484810
>>250094095 (OP)
Решение идеальное для такой задачи, всё правильно делаешь.
Аноним 02/07/21 Птн 00:27:38 25009488611
>>250094804
Ты аналитик, дата-сатанист? В юпитере вон орудуешь смотрю.
Аноним 02/07/21 Птн 00:28:34 25009492012
>>250094800
хуевое решение, не понятно, во что развернется в итоге. Ебнутый оптимизатор может этот каунт криво развернуть и запускать для каждой строки результата, т.е. ты получишь пачку обращений к БД на пустом месте. Тогда лучше это поле отдельно посчитать в where и сравнивать уже с ним.
Аноним 02/07/21 Птн 00:29:44 25009497513
>>250094095 (OP)
Лови еще больший омск: для каждого клиента делаешь выборку дат, из каждой извлекаешь номер месяца, их складываешь и сравниваешь с заранее посчитанным числом (которое получится, если сложить все твои 13 месяцев).
Аноним 02/07/21 Птн 00:30:01 25009499314
>>250094920
* без подзапроса, разумеется
Аноним # OP 02/07/21 Птн 00:30:23 25009501415
>>250094800
Годный совет, спасибо. Но не работает что-то, наверное подзапрос надо ебошить, может по этому. А я уже забыл как это делать. Щас буду вспоминать.

>>250094886
На предыдущей работе аналитик был, там в юпитере работал, а сейчас данные из экселя вообще, поэтому по старой памяти в sqlite сделал базу, залил данные и через пандас запросы делаю

вообще ебал я манагерскую работу, как же приятно сидеть писать код, гуглить проблемы. Так бы и вкатился куда нибуь в бэкенд, но в 24 не судьба похоже, когда знакомые уже по 300к получают, которые сразу после пту вошли в сферу
Аноним 02/07/21 Птн 00:32:47 25009511016
>>250094975
А как надо, если это омск, анончик?
Аноним 02/07/21 Птн 00:32:49 25009511117
>>250095014
>>250094920

совет плохой. Хочешь так сравнивать - сделай select из selectа, или заранее вычитай, если нет требований к тому, чтобы скрипт sql был только один.
Аноним # OP 02/07/21 Птн 00:36:53 25009525818
xJhAICj[1].png 21Кб, 844x727
844x727
>>250095111
Вот так? В целом работает
Аноним 02/07/21 Птн 00:37:55 25009530419
>>250095014
вкатился в 28 на сотку с ходу, ты ебанутый в 24 об эйджизме заикаться?
02/07/21 Птн 00:39:16 25009535920
>>250094095 (OP)
Если скорость нужда и данных миллионы, то делай юнион по каждой дате. Дальше смержишь, можешь параллелить говназапросы свои . Кароч по ррпинципу мап-ридуса. Груп всегда сосет бо квадратичный.
Если данных до десятка лямов записей, то не еби се моск, всем насрать на твой "красивый" код.


мимо 15 лет стажа проггер
02/07/21 Птн 00:40:40 25009540621
>>250095304
пиздешь.

вчера от хрюшки прилетел запрос не брать старше 23 (я собесы веду - пиздеть не мешки ворочать). ми ->>>>250095359
Аноним 02/07/21 Птн 00:40:43 25009540822
изображение.png 5Кб, 497x208
497x208
>>250094095 (OP)
Может вот так? Проверить не могу так как пишу с домашнего компа на котором нету ничего. Продебажить не могу, дебаж сам.
02/07/21 Птн 00:42:19 25009546423
Аноним 02/07/21 Птн 00:44:18 25009553724
>>250095359
Не понял, как ему юнион брать по датам? Юнион же делает ся по селектам с одинаковой сигнатурой (число колонок, типы)


Бич 7 месяцев в ойти
Аноним 02/07/21 Птн 00:44:53 25009555425
>>250095258
Я в целом против подзапросов - у тебя этот select count(distinct date_new) запускается для каждой строки результата, т.е. 79 раз. При этом ты понимаешь, что он всегда возвращает один и тот же результат, т.е. это суходрочка. Будет в результирующей таблице миллион записей - будет тебе миллион вложенных циклов.


В идеале - вычитай в переменную и используй значение в запросе. Или группировку с rollup сделай, это всё равно по своей сути - оконная функция, но ты можешь сделать count(*) без группировки по id_client и с группировкой в одном selectе.
Аноним # OP 02/07/21 Птн 00:44:55 25009555626
egg9Iwt[1].png 23Кб, 374x652
374x652
>>250095359
Данных всего 400к, нужно чтобы просто работало

В таком случае можно ехать дальше и добавлять следующую колонку. Есть столбец sum_payment. Для каждого клиента, включая условие из первой задачи, посчитать "средний чек за период". Неоднозначное описание как по мне, поэтому буду считать, что это просто ебнуть среднее за весь год для каждого клиента. Это легко и вроде справлюсь сам, а дальше уже не мой уровень будет
Аноним 02/07/21 Птн 00:45:47 25009558927
>>250095537
видимо руками where прописать.
Аноним 02/07/21 Птн 00:47:00 25009562428
>>250095408
having нижний не нужон, у тебя ж уже табличное выражение в результате selectа получается, можно из него селект с where сделать.
Аноним # OP 02/07/21 Птн 00:48:25 25009567529
Аноним 02/07/21 Птн 00:48:52 25009568830
>>250095406
Деды не хотят за идею пахать?
Аноним # OP 02/07/21 Птн 00:51:36 25009578631
wcgh4XQ[1].png 21Кб, 727x548
727x548
Получается так, если я правильно понял задачу. Тогда можно переходить к следующему
Аноним 02/07/21 Птн 00:51:42 25009579032
>>250095406
А, понял, разработчиков старше 23 не существует, испарились. Заебись живётся, когда хрюшка тебе поручения даёт?
Аноним 02/07/21 Птн 00:53:58 25009589333
>>250095675
Можно через промежуточную таблицу сделать, как на стековерфлоу советуют. Но в целом можно и не оптимизировать заранее и сделать подзапрос в having - будет тормозить, заюзаешь дополнительно таблицу со значением.

С rollup я напутал, он добавляет строку к результату, а не столбец.
Аноним # OP 02/07/21 Птн 00:57:47 25009603434
Ну а теперь "средняя сумма покупок за месяц". Если это значит, посчитать сумму за каждый прошедший месяц и затем взять среднее, то идей даже нет как это делать
Аноним 02/07/21 Птн 01:03:11 25009622535
>>250095675 >>250095893
Во втором ответе ссылке на SO говрят про рид-онли переменные.
WITH const AS (SELECT count(distinct date_new) AS date_count FROM transactions)
SELECT id_client, count(distinct date_new) FROM transactions
GROUP BY id_client
HAVING count(distinct date_new) = const.date_count
Аноним 02/07/21 Птн 01:03:44 25009624936
>>250096034
select
date_new, avg(sum_payment)
from ....
group by date_new

?

Или чётче формулируй, без внятного ТЗ результат всегда ХЗ
Аноним # OP 02/07/21 Птн 01:03:57 25009625537
Не получается мыслить языком запросов к бд, у меня в голове это выглядит как циклом пройтись по массиву и посчитать нужные суммы и все остальное. А как это перевести в SQL пока не доходит
Аноним 02/07/21 Птн 01:06:57 25009636138
>>250096225
я пробовал with, у меня nested loops в MS SQL получаются. что с обобщенными выражениями, что просто с select из select.
Аноним 02/07/21 Птн 01:08:25 25009641639
>>250096255
это да, к декларативному описанию надо прийти, а потом еще раз прийти, когда поймешь, как там всё внутри работает и почему подзапросы в основном - зло.
Аноним 02/07/21 Птн 01:09:44 25009645840
>>250096255
Ты кинь в тред код создания и заполнения таблицы - create/insert-ы, чтобы аноны могли тестировать у себя запросы.
Аноним # OP 02/07/21 Птн 01:11:56 25009654441
HBajOaa[1].png 45Кб, 363x1189
363x1189
>>250096249
Для каждого id_client есть много date_new и sum_payment, как на скрине, нужно для каждого месяца посчитать сумму sum_payment и затем взять среднее из средних.
Например, (avg(за февраль 2019) + avg(за март 2019) + avg(за апрель 2019) .. + avg(за фефраль 2020) и поделить на количество месяцев, т.е 13.
У каждого клиента есть операции в каждом месяце, т.к в первой задаче взяты только клиента с непрерывной историей за период
Аноним 02/07/21 Птн 01:13:01 25009659142
>>250096544
не усложняешь? среднее из средних математически не будет равно просто среднему?
Аноним # OP 02/07/21 Птн 01:14:24 25009665043
>>250096591
Что-то я не то написал, да. Сам не до конца понимаю что значит "средняя сумма покупок за месяц". Думаю это сумма покупок за каждый месяц / количество прошедших месяцев.
Аноним # OP 02/07/21 Птн 01:14:57 25009667144
Аноним # OP 02/07/21 Птн 01:18:29 25009680745
>>250096650
>>250096591
Опять что-то не то.
>Думаю это сумма покупок за каждый месяц / количество прошедших месяцев.

Это же тоже самое, что просто сумма всех покупок за период / 13 прошедших месяцев
Аноним 02/07/21 Птн 01:18:58 25009682346
>>250096671
SELECT SUM(sum_payment) / (SELECT count(distinct date_new) AS date_count FROM transactions)
FROM transactions
Аноним 02/07/21 Птн 01:19:12 25009683347
>>250096650
если просто "средняя сумма покупок за месяц", то бери месяц и считай среднее. Если для человека - добавь туда человека. т.е. у тебя все равно вариантов два.

date_new, avg(sum_payment)
или
id_client, date_new, avg(sum_payment)

Не выдумывай себе трудности, их тебе выдумает заказчик.
Аноним 02/07/21 Птн 01:21:08 25009690748
>>250096823
ну вот тоже жизнеспособная идея, если тебе и месяцы не нужны, то это одна цифра, сколько в среднем магазин зарабатывает в месяц.
Аноним 02/07/21 Птн 01:27:43 25009714249
>>250096907
SELECT SUM(sum_payment) / count(distinct date_new)
FROM transactions

Да, только я б подзапрос всё таки убрал
Аноним # OP 02/07/21 Птн 01:29:17 25009719550
>>250096823
>>250096833
>>250096907

В целом задача "среднее за месяц" звучит странно потому что:
>Это же тоже самое, что просто сумма всех покупок за период / 13
В таком случае остается просто для каждого месяца запилить отдельный столбец со средним за этот месяц. Но это опять же странно, ведь период мог состоять не из 13 месяцев а из 113
Ну хуй с ним. Буду делать
02/07/21 Птн 01:32:16 25009729751
>>250094095 (OP)
паржал с тупорылого аналитика, который даже ссаный сиквел для дошкольника не знает, лоол
Аноним 02/07/21 Птн 01:37:50 25009749352
>>250097195
Столбцы пилить не надо, а строкам пофигу, avg сам тебе среднее посчитает сумму и разделит на количество строк в группе.
Аноним 02/07/21 Птн 01:38:38 25009752753
>>250097297
фронтендер-петушок, тут тебе не рады.
Аноним # OP 02/07/21 Птн 01:49:39 25009788554
OmoZGBD[1].png 37Кб, 430x830
430x830
Обосрался я с предыдущей задачей т.е "средний чек за период". Есть еще столбец id_check. Получается надо sum(sum_payment) / количество чеков
Аноним 02/07/21 Птн 01:55:41 25009809155
>>250097885
ну таки также, sum() / (count discinct id_check)
Аноним # OP 02/07/21 Птн 02:06:14 25009844456
PtRvBdS[1].png 29Кб, 799x550
799x550
>>250098091
Вот так получилось. Добавил еще количество операций за период, судя по всему в count можно не передавать параметр, ведь не важно какой столбец считать?

На сегодня закончу, завтра меня таки ждет ранжирование по месяцам, по возрастам с шагом N лет, подсчет за квартал, пиздец.

Спасибо всем кто был в треде и особенно тем, кто помог! Завтра на вечернем создам еще раз.
15 лет кун приходи

Абу благословил этот пост.
Аноним 02/07/21 Птн 02:11:26 25009859157
>>250098444
в count(*) и count(a) есть важное отличие - в первом случае он тебе посчитает все строки, во втором - только те, где a не null. Удачи!
Аноним 02/07/21 Птн 04:41:59 25010148758
>>250094804
За что тебе платят такие деньги, блядь, с одним годом опыта!?
Настройки X
Ответить в тред X
15000
Макс объем: 20Mб, макс кол-во файлов: 4
Кликни/брось файл/ctrl-v
X
Ваш шидевор X
Стикеры X
Избранное / Топ тредов