powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / тестовая задача - с какой стороны рыть ?
19 сообщений из 19, страница 1 из 1
тестовая задача - с какой стороны рыть ?
    #40076702
grabli092
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день.
Ткните пожалуйста меня носом - как сделать эту задачу красиво ?
Роюсь уже 3 дня, хотя вроде на вид не шибко сложная..

5. Покупатель имеет бонусную карту, привязанную только к его номеру телефона.
Покупатель может заменить бонусную карту по причине утери, либо какой-то другой.
При этом все данные со старой карты клонируются на новую, включая номер телефона, а старая очищается. После этого старая карта считается свободной для следующей выдачи либо замены (переноса данных). Поскольку покупатель всегда имеет право поменять номер телефона и перепривязать бонусную карту к нему, идентифицируем покупателя на текущий момент как владельца той или иной бонусной карты.
Один покупатель не имеет права осуществлять более 5 переносов с карты на карту в год (@limit = 5).
Есть процедура замены, получающая на вход два номера карты – текущий (@old_card) и новый (@new_card).
Требуется написать скрипт для нее, определяющий, позволяется ли покупателю осуществить текущий перенос (достиг ли он лимита), если лимит достигнут, когда он сможет в следующий раз воспользоваться заменой карты.
Есть таблица переносов c карты на карту:

Table cards_transfer
old_card new_card dt
111 555 2020-01-09
222 223 2020-02-10
333 334 2020-03-11
444 222 2020-04-12
555 666 2020-05-12
666 777 2020-06-13
777 888 2020-07-14
888 000 2020-08-15
999 333 2020-09-16
223 111 2020-10-16
Таким образом, согласно данным в примере, владелец карты 000 не может осуществлять замену карты до 09.01.2021.
...
Рейтинг: 0 / 0
тестовая задача - с какой стороны рыть ?
    #40076717
Кесарь
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
grabli092,

копать надо в сторону "родители" и "рекурсия".

Что-то вроде такого (код не мой, поэтому такой вид):

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
;WITH relationships AS (
   SELECT *,  1 as n
   FROM Table
   WHERE Child = 'A' -- стартовая позиция
   UNION ALL
   SELECT p.*, n + 1   -- количество актов наследования
   FROM Table p
    JOIN relationships pa on pa.Child = p.Parent  -- правило соединения для след. шага
) 
select *
from relationships 
where n > 5 ;
...
Рейтинг: 0 / 0
тестовая задача - с какой стороны рыть ?
    #40076721
grabli092
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Кесарь,
мне кажется я вроде понял, буду рыть тут.. спасибо в любом случае
...
Рейтинг: 0 / 0
тестовая задача - с какой стороны рыть ?
    #40076723
Кесарь
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
grabli092
Кесарь, про "родителей" это в смысле ДНК ? )) или я не понял аллегорию ?
насчет своего ДНК я и не обольщаюсь вовсе. Почему то всегда хожу самыми извилистыми путями и через заборы.. это у меня с рождения ((


Где, где смайлик "рукалицо"???


grabli092, это профессиональный форум. Здесь выражаются не аллегорически. Если я сказал вам искать по словам "родители" и "рекурсия", то так и ищите. Не забудьте вначале написать "sql server".

Если не нравится так, то ищите "обход дерева наследования". Но там будет больше не нужных вам вариантов...
...
Рейтинг: 0 / 0
тестовая задача - с какой стороны рыть ?
    #40076738
grabli092
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Кесарь,
нененене.. мне все нравится... мне просто нужен был пинок толчок в нужную сторону, я очень ценю помощь
...
Рейтинг: 0 / 0
тестовая задача - с какой стороны рыть ?
    #40076750
SERG1257
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
При фискированном уровне вложений можно сделать пять left join.
Запрос будет проще, накосячить сложнее чем с рекурсией.
...
Рейтинг: 0 / 0
тестовая задача - с какой стороны рыть ?
    #40076815
Кесарь
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SERG1257
При фискированном уровне вложений можно сделать пять left join.
Запрос будет проще, накосячить сложнее чем с рекурсией.


Задача не найти пять родителей, а найти того, у кого уже 5 или более (в любой системе бывают косяки, у кого-то может уже 6).

И потом, если бизнес решит поменять кол-во смен карт за год, вы переписывать код будете?



Нормальные программисты (инженеры) хранят бизнес-настройки в том или ином виде, доступном для редактирования пользователями бизнеса. И применяют эти настройки в коде в виде переменных. В результате чего почти никогда не требуется переделка кода при изменении параметров (остаток случаев запишем на снифинг).

Если вы делаете не так, то переучивайтесь на нормальный способ ведения дел.
...
Рейтинг: 0 / 0
тестовая задача - с какой стороны рыть ?
    #40076840
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SERG1257
При фискированном уровне вложений можно сделать пять left join.
LEFT-то зачем? INNER хватит. Если запрос вернул пустой набор - можно менять. Если не пустой - смотрим дату из 5-й копии.

Кесарь
Что-то вроде такого
Отсечку надо делать во WHERE рекурсивной части - нафига нужна вся цепь обменов?

PS. А ещё в запрос следует добавить проверку, что переданный номер карты является конечным. А то так можно прийти с якобы утраченной ранее картой - и вот уже у тебя две бонусные карты.
...
Рейтинг: 0 / 0
тестовая задача - с какой стороны рыть ?
    #40076841
Кесарь
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Akina
SERG1257
При фискированном уровне вложений можно сделать пять left join.
LEFT-то зачем? INNER хватит. Если запрос вернул пустой набор - можно менять. Если не пустой - смотрим дату из 5-й копии.

Кесарь
Что-то вроде такого
Отсечку надо делать во WHERE рекурсивной части - нафига нужна вся цепь обменов?


Хотя тоже стратегия, особенно эффективна на самописных системах: всегда будет работа. Ведь столько нужно переделывать, а ты такой незаменимый...

В предпенсионном возрасте особенно полезно.
...
Рейтинг: 0 / 0
тестовая задача - с какой стороны рыть ?
    #40076842
uaggster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Кесарь
SERG1257
При фискированном уровне вложений можно сделать пять left join.
Запрос будет проще, накосячить сложнее чем с рекурсией.


Задача не найти пять родителей, а найти того, у кого уже 5 или более (в любой системе бывают косяки, у кого-то может уже 6).

Значит, нужно сделать 6 left join'ов
И потом, если бизнес решит поменять кол-во смен карт за год, вы переписывать код будете?

Нормальные программисты (инженеры) хранят бизнес-настройки в том или ином виде, доступном для редактирования пользователями бизнеса. И применяют эти настройки в коде в виде переменных. В результате чего почти никогда не требуется переделка кода при изменении параметров (остаток случаев запишем на снифинг).

Если вы делаете не так, то переучивайтесь на нормальный способ ведения дел.
Ага. Руками.
Я не хочу сказать, что вариант с рекурсией - очень сложный, я бы тоже, например так и сделал.
Но вызов подобного запроса обязательно должен предваряться либо проверкой хранящихся значений в таблице на наличие петель, либо с ограничением на глубину рекурсии.
А кондовый способ с 6 лефт джойнами - ничего такого не требует. Он прост, как лом и такой же прочный и неломаемый.
И, как показывает практика - чем проще, тупее и очевиднее код - тем лучше.
...
Рейтинг: 0 / 0
тестовая задача - с какой стороны рыть ?
    #40076844
Кесарь
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Akina
Кесарь
Что-то вроде такого
Отсечку надо делать во WHERE рекурсивной части - нафига нужна вся цепь обменов?

PS. А ещё в запрос следует добавить проверку, что переданный номер карты является конечным. А то так можно прийти с якобы утраченной ранее картой - и вот уже у тебя две бонусные карты.


1. Если рассматривать задачу узко, то да. А если заботится о системе в целом, то при получении значения N более 5-ти можно и нужно формировать сообщение об ошибке процесса и отсылать его через обмен в нужное место для разбора.

2. Вот тут не могу не согласиться!
...
Рейтинг: 0 / 0
тестовая задача - с какой стороны рыть ?
    #40076846
Кесарь
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
uaggster
Кесарь
пропущено...


Задача не найти пять родителей, а найти того, у кого уже 5 или более (в любой системе бывают косяки, у кого-то может уже 6).

Значит, нужно сделать 6 left join'ов
И потом, если бизнес решит поменять кол-во смен карт за год, вы переписывать код будете?

Ага. Руками.

И, как показывает практика - чем проще, тупее и очевиднее код - тем лучше.

Вы очень оригинально понимаете смысл автоматизации...



Касательно проверок: само собой, я ведь не говорил, что мой код конечен. Это был пример куда копать, не более. Но он позволяет делать автоматизацию. А "лефт джойны в штуках" нет.

В нормальной системе у менеджера есть возможность поменять значение параметра руками в клиенте. И это сразу и автоматически будет иметь силу. Без какой либо переделки в системе.
...
Рейтинг: 0 / 0
тестовая задача - с какой стороны рыть ?
    #40076862
uaggster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Кесарь

Вы очень оригинально понимаете смысл автоматизации...

Ага. Только не оригинально, а единственно правильное, я бы сказал.
Программа, в идеале, должна а) Работать б) Быть обслуживаемой. Причем крайне желательно - программистом (джуниором) "с улицы", через 5 минут после вхождения в тему.
Ergo - чем тупее и железобетоннее код - тем лучше.
Программы пишутся для программистов, а не для компьютеров.
Изящные, "конфигурируемые" и "свободно настраиваемые" и тому подобные решения - не работают от слова "совсем".
Там, где можно обойтись ломом - там избыточен даже перфоратор.

И да. Не нужно делать хорошо. Нужно делать - чтобы работало. Ударение на "работало".

Касательно проверок: само собой, я ведь не говорил, что мой код конечен. Это был пример куда копать, не более. Но он позволяет делать автоматизацию. А "лефт джойны в штуках" нет.

На самом деле - тоже позволяют.
Надо сделать один join и While не более 6 раз или до получения пустого резалтсета.
(я бы так не сделал (а сделал бы рекурсией), но это как раз было бы максимально устойчивым и при этом конфигурируемым решением).
...
Рейтинг: 0 / 0
тестовая задача - с какой стороны рыть ?
    #40076867
uaggster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Кесарь, Да, кстати, забыл "Касательно проверок".
В абсолютном идеале - код не должен требовать проверок. "Проверка" - должна быть имманентна самому коду.
Вот 6 лефт джойнов - не чувствительны к качеству данных и проверок на петли - не требуют. Совсем.
Следовательно - в системе в принципе невозможны ошибки функционирования, связанные с а) качеством данных в системе (которые всегда говно, и по-другому не бывает) и с б) с реализацией самих проверок (которые пишутся людьми, у которых всегда руки не из того места, и по другому - тоже не бывает).

Хотя я тоже выберу вариант с рекурсией. Он первым приходит на ум. :-)
...
Рейтинг: 0 / 0
тестовая задача - с какой стороны рыть ?
    #40076877
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Решение зависит от контекста задачи и контекста исполнения. При массовой обработке рекурсии могут сесть на попу, в этом случае джойны более выгодны. Если абонент меняет карту на карту по кругу, рекурсия сломается, а ему не запрещено это делать.
...
Рейтинг: 0 / 0
тестовая задача - с какой стороны рыть ?
    #40076880
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
uaggster
Хотя я тоже выберу вариант с рекурсией. Он первым приходит на ум. :-)
Рекурсия почти всегда слишком дорогое удовольствие.
Задача ТС решается гораздо проще - дополнительный столбец, хранящий корневую карту для цепочки.
...
Рейтинг: 0 / 0
тестовая задача - с какой стороны рыть ?
    #40076882
Фотография Focha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
оО знакомое задание, не помню только в какой конторе оно было :(
...
Рейтинг: 0 / 0
тестовая задача - с какой стороны рыть ?
    #40076922
aleks222
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
invm
uaggster
Хотя я тоже выберу вариант с рекурсией. Он первым приходит на ум. :-)
Рекурсия почти всегда слишком дорогое удовольствие.
Задача ТС решается гораздо проще - дополнительный столбец, хранящий корневую карту для цепочки.


Еще проще, оно решается наличием идентификатора клиента в этих бредовых данных.
...
Рейтинг: 0 / 0
тестовая задача - с какой стороны рыть ?
    #40076928
uaggster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
aleks222
invm
пропущено...
Рекурсия почти всегда слишком дорогое удовольствие.
Задача ТС решается гораздо проще - дополнительный столбец, хранящий корневую карту для цепочки.


Еще проще, оно решается наличием идентификатора клиента в этих бредовых данных.

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


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