Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Базы данных и репортинг > sql запрос к базе access


Автор: jon007 6.4.2016, 21:30
Здравствуйте. Есть таблица в access с полями data, time, tovar, kolvo, в ней значение в поле tovar могут повторятся. Не получается сделать запрос так чтобы было выбраны все записи таблицы, исключая одинаковые значения в поле товар, но при этом была возможность выбора даты и времени в запросе и максимальное значение поля kolvo. Спасибо.
Типа записи таблицы:
data                    time            tovar            kolvo
04.04.2016    23:08:49    пластырь    12
05.04.2016    23:10:15    пластырь    13
06.04.2016    22:10:16    спички    1
06.04.2016    23:10:17    пластырь    14
06.04.2016    22:40:11    спички    2
06.04.2016    23:40:12    пластырь    15
06.04.2016    22:40:13    спички    3
06.04.2016    22:40:14    спички    4
 А на выходе получить только:
06.04.2016    23:10:18    пластырь    15
06.04.2016    22:40:14    спички    4 

Автор: homef1re 6.4.2016, 23:07
http://www.tbania.ru/
лучшие банные процедуры со всего мира,Дубовая фитобочка,
Японская баня офуро,Турецкая баня хамам,Русская баня в комплексе «Таёжные бани»
Московские бани – всегда легкий пар!Элитный комплекс отдыха
«ТАЁЖНЫЕ БАНИ» баня на дровах с печкой на березовых поленьях.

Этот ответ добавлен с нового Винграда - http://ru.vingrad.com/sql-zapros-k-baze-access-id5705565eae201531188b4567#findElement_E7045_57056c6aae2015592678b7af_0

Автор: DizzyCrazy 7.4.2016, 11:39
select table1.data,table1.time,t.tovar,maxkolvo as kolvo from
(
--Отобрали max значения для названий во временную t
select tovar,max(kolvo) as maxkolvo from Table1 group by tovar
) t
--связали t с Table1 по названию и max количеству
inner join Table1 on
t.tovar = table1.tovar and maxkolvo = kolvo

Этот ответ добавлен с нового Винграда - http://ru.vingrad.com/sql-zapros-k-baze-access-id5705565eae201531188b4567#findElement_E7045_57061cddae2015067778c1ca_0

Автор: jon007 7.4.2016, 13:51
DizzyCrazy, делфи ругается при запуске запроса, пишет "ошибка синтаксиса в операции JOIN". 
Не пойму почему не работает такой запрос:
Код

dm.ADOQuery1.SQL.Add('select max(kolvo) from prodazha');
 результат ноль

Автор: salik 7.4.2016, 14:08
Цитата(jon007 @ 6.4.2016,  22:30)
Здравствуйте. Есть таблица в access с полями data, time, tovar, kolvo, в ней значение в поле tovar могут повторятся. Не получается сделать запрос так чтобы было выбраны все записи таблицы, исключая одинаковые значения в поле товар, но при этом была возможность выбора даты и времени в запросе и максимальное значение поля kolvo. Спасибо.
Типа записи таблицы:
data                    time            tovar            kolvo
04.04.2016    23:08:49    пластырь    12
05.04.2016    23:10:15    пластырь    13
06.04.2016    22:10:16    спички    1
06.04.2016    23:10:17    пластырь    14
06.04.2016    22:40:11    спички    2
06.04.2016    23:40:12    пластырь    15
06.04.2016    22:40:13    спички    3
06.04.2016    22:40:14    спички    4
 А на выходе получить только:
06.04.2016    23:10:18    пластырь    15
06.04.2016    22:40:14    спички    4


Код

select date, time, tovar, kolvo from prodaja
group by tovar
having
date = 'blablabla'
and time = 'blablabla'
and kolvo = max(kolvo)

Автор: jon007 8.4.2016, 11:30
Опять ругается "Попытка выполнить запрос, который не включает указанное выражение 'time' как часть статистической функции или группы". На компе стоит делфи 7 и access 2002.

Автор: superVad 8.4.2016, 18:55
Может проблема в названиях полей таблицы?
date, time скорее всего функции такие есть

Автор: Vas 8.4.2016, 21:58
Код

select  tovar, max(kolvo) from prodaja
where date=:my_date and time=:my_time
group by tovar

Автор: jon007 9.4.2016, 07:37
Цитата(Vas @ 8.4.2016,  21:58)
Код

select  tovar, max(kolvo) from prodaja
where date=:my_date and time=:my_time
group by tovar

Такой запрос работает на половину, выводит поле tovar и не выводит поле kolvo. Похожие запросы я уже все перепробовал.

Добавлено через 2 минуты и 42 секунды
Цитата(superVad @ 8.4.2016,  18:55)
Может проблема в названиях полей таблицы?
date, time скорее всего функции такие есть

Изначально в базе поле data, а не date, как пишут в запросах, даже исключая поле time запросы не хотят правильно работать.

