Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Базы данных и репортинг > Запрос к БД. Кол-во записей за несколько месяцев.


Автор: Nikolja 20.6.2010, 19:43
Здравствуйте, форумчане и замечательный форум Vingrad!  smile 
Здесь, на форуме, есть что почитать, но ПИШУ я сюда редко. 
(Не писатель, а читатель, однако)  smile 

Базы данных – дело для меня то ли новое, то ли хорошо забытое старое.
Надеюсь, что для людей, занимающихся этим делом постоянно, ответить на следующий вопрос не составит труда.

Есть некий диагностический центр и его база данных. БД – локальная, Парадокс, Delphi. 
Идентификаторы я напишу по-русски, русскими буквами. Возможно, так скорее и проще будет понятна суть вопроса.

Каждый день в диагностический центр обращаются клиенты/пациенты, направленные туда из РАЗНЫХ БОЛЬНИЦ и прочих лечебных заведений. В БД заносится разная информация по каждому клиенту. В том числе и — из какой больницы он направлен.

-----------------------------------------------------------------------------

Таблица Основная.db

Поля:

Фамилия_пациента
Имя
Отчество
Дата_приёма
Название_больницы

другие, к делу не относящиеся, поля.

-----------------------------------------------------------------------------

СУТЬ ДЕЛА: 

Нужен отчёт, где
1) Список из названий больниц, откуда пришли клиенты
2) Сколько пришло из каждой больницы пациентов за месяц
3) Сколько за каждый из выбранных 4-х месяцев.

Например:

Название больницы     Январь   Февраль   Март   Апрель
-----------------------------------------------------------
1-ая город. больница    5         7        8        3
2-ая город. больница    10        5        7        15
Областная больница      20        12       11       21

и т.п.

----------------------------------------------------------


Как это сделать? С помощью SQL или, может быть, как-нибудь средствами Delphi можно?

Допустим, чтобы выбрать данные за 1 месяц, (например, за январь) я написал такой запрос (идентификаторы, для понятности, ЗДЕСЬ на русском):

Код

SELECT Название_больницы, COUNT(Название_больницы)
FROM Основная.db
WHERE (Дата_приёма BETWEEN "1.01.10" AND "31.01.10")
GROUP BY Название_больницы


А как за 4 месяца? 
и чтобы количество за каждый месяц в отдельной колонке, как в табличке выше?


И ЕЩЁ ВОПРОС:

Можно ли задать условие так, чтобы задавать в запросе только нужный месяц, а не диапазон с первого по последнее число месяца
Чтобы пользователь не вспоминал, сколько дней в январе, сколько в феврале, а сколько в марте?

Автор: Keeper89 20.6.2010, 20:59
Какие еще есть таблицы (список пациентов, список больниц и т.д.)?
Насколько я понимаю, для решении данных задач достаточно 3-х таблиц: клиенты, больницы и сводная (типа той, что приведена).

Автор: chip_and_dayl 20.6.2010, 21:03
Цитата(Nikolja @  20.6.2010,  19:43 Найти цитируемый пост)
А как за 4 месяца?

Также как и за 1 месяцsmile


Цитата(Nikolja @  20.6.2010,  19:43 Найти цитируемый пост)
Можно ли задать условие так, чтобы задавать в запросе только нужный месяц, а не диапазон с первого по последнее число месяца? 

Можно, на уровне Делфи. Пользователь указывает только месяц, а программа уже с помощью встроенных функций вычисляет количество дней в месяце и передает в скл запрос. Для этого лучше использовать параметри

Добавлено через 2 минуты и 31 секунду
Да, правда чтобы результат был в виде, что выше нужно подумать

Добавлено через 4 минуты и 23 секунды
Что за база!?!
На сколько я знаю, то есть в скл ф-ции которые отделяют от даты месяц, год и т.д. Тогда можно по им группировать

