Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Помогите написать запрос.

63K
16 сентября 2010 года
Wsm
2 / / 16.09.2010
12. Есть таблица посещение клиентами банка, что имеет код клиента та дату посещение. Как найти клиентов в которых перерыв между посещениями хоть раз была больше 90 дней.
1.8K
16 сентября 2010 года
LM(AL/M)
332 / / 20.12.2005
если нужно для диалекта который поддерживает курсоры (вроде TransactSQL) то задача тривиальная и не интересная.
на чистом sql гораздо интереснее: сложность в том как найти пары соседних дат
вот пример как это можно сделать (используется тестовая таблица с двумя целочисленными столбцами для простоты):
[highlight=sql]
SELECT a1.id, MAX(a2.date), a1.date
FROM a a1 INNER JOIN a a2 ON a1.date > a2.date
GROUP BY a1.id;
[/highlight]

соответственно такой запрос вернёт записи у которых разность текущей и предыдущей дат больше 90:
[highlight=sql]
SELECT * FROM (
SELECT a1.id 'id', a1.date - MAX(a2.date) 'pause'
FROM a a1 INNER JOIN a a2 ON a1.date > a2.date
GROUP BY a1.id;
)
WHERE pause > 90;
[/highlight]
осталось только адаптировать эти запросы к исходной задаче
10
17 сентября 2010 года
Freeman
3.2K / / 06.03.2004
Чисто теоретически пары соседних дат можно попробовать найти аналитической функцией, которые есть в Oracle, PostgreSQL и MS SQL последних версий. Но сейчас уже пора спать. :)
385
17 сентября 2010 года
SomewherSomehow
477 / / 25.07.2004
LM(AL/M),
Идея правильная только есть несколько ошибок.
Во-первых, если вы группируете по ИД, то в селекте нельзя будет использовать дату, следовательно ее не хватает в предложении group by.
Во-вторых логическая ошибка, если даты клиентов будут пересакаться каким-либо образом, то будет мешанина и запрос вернет неверные результаты, по этому в джоин надо добавить условие соединения в рамках одного клиента.
правильный запрос выглядит примерно так
 
Код:
SELECT * FROM (
    SELECT a1.id as id, a1.date - MAX(a2.date) as pause
    FROM a a1 INNER JOIN a a2 ON a1.date > a2.date and a1.id = a2.id
    GROUP BY a1.id, a1.date
) a
WHERE pause > 90

Еще посоветую автору обратить внимание на случаи когда клиент посетил банк лишь однажды, я бы в таком случае сравнивал эту дату с текущей, т.е. он один раз пришел и до сегодняшнего момента не появлялся и если этот промежуток более 90 дней, то включать его в выборку тоже, в таком случае запрос немного изменится. Но т.к. в условиях задачи это явно не сказано (а это видимо именно задача, т.к. автор скопипастил даже не потрудившись убрать номер) - то фиг с ним...
1.8K
17 сентября 2010 года
LM(AL/M)
332 / / 20.12.2005
SomewherSomehow, вы похоже не обратили внимания на вот эти мои слова:
Цитата: LM(AL/M)
осталось только адаптировать эти запросы к исходной задаче


я не ставил цели написать полноценный запрос -- только продемонстрировать идею. должен же ТС хоть что-то сам сделать...

385
17 сентября 2010 года
SomewherSomehow
477 / / 25.07.2004
Ну почему же, обратил.
Никто и не говорит про полноценный запрос, ведь незвестна реальная структура таблиц, полей, индексов и т.д.
Если вы хотели дать автору возможность "подумать" (хотя я сомневаюсь, что он станет думать), то надо было остановиться на первой части, которая прекрасно иллюстрирует идею.
Вторая же часть дана уже как реально работающий пример кода, наглядно воплощающий идею в рамках тех тестовых объектов которые вы придумали. И раз уж вы ее приводите, то она должна быть рабочей и как минмимум верной логически - ведь так? иначе какой смысл приводить?=) представьте что в МСДНе приводили бы неверные примеры, а потом отмазывались, что типа "этж не рабочий код, этж пример, ну саавсем никто думать не хочет"...=)
1.8K
17 сентября 2010 года
LM(AL/M)
332 / / 20.12.2005
я не буду с вами спорить хотя считаю что в том смысле который я вложил во второй пример он вполне корректен, привёл я его скорее для демонстрации вложенных запросов на случай если автор вопроса этого не знает
385
17 сентября 2010 года
SomewherSomehow
477 / / 25.07.2004
Может быть. В любом случае, автор уже видимо скопипастил ваш пример в свою лабу, курсач или что там, ибо мы с вами уже обсуждаем долго, а автора все нет! =)
63K
20 сентября 2010 года
Wsm
2 / / 16.09.2010
Да это лабораторная работа нужно сделать клиентскую базу банка в Access. Большое спасибо посидел подумал понял. Еще один маленький вопрос =)
У меня есть таблица выплат сотрудникам зарплат за 12 месяцев как.
Как найти 10 сотрудников с наибольшим относительным (у процентах ) увеличением(падением ) зарплат за этот промежуток времени, относительно зарплати за первый месяц. Вывести процент увеличения.
И еще вопрос можно это зделать с помощью конструктора запросов Access, а не через SQL.
385
21 сентября 2010 года
SomewherSomehow
477 / / 25.07.2004
Ну принцип остается тот же самый, вы соединяете таблицу с собой же, и вычитаете одно из другого, только поля поменяются - получится увеличение зп относительно предыдущего месяца, и делите эту дельту на соотв.значение.
Если надо все считать относительно именно первого месяца (а не предыдущего для каждой зп) - еще проще, сделайте подзапрос, в котором посчитайте для каждого сотрудника его первую зп, соединяете этот подапрос с таблицей, опять вычитание, деление и готово.
А констурктор, это задание в лабе такое или вы для себя, чтоб визуально проще было воспринимать? Если в лабе, то понятно, но если для себя - лучше откажитесь вообще от этого способа, приучайте себя сразу думать в рамках sql без всяких конструкторов, потом пригодится.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог