Консультация № 146137
05.10.2008, 22:04
0.00 руб.
05.10.2008, 22:07
0 15 0
Здравствуйте!
Скажите возможно ли использование этого кода в Дельфях? У меня при использовании group by вылетает ошибка. Данные выводятся в DBGrid. Может именно поэтому не получается? Реально ли вообще в DBGrid'е вывести по одному и с суммами? Или придётся перебирать все и выводить в какой-нибудь ListView?

Приложение:
SELECT таблица2.название_лекарства, SUM(таблица1.количество)
FROM таблица2 INNER JOIN таблица1 ON таблица2.id_лекарства=таблица1.id_лекарства
GROUP BY таблица2.название_лекарства
ORDER BY таблица2.название_лекарства

Обсуждение

давно
Мастер-Эксперт
425
4118
06.10.2008, 09:09
общий
Maximus777
А текст ошибки кто за Вас будет писать?
Об авторе:
Я только в одном глубоко убеждён - не надо иметь убеждений! :)
Неизвестный
07.10.2008, 20:58
общий
Разобрался с кодом. Выводит, но малость не так как хотелось. Мне надо чтобы одинаковые наименования по количеству суммировались, и название выводилось только один раз. Например, был продан Анальгин 01.10.2008-1 и 05.10.2008-3, дык вот чтоб в гриде было |Анальгин | 4 |. Или это невозможно?
давно
Мастер-Эксперт
425
4118
08.10.2008, 06:27
общий
Возможно:

SELECT название, SUM(количество) AS количество FROM таблица WHERE дата BETWEEN начальная_дата AND конечная_дата GROUP BY название

Это общий, так сказать, стандартный вид вид запроса для Вашего случая. В результате выводится по одному названию, количество суммируется по названию, за указанный период.
Об авторе:
Я только в одном глубоко убеждён - не надо иметь убеждений! :)
Неизвестный
08.10.2008, 23:08
общий
Спасибо. Вроде разобрался, работает. Пришлось в дельфях из ADOQuery убирать поля, тогда заработало. Теперь другой вопрос. Нигде не могу найти толкового примера с двумя JOIN. У меня названия берутся из Table1, а Приход и Расход соответственно с Table3 и Table2. Т.е. Table1 надо заJOINить с 2 и 3. С одним JOINом всё работало. Теперь надо два. Поправьте плиз код. Засада явно где-то во второй строке.

SQL.Add('select Table1.Наименование,sum(Table3.Количество) as Приход,sum(Table2.Количество) as Расход');
SQL.Add('from Table1 join Table2 join Table3 on Table1.key1=Table2.id and Table1.key1=Table3.id');
SQL.Add('where Дата between #'+FormatDateTime('mm''/''dd''/''yyyy',Date1.Date)+'# and #'+FormatDateTime('mm''/''dd''/''yyyy',Date2.Date)+'#');
SQL.Add('group by Table1.Наименование');
SQL.Add('order by Table1.Наименование');
давно
Мастер-Эксперт
425
4118
09.10.2008, 05:08
общий
Обе таблицы (Приход, Расход) надо связывать со справочником, а не друг с другом:

SELECT Table1.Наименование, SUM(Table3.Количество) AS Приход,sum(Table2.Количество) AS Расход
FROM Table1
INNER JOIN Table2 ON Table1.key1=Table2.id
INNER JOIN Table3 ON Table1.key1=Table3.id

Таким образом сначала прописывается связь первой таблицы со второй и условие их связи, а потом прописывается связь с третьей таблицей и условие связи первой таблицы с третьей.
Об авторе:
Я только в одном глубоко убеждён - не надо иметь убеждений! :)
Неизвестный
09.10.2008, 19:46
общий
делаю так:

Код:
    Close; SQL.Clear;
SQL.Add('select Table1.Наименование, sum(Table3.Количество) as Приход, sum(Table2.Количество) as Расход');
SQL.Add('from Table1');
SQL.Add('inner join Table2 on Table1.key1=Table2.id');
SQL.Add('inner join Table3 on Table1.key1=Table3.id');
SQL.Add('where Дата between #'+FormatDateTime('mm''/''dd''/''yyyy',Date1.Date)+'# and #'+FormatDateTime('mm''/''dd''/''yyyy',Date2.Date)+'#');
SQL.Add('group by Table1.Наименование');
SQL.Add('order by Table1.Наименование');
Open;