Автор: Nikolja 21.6.2010, 13:51
Цитата(Keeper89 @ 20.6.2010,  20:59)
Какие еще есть таблицы (список пациентов, список больниц и т.д.)?
Насколько я понимаю, для решении данных задач достаточно 3-х таблиц: клиенты, больницы и сводная (типа той, что приведена).

Вся основная инфа, как раз в той таблице, под названием ~ Основная.bd. Если угодно -- Osnovna.bd
Есть ещё таблица со списком лечебных заведений. 

Ну а остальное, как я и писал, уж извините, как говорится, не в обиду будь сказано, действительно ничуть не относится к данному вопросу. Списки врачей, лаборантов, израсходованных материалов...

Добавлено @ 13:56
Цитата(chip_and_dayl @ 20.6.2010,  21:03)
Цитата(Nikolja @  20.6.2010,  19:43 Найти цитируемый пост)
А как за 4 месяца?

Также как и за 1 месяцsmile

А поконкретнее можно, если знаете? Тут ведь, по идее, несколько строчек кода...
Я же именно об этом и спрашиваю, -- т.е. понимаю, что это где-то близко к тому, что выше написано -- но не соображу КАК именно! 

Отвечаю на другие вопросы:
Как уже было сказано: БД -- несколько таблиц на Парадоксе, интерфейс -- на Delphi.

Автор: Nikolja 21.6.2010, 14:07
Цитата(chip_and_dayl @ 20.6.2010,  21:03)
На сколько я знаю, то есть в скл ф-ции которые отделяют от даты месяц, год и т.д. Тогда можно по им группировать

Опять-таки - а конкретнее? Программирование -- всё-таки более-менее точная техническая наука, хоть и творческая... smile 

В Delphi, к примеру, есть ф-ция DecodeDate(), которая разделяет дату на несколько беззнаковых целых (тип word)... Год, месяц, день...

Автор: chip_and_dayl 21.6.2010, 15:03
Заставили в гугл лезть.

Код

select Count(*), YEAR(bDate) as mDate  from BPR_A
group by YEAR(bDate)


Такое в Аксесе прокатило. Что с Парадоксом будет я не знаюsmile

Добавлено через 1 минуту и 1 секунду
Результат
2007     1258
2008     2589

Вместо Yera используете Month

Автор: Nikolja 23.6.2010, 16:25
To chip_and_dayl
Спасибо за помощь!

Натолкнули на поиск в нужном направлении. 
Плюс вам в репутацию за совет! +1 . Нет... постов у меня маловато на этом форуме, говорит техника... надо больше ста, чтобы влиять на репутацию. Ну, буду должен.

Правда, ваш код, тот что выше, в ДАННОМ случае, не работает, но благодаря ему я СУТЬ решения понял.
Ответ нашёл в Помощи к Delphi, раздел "Local SQL".

Итак, на ОДИН вопрос ответ уже есть. Вот он.

Чтобы задавать в запросе только нужный МЕСЯЦ, а не диапазон с первого по последнее число месяца
надо использовать функцию EXTRACT().


В данном случае EXTRACT(MONTH ...).

Например, выделим из поля с датой (приёма) Data_prijoma год, месяц и день.
Это делается так.

Код

SELECT Data_prijoma, 
       EXTRACT(YEAR FROM Data_prijoma) AS God,
       EXTRACT(MONTH FROM Data_prijoma) AS Mesjac,
       EXTRACT(DAY FROM Data_prijoma) AS Denj 
FROM Osnovna


А вот так задаётся УСЛОВИЕ - 
например, выбрать записи, где Дата приёма - май, т.е. 5-ый месяц.


(Прим. "Назва лікарні" - укр. "название больницы",
а "месяц" и "день" выше я написал на такой югославско-хорватский манер - "mesjac', "denj". 
Их "j" - это наше "й" или "ь".)

Код

SELECT Nazva_likarni, COUNT(Nazva_likarni)
FROM Osnovna.db
WHERE (EXTRACT(MONTH FROM Data_prijoma) = 5)
GROUP BY Nazva_likarni