Автор: Vas 9.4.2016, 10:58
Цитата(jon007 @  6.4.2016,  21:30 Найти цитируемый пост)
исключая одинаковые значения в поле товар, но при этом была возможность выбора даты и времени в запросе и максимальное значение поля kolvo

Значит я в поставленной задаче что-то не понимаю. Если в моем запросе выкинуть условия, то выведутся все товары с максимальным количеством, а потом уже условиями выбираем по дате и времени. Группировка как раз исключит одинаковые товары.

Добавлено @ 10:59
Если еще ограничить макисмум каким-то числом, то добавьте в WHERE kolvo<:my_kolvo

Автор: jon007 9.4.2016, 11:47
Вот выполнение Вашего запроса с выборкой по дате, выборку по времени убираем пока:
user posted image Вот запрос без даты: user posted image 
А вот запрос без группировки. 
Код

dm.ADOQuery1.SQL.Add('select tovar, kolvo from prodazha');
 
user posted image
А как сделать что бы такой запрос с группировкой выдавал не только поле товар, но и максимальное число поля количество? Я уже склоняюсь к мысли что бы вернуть программу к начальному шагу, где была таблица, в которую записыватся название товара и его количество в момент скана. В таком случаи такого запроса вполне хватает.
Код

      if dm.ADOTable1.Locate('scan', skanshtrih.text, []) then
        begin
          dm.ADOQuery1.SQL.Clear;
          dm.ADOQuery1.SQL.Add('select * from prodazha where data = date and tovar = tov');
          dm.ADOQuery1.Parameters.paramByName('date').Value:= date;
          dm.ADOQuery1.Parameters.paramByName('tov').Value:= dm.ADOTable1tovar.Value;
          dm.ADOQuery1.Open;
          if dm.ADOQuery1.RecordCount > 0 then
            begin
              dm.ADOQuery1.Last;
              col:= dm.ADOQuery1.Fields[2].Value;
              dm.ADOQuery1.Edit;
              inc(col);
              dm.ADOQuery1.Fields[0].Value:= date;
              dm.ADOQuery1.Fields[1].Value:= dm.ADOTable1tovar.Value;
              dm.ADOQuery1.Fields[2].Value:= col;
            end
          else
            begin
              dm.ADOQuery1.Insert;
              dm.ADOQuery1.Edit;
              dm.ADOQuery1.Fields[0].Value:= date;
              dm.ADOQuery1.Fields[1].Value:= dm.ADOTable1tovar.Value;
              dm.ADOQuery1.Fields[2].Value:= 1;
            end;
          dm.ADOQuery1.Post;
          dm.ADOQuery1.Close;
        end;
 Тут ADOTable1 привязан к таблице с базой товара и штирхкода к нему.
user posted image
И сделать ещё одну таблицу где будет фиксироваться время и дата скана штрихкода, ну и уже по ней делать нужные выборки по датам и времени. 

Автор: Vas 9.4.2016, 13:50
Цитата(jon007 @  9.4.2016,  11:47 Найти цитируемый пост)
А вот запрос без группировки. 
Выделить всёкод Pascal/Delphi
1:
    
dm.ADOQuery1.SQL.Add('select tovar, kolvo from prodazha');

Этот запрос пишите вы у себя в программе.

А вот такой пишу я в сообщении

Цитата(Vas @  8.4.2016,  21:58 Найти цитируемый пост)
    
select  tovar, max(kolvo) from prodaja
where date=:my_date and time=:my_time
group by tovar

Я думаю разницу вы видите. И в сообщении моем выше приложен файл с результатами на моей машине
Приложу еще раз

Автор: Vas 9.4.2016, 13:53
max(kolvo) в запросе не забывайте писать, не в условии, а в результате. А если на дату у вас нет товара, то он показываться и не должен, не вижу проблем. Если на раньшую дату надо выбрать, пишите data <: my_data

Автор: jon007 9.4.2016, 14:19
Вот запрос:
Код

  dm.ADOQuery1.SQL.Clear;
  dm.ADOQuery1.SQL.Add('select  tovar, max(kolvo) from prodaja where date=:my_date and time=:my_time group by tovar');
  dm.ADOQuery1.Parameters.paramByName('my_date').Value:= strtodate('06.04.2016');
  dm.ADOQuery1.Parameters.paramByName('my_time').Value:= strtotime('23:10:18');
  dm.ADOQuery1.Open;
end;
 Вот ошибка:
user posted image
Исправляем название таблицы:
Код

  dm.ADOQuery1.SQL.Clear;
  dm.ADOQuery1.SQL.Add('select  tovar, max(kolvo) from prodazha where date=:my_date and time=:my_time group by tovar');
  dm.ADOQuery1.Parameters.paramByName('my_date').Value:= strtodate('06.04.2016');
  dm.ADOQuery1.Parameters.paramByName('my_time').Value:= strtotime('23:10:18');
  dm.ADOQuery1.Open;
end;
 Получаем:
user posted image
Исправляем поле date на data так как она в таблице стоит и получаем пустой ответ на запрос, хотя данные на этот день и число в таблице есть, скрины запросов на эту же дату в предыдущем посте:
Код

dm.ADOQuery1.SQL.Add('select tovar, kolvo from prodazha');

Попытка выполнить такой запрос:
Код

dm.ADOQuery1.SQL.Add('select tovar, max(kolvo) from prodazha');
 выпадает в такую ошибку:
user posted image
Я не пойму почему так происходит.
Содержимое таблицы prodazha:
data              time           tovar           kolvo
06.04.2016    22:59:41    пластырь    1
06.04.2016    22:59:43    пластырь    2
06.04.2016    23:00:16    пластырь    3
06.04.2016    23:00:53    пластырь    4
06.04.2016    23:01:08    пластырь    5
06.04.2016    23:08:24    пластырь    6
06.04.2016    23:08:27    пластырь    7
06.04.2016    23:08:28    пластырь    8
06.04.2016    23:08:30    пластырь    9
06.04.2016    23:08:44    пластырь    10
06.04.2016    23:08:46    пластырь    11
06.04.2016    23:08:49    пластырь    12
06.04.2016    23:10:15    пластырь    13
06.04.2016    23:10:17    пластырь    14
06.04.2016    23:10:18    пластырь    15
06.04.2016    22:35:06    спички    1
06.04.2016    22:40:11    спички    2
06.04.2016    22:40:13    спички    3
06.04.2016    22:40:14    спички    4
06.04.2016    22:40:15    спички    5
06.04.2016    22:40:16    спички    6
06.04.2016    22:40:17    спички    7
06.04.2016    22:40:18    спички    8
06.04.2016    22:40:19    спички    9
06.04.2016    22:42:39    спички    10
09.04.2016    14:32:07    спички    1
09.04.2016    14:34:08    спички    2
09.04.2016    14:34:11    спички    3
09.04.2016    14:34:12    спички    4
09.04.2016    14:34:13    спички    5

Автор: Vas 9.4.2016, 20:39
Нельзя использовать агрегатные функции без группировки с другими полями 

Цитата(jon007 @  9.4.2016,  14:19 Найти цитируемый пост)
Попытка выполнить такой запрос:
Выделить всёБез подсветки
1:
    
dm.ADOQuery1.SQL.Add('select tovar, max(kolvo) from prodazha');

Перепиши вот так
Код

dm.ADOQuery1.SQL.Add('select tovar, max(kolvo) from prodazha group by tovar');





Цитата(jon007 @  9.4.2016,  14:19 Найти цитируемый пост)
Исправляем название таблицы:
  dm.ADOQuery1.SQL.Clear;
  dm.ADOQuery1.SQL.Add('select  tovar, max(kolvo) from prodazha where date=:my_date and time=:my_time group by tovar');
  dm.ADOQuery1.Parameters.paramByName('my_date').Value:= strtodate('06.04.2016');
  dm.ADOQuery1.Parameters.paramByName('my_time').Value:= strtotime('23:10:18');
  dm.ADOQuery1.Open;

Дык для ADO сначала распарсить параметры в запросе надо, что-то из разряда ADOQuery.ParseParam (проверять по справке надо), а потом передавать им параметры, или на крайняк создавать самому их и тип их.

Ну и собсно читать Использование агрегатных функций в SQL обязательно.

Добавлено через 7 минут и 50 секунд
P.S. Я три раза скрин свой прикрепил, там же явно видно запрос без параметров и с group by почему нельзя для начала тупо переписать запрос и выполнить? Как же раньше учились по книжкам программировать без интернета, вот время было, одна книга + справка и все, а деваться то некуда.

Дж. Грофф, П. Вайнберг Энциклопедия SQL 3-е издание, может быть уже есть 4-е не знаю. Но почитать не помешало бы, там даже раздел есть запросы с группировкой smile

Автор: jon007 9.4.2016, 20:49
Цитата(Vas @ 9.4.2016,  20:39)
Нельзя использовать агрегатные функции без группировки с другими полями 
Перепиши вот так
Код

dm.ADOQuery1.SQL.Add('select tovar, max(kolvo) from prodazha group by tovar');

Так выдаёт только список товара, поля kolvo остаются пустыми. В общем спасибо за помощь. Буду действовать по первому плану и добавлю ещё одну таблицу.

Автор: Vas 9.4.2016, 20:56
А собственно к таблице поле подвязано kolvo, а в запросе как max(kolvo), потому и пустое скорее всего. 
Перепиши так
Код

dm.ADOQuery1.SQL.Add('select tovar, max(kolvo) as kolvo from prodazha group by tovar');

Автор: jon007 9.4.2016, 21:05
А так заработала. Даже так работает: 
Код

select tovar, max(kolvo) as kolvo from prodazha where data = date group by tovar
 Спасибо. То что надо. Да, мне в SQL знаний явно не хватает.

Автор: Vas 9.4.2016, 21:45
Ну так я сразу говорил, что все должно работать  smile 

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