Говорит "Ошибка синтаксиса, пропущен оператор".
давно
Мастер-Эксперт
425
4118
10.10.2008, 05:24
общий
А почему у Вас внутри FormatDateTime(), в строке формата, стоят одинарные кавычки?
Об авторе:
Я только в одном глубоко убеждён - не надо иметь убеждений! :)
Неизвестный
10.10.2008, 05:57
общий
Могу сказать только одно, с двумя таблицами всё работает на ура, с этой же строкой про дату. Проблема возникает с JOINом, когда я третью таблицу пытаюсь привязать.
давно
Мастер-Эксперт
425
4118
10.10.2008, 06:51
общий
Конструкцию, подобно Вашей, я проверил на своей БД (только она MySQL, а не Access) - работает без проблем.
А без WHERE с тремя таблицами у Вас работает?
Перед полем "Дата" название таблицы пробовали ставить? А то Дата у Вас стоит сиротинушкой, неизвестно к какой таблице относится.
Об авторе:
Я только в одном глубоко убеждён - не надо иметь убеждений! :)
Неизвестный
10.10.2008, 10:19
общий
У меня с тремя таблицами вообще не получается. Работает только с двумя. Я наверное запутал вас. Попробую объяснить суть моей задачи. Есть три таблицы:

Table1 - id, Наименование, Цена (таблица справочник наименований)
Table2 - id, Дата, количество (таблица по расходу)
Table3 - id, Дата, Количество (таблица по приходу)

И есть DBGrid, в котором надо выводить информацию за период (неделю, месяц, год) в таком виде:

Наименование | Приход | Расход

Причём за этот период приход или расход может быть и нулевым. Никак не могу сообразить что мне связать и какой запрос делать. Это мой первый опыт работы с БД.
Неизвестный
10.10.2008, 13:54
общий
Всё! Вопрос решён. Метод научного тыка сделал своё дело. Вот оно:

SELECT Table1.Наименование, Sum(Table3.Количество) AS Приход, Sum(Table2.Количество) AS Расход
FROM (Table1 LEFT JOIN Table2 ON Table1.key1 = Table2.id) LEFT JOIN Table3 ON Table1.key1 = Table3.id
WHERE (((Table3.Дата) Between #1/10/2008# And #10/31/2008#)) OR (((Table2.Дата) Between #1/10/2008# And #10/31/2008#))
GROUP BY Table1.Наименование
ORDER BY Table1.Наименование;

Я нашёл отличный вариант помощи в запросах. В конструкторе Акцесса добиваюсь работоспособности запроса, потом перевожу конструктора в режим SQL и вижу весь текст. Вуаля. Остаётся чуть-чуть подпилить для дельфей и всё. Спасибо за внимание, уделённое моему вопросу.
давно
Мастер-Эксперт
425
4118
11.10.2008, 04:11
общий
Table3.Дата

Я ведь Вас про это спрашивал. И если бы Вы обращали внимание на мои уточняющие вопросы, то работоспособности запроса можно было бы добиться гораздо раньше.
Об авторе:
Я только в одном глубоко убеждён - не надо иметь убеждений! :)
Неизвестный
11.10.2008, 08:58
общий
А я думаю что наиболее критичное место всё-таки вторая строка. Третью строку я по всякому упрощал, но работоспособности запрос не приобретал. А вот после появления скобок и слова LEFT во второй строке всё заработало. Теперь бы ещё понять как весь процесс JOINа происходит ...

И всё-таки запрос работает не как мне надо. Мне необходимо как-то разделить Приход с Расходом. Сейчас одно из этих полей может врать. Не получается вывести за определённую дату. Подскажите где я не прав? К примеру задаём период с 05.10.2008 по 06.10.2008. Должно быть так:
Анальгин | 5 | 0
Бинт | 0 | 10

А у меня получается что если во вторую колонку попадает что-то, то автоматом и третья заполняется значением, но у этих значений (в третьем столбце) дата другая.
давно
Мастер-Эксперт
425
4118
11.10.2008, 17:19
общий
Слово LEFT означает, что при объединении таблиц из левой таблицы будут взяты все записи без исключения. INNER означает, что взяты будут тольке те записи, которые удовлетворяют условию объединения (которое после ON). Соответственно слово RIGHT будет обозначать, что берутся все без исключения записи в правой таблице.
По поводу условия.
1. Вам надо чтобы в приходе и расходе id лекарства совпадало с таблицей справочника. Это у Вас выполняется в условиях объединения (JOIN).
2. Вам надо, чтобы дата и в расходе и в приходе входила в заданный диапазон. "И" по английски пишется как "AND". Посмотрите, а у Вас там в условии какое слово написано? По Вашему условию получается, что запись будет попадать если дата расхода совпадает или дата прихода совпадает.
Об авторе:
Я только в одном глубоко убеждён - не надо иметь убеждений! :)
Неизвестный
11.10.2008, 18:15
общий
Слово "И" то я знаю, с этим проблем нет, но если его использовать, то в грид вообще ничего не попадает. Потому что к примеру в периоде за 5-6 число Приход был 5-го, а Расход был 6-го. И если я делаю выборку за 5-е число, то в гриде пусто. Приход и Расход должны быть независимы друг от друга, а связаны только со справочником. Вобщем засада.
Форма ответа