НО! 
Остаётся ОСНОВНОЙ вопрос! 
Как изменить тот запрос, что написан выше (последний запрос), чтобы он выводил информацию за несколько месяцев, и за каждый месяц в отдельной колонке?


Получается, что к каждому столбику отдельное условие, что ли?

Переформулирую запрос попроще, русским языком. 
Нам надо вывести информацию за 4 месяца (например, январь, февраль, март, апрель), где:

1-ый столбик -- список Названий_больниц (откуда пришли клиенты/пациенты). Это сделать просто -- SELECT Название_больницы.
2-ой столбик -- Кол-во Названий_больниц, ГДЕ Дата_приёма = январь. С этим тоже уже разобрались.

Пока непонятно следующее. Как же переписать запрос, чтобы он выводил ещё и такую инф-ию? :

3-ий столбик -- Кол-во Названий_больниц, ГДЕ Дата_приёма = февраль
4-ый столбик -- Кол-во Названий_больниц, ГДЕ Дата_приёма = март
5-ый столбик -- Кол-во Названий_больниц, ГДЕ Дата_приёма = апрель

Автор: chip_and_dayl 23.6.2010, 17:44
Почти, но не все в моем примере доглядели smile
Код

SELECT Nazva_likarni, COUNT(Nazva_likarni), EXTRACT(MONTH FROM Data_prijoma)
FROM Osnovna.db
where data_prijoma>='01.01.2010' and data_prijoma<='01.10.2010'    
GROUP BY Nazva_likarni, EXTRACT(MONTH FROM Data_prijoma)


Начало и конец даты лучше передавать через параметры

Результатом по идеи должно быть следующее:

Бол. Святая Мария    февраль    158
Бол. Святая Мария     март         178

Бол. Святой Петр      февраль    358
Бол. Святой Петр      март          258

Чтобы результат был в том виде, как у вас, то нужно или использовать специальный компонент для отображения таблиц, или думать как это можно реализовать с помощью запроса

Автор: Nikolja 29.6.2010, 13:29
GROUP BY Nazva_likarni, EXTRACT(MONTH FROM Data_prijoma)

такое не работает.

Автор: Akella 29.6.2010, 14:43
почему?

Автор: chip_and_dayl 29.6.2010, 14:54
Nikolja
Хоть ошибку скажите:)

Автор: Akella 29.6.2010, 16:24
Зачем? Он ждёт телепатов!

Автор: chip_and_dayl 29.6.2010, 16:37
В принципе я телепатом подрабатываю, но в четверг, а сегодня вторник, так что ждем автора или четверга :)

Автор: Nikolja 30.6.2010, 16:13
Цитата(Akella @ 29.6.2010,  14:43)
почему?

 smile Самому интересно, почему?! smile 

Я запросы проверяю в SQL Explorer`e. Так ОН говорит что-то в таком роде - не поддерживаются выражения в GROUP BY.
Не верите  smile  - проверьте. Я так обычно, в спорных случаях и делаю. 
Можно очень быстро создать такую несложную табличку, как выше. Например, в Database Desktop`e. 

Там всего-то и надо полей для данной задачи:
Название больницы - символьное
Дата приёма - дата

И несколько записей сочинить, чтобы было из чего выбирать.

Автор: Nikolja 1.7.2010, 14:34
Цитата(chip_and_dayl @ 29.6.2010,  16:37)
В принципе я телепатом подрабатываю, но в четверг, а сегодня вторник, так что ждем автора или четверга smile

 smile Вот он и ЧЕТВЕРГ.

Как говорят французы, пардон. У меня именно сейчас, к сожалению, сложности с доступом к Интернету. Поэтому так выходит, что я пишу коротко и редко. 

И, хуже того, программа (по которой возникли вопросы)  - у меня на одном компе, а в Интернет приходится выходить с другого.

2 chip_and_dayl

Спасибо за совет. Это, в принципе, тоже вариант решения.

Цитата
не все в моем примере доглядели smile

Увидел ваш совет сразу. И попробовал.
НО - такая группировка - сначала по Названию, а потом по Дате, работает, к сожалению, только когда Дата - полная.

Может быть, я где-то ошибаюсь, но я попробовал в разных вариациях группировать по выделенному из даты месяцу - не получается! 

Ничего! Зато я из-за этого запроса основательно SQL вспомнил и повторил! 
А то, как говорится, волею случая, мне несколько лет ничем связанным с базами данных заниматься не приходилось. А оно забывается.

Автор: chip_and_dayl 1.7.2010, 15:16
Nikolja
Сейчас могу только одно посоветовать, переходите хотя бы на Аксес (используется для этого компонент АДоКвери или АдоТабле, тот же самый Табле и Квери, слегка модифицированный):)
И если правильно все организовать, то будет работать запросы вида, что выше, и при переносе программы с одного компьютера не нужно лезть в БДЕ настраивать алиасы и т.д. Ну и главное не нужно ставить сам БДЕ.

По поводу запроса с группировкой. Ну может парадокс понимает какие-то другие вариации. Я б залез бы ДатаБейс и вспомнил бы молодость, но желания нету:) да и времени, и вообще мне даже в Аксес уже не интересно лазить :)

Добавлено через 3 минуты и 14 секунд
Цитата(Nikolja @  1.7.2010,  14:34 Найти цитируемый пост)
 Вот он и ЧЕТВЕРГ.

Я тут сегодня случайно прочитал мысли менеджера проекта, и там было сказано, что если сегодня к вечеру не будут собраны две версии программы, то мне жить осталось не долго, поэтому на этом я вас покидаю:)

Автор: Nikolja 1.7.2010, 15:26
Цитата(chip_and_dayl @ 1.7.2010,  15:16)
если правильно все организовать, то будет работать запросы вида, что выше, и при переносе программы с одного компьютера не нужно лезть в БДЕ настраивать алиасы и т.д. Ну и главное не нужно ставить сам БДЕ.

Да, это аргумент. Удобно для переносимости программы.

Добавлено через 7 минут и 56 секунд
Цитата(chip_and_dayl @ 1.7.2010,  15:16)
Я б залез бы ДатаБейс и вспомнил бы молодость, но желания нетуsmile да и времени, и вообще мне даже в Аксес уже не интересно лазить smile

Понятно, что Paradox, DataBase, FoxPro - не самые крутые форматы на сегодняшний день.
Acsess`ом тоже не очень-то хочется голову забивать... но я подумаю... может быть.

Удачи вам с вашим проектом! Но если найдете пару минут, то очень интересно было бы услышать ваше мнение:
а с какими форматами баз данных сейчас стоит работать? 
Что изучать и куда стремиться? smile Что сейчас считается современным, на ваш взгляд?

Автор: chip_and_dayl 1.7.2010, 23:49
Код

а с какими форматами баз данных сейчас стоит работать? 

Как говорится, смотря для чего нужно, если вашу базу тянул парадокс, то можно на Аксес перейтиsmile А так для более сложных, которые я подметил, используют MS SQL SERVER, Postgresql и втом же духе другие СУБД.
На данный момент работаю в MS SQL SERVER 2000-2008. Что в нем нравится, так это инструменты для работы с базой (если взять Sybase 9 версия, то там, чтобы посмотреть содержимое таблицы, нужно такие действия сделать, что за это время можно покурить), ну и возможности языка sql.

Цитата

Что изучать и куда стремиться?

Не знаю кому как, а я стремлюсь к SQL Server в связке с C#. Ну и главное, к языку, который называется Английскийsmile

Автор: Akella 2.7.2010, 06:56
Цитата(Nikolja @  1.7.2010,  15:26 Найти цитируемый пост)
а с какими форматами баз данных сейчас стоит работать? 
Что изучать и куда стремиться? smile Что сейчас считается современным, на ваш взгляд? 

Смотри в сторону клиент-серверных СУБД: MSSQL, Firebird, Interbase, PostgreSQL, MySQL, Oracle и т.д.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)