Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 2002.09.19;
Скачать: [xml.tar.bz2];

Вниз

SQL запрос   Найти похожие ветки 

 
juster   (2002-08-24 11:31) [0]

Доброго всем дня.
Такай trouble: делаю из программы запрос:
select Field1, Field2, Field3 from table1, table2 where ...
в базе Access из нескольких таблиц.
Все работает. Добавляю GROUP BY Field2 - возникает ошибка:
you tried to execute a query that does not include the specified expression Field1(первое поле указанное в запросе) as part of ann aggregate function
По русски говоря Access хочет чтобы было
GROUP BY Field1, Field2, Field3, но это же мне не надо это же просто результат без дублируемых записей, которых у меня заведомо нет. Кстати, такой же запрос на такой же базе данных работает безукоризненно в MYSQL. Что делать, может перейти на другой движок вместо Access, посоветуйте на какой, что без troube


 
ЮЮ   (2002-08-24 11:50) [1]

GROUP BY Field2 предполагает, что ты группируешь по полю Field2, а следовательно только его и можешь получить в итоговом запросе. По остальным поля ты мошешь получить тольго аггрегированные фанкции: Sum, Count.
А что по твоему должен вернуть твой запрос, в случае:
f1 f2 f3
1 1 1
2 1 2
3 1 3
???


 
juster   (2002-08-24 12:12) [2]

Хотя конечно такой ситуции у меня заведомо не случиться, но если скажем я хочу получить из этого
f1 f2 f3
1 1 1


 
ЮЮ   (2002-08-24 12:15) [3]

Каким же образом из
1 1 1
2 1 2
3 1 3
ты хочешь получить
1 1 1 ?
Не думаю, что ты сможешь получить такое с помощью MYSQL :-)


 
juster   (2002-08-24 12:17) [4]

Мне без разницы или это будет
f1 f2 f3
2 1 2
или
f1 f2 f3
3 1 3
главное чтобы в результате не было строк с одинаковыми значениями в f2


 
juster   (2002-08-24 12:21) [5]

Хорошо если я напишу group by f2 это не правильно? Может быть я не прав, но в MySQL это работает, именно этот конкретный пример я не проверял, но в моей базе без проблем


 
ЮЮ   (2002-08-24 12:23) [6]

Так тогда и выбирай только f2, если f1 b f3 тебе без разницы :-)


 
ЮЮ   (2002-08-24 12:26) [7]

Или, например, max(f1),f2,max(f3)
ecли max(f1 и max(f3) тебе о чём-нибудь скажут, ведь они могут быть получены из разных записей.


 
ЮЮ   (2002-08-24 12:28) [8]

>Может быть я не прав, но в MySQL это работает
не верю


 
juster   (2002-08-24 12:51) [9]

И зря не веришь выборка из разных таблиц нескольких полей в конце ставишь group by по любому одному из полей - все работает.
Это ладно проблема в Access. Понятно что остальные поля он тоже хочет аггрегировать, но не знает как и хочет чтобы ему сказали.
Ты предлагаешь max() - нет не подходит надо чтобы была реальная строка из базы
или 1 1 1
или 2 1 2
или 3 1 3
и никак не 2 1 3




 
Balu   (2002-08-24 14:23) [10]

Я не работал с MySQL, но принцип T-SQL по моему нарушать ни в одной среде разработчики не собирались, иначе бред полный получается.
Если стрелять из пистолета по самолётам, то у тебя ничего не получится. Это к тому что в каждой ситуации необходимо пользоваться тем инструментом (язоковыми конструкциями) которые решают эту конкретную проблему.
Если тебе необходимо получить уникальные значение по Field1, Field2, Field3, то Введи:
SELECT DISTINCT Field1, Field2, Field3 FROM table1, table2 where ...

и все будет нормально, или полнее опиши свою проблему, если я тебя не так понял.


 
juster   (2002-08-24 14:43) [11]

Нет не так. Нужно чтобы в результате не повторялись значения в Field2 и только в нем допустим(суть важна что убрать повторения только в одлном поле).
Пусть есть запрос SELECT Field1, Field2, Field3 FROM table1, table2 where ...
результат предположим
Field1 Field2 Field3
1 1 2
2 1 3
3 1 3
мне надо чтобы вместо 3 строк в данном случае была одна любая из них(опять таки в данном случае) - в Field2 только одно повторяющееся значение это 1, надо убрать повторение в этом поле, т. е. удовлетворяет одна из 3 строк, любая.
Если добавить DISTINCT ничего не измениться(полностью повторяющихся строк нет)
Может быть использовать first?


 
Johnmen   (2002-08-24 21:18) [12]

http://delphi.mastak.ru/cgi-bin/forum.pl?look=1&id=1030094894&n=1


 
ЮЮ   (2002-08-26 03:46) [13]

to Johnmen © (24.08.02 21:18)
Там нет рещения данной проблемы

to juster
Можно побольше информации о таблицах: есть ли уникальные поля и по каким полям связываются таблицы, т.к. в общем случае задача может не иметь решения


 
juster   (2002-08-26 11:56) [14]

Если поробовать:
SELECT
First(Field1) as First_Field1,
Field2,
First(Field3) as First_Field3
FROM table1, table2
where ...
order by Field2;
то вроде как это решение проблемы, но опять таки это не панацея в данном случае - не все движки понимают что такое First.
В Access это заработало, но если в where стоит что-то сложное и длинное, то тормоза ощутимы вплоть до того, что время возврата запроса может быть просто немыслимым.
Вот такой вот компот. База небольшая, на локальной машине, так что либо я где-то что-то упустил, либо можно поставить еще один баг в продукции Microsoft.
Думаю переходить на другой движок, что подскажете?




 
Reindeer Moss Eater   (2002-08-26 12:01) [15]

мне надо чтобы вместо 3 строк в данном случае была одна любая из них

То есть, значения полей F1 и F2 тебя вообще не интересуют.
Значит запрос твой должен выглядеть так :
Select distinct Field2 from Table1


 
juster   (2002-08-26 12:20) [16]

to Reindeer Moss Eater.
Не совсем так. Они меня не интересуют какими они будут, лижбы это были реальные значения из какой-то строки, группировка по Field2. Вот и решение:
SELECT
First(Field1) as First_Field1,
Field2,
First(Field3) as First_Field3
FROM table1, table2
where ...
order by Field2;
только повторюсь тормоза жуткие если в where что-то большое, ненавижу Access, посоветуйте что-нибудь другое а?


 
Balu   (2002-08-26 14:20) [17]

Создай в Access-е запрос

select Field1, Field2, Field3 from table1, table2 where ...

И потом обращайся к этому запросу

SELECT Field2, MIN(Field1), MIN(Field3) FROM Запрос1 where ...


 
ЮЮ   (2002-08-27 05:09) [18]

Так и не ответил на ЮЮ © (26.08.02 03:46)
Можно побольше информации о таблицах: есть ли уникальные поля и по каким полям связываются таблицы, т.к. в общем случае задача может не иметь решения

>жуткие если в where что-то большое

Возможно стоит использовать подзапросы, сначала отбирая записи по where, а затем делать Group и связывать таблицы через left join


 
juster   (2002-08-27 13:18) [19]

к ЮЮ
Ты прав ситуация возможно решаема, используя несколько запросов.
Но самое большое неудобство в Access, это то что запросы типа select являются нередактируемыми, это вот заноза.
Приходится использовать либо временные таблицы, либо массивы или еще как-то сохранять информацию про изменения, при этом необходимо использовать компоненты не связанные с базами данных. Потом записывать измененные данные в таблицы, делать Refresh исходному запросу(select). Все это хлопотно и делает сложность в проге. Поэтому-то я и пытаюсь сейчас перейти на другой движок.
К тому же выражение в where вычисляется динамически - еще один камень в огороде.


 
ЮЮ   (2002-08-28 04:51) [20]

сложный запрос никакой движок не позволит редактировать.

Access позволяет редактировать даже запросы, полученные связыванием left join, если в правой таблице есть записи.

Кстати, ты используешь ADO или BDE?


 
juster   (2002-08-28 11:37) [21]

to ЮЮ
Да использую BDE, но с Access даже простейший запрос
select * from tblname не редактируется.
Access 2000:
Создаю запрос где-то на форме
qry:=TQuery.Create(self);
Присваиваю alias из BDE
qry.DatabaseName:=Alias;
Добавляю SQL
qry.SQL.Add(select * from tblname);
qry.Open;
Устанавливаю свойство RequestLive
qry.RequestLive:=true;
Пытаюсь изменить значение в поле Field1
qry["Field1"]:=SomeVariant;
не выходит
Ты говоришь можно редактировать, а как? Может я что-то не так делаю?


 
ЮЮ   (2002-08-28 11:40) [22]

Неужели qry["Field1"]:=SomeVariant;
Может всё-таки qry["Field1"] .Value:=SomeVariant;


 
juster   (2002-08-28 11:49) [23]

Не совсем правильно, перед изменением значения в поле
qry["Field1"]:=SomeVariant;
делаю qry.Edit;
и уже на этом этапе возникает ошибка
can not modify a read-only dataset


 
juster   (2002-08-28 11:51) [24]

А насчет
Неужели qry["Field1"]:=SomeVariant;
Может всё-таки qry["Field1"].Value:=SomeVariant;
то это по моему одно и то же


 
ЮЮ   (2002-08-28 12:06) [25]

Устанавливаю свойство RequestLive
qry.RequestLive:=true;
А оно устанавливается? qry.RequestLive:=true - это только попытка установить. Если невозможно, то останется False.

И, вообще, с Access лучше работать чере ADO через Microsoft.Jet.OLEDB.4.0


 
NDeu   (2002-08-28 12:16) [26]

Value is default property


 
juster   (2002-08-28 12:34) [27]

Сомневаюсь что через ADO будет быстрее


 
ЮЮ   (2002-08-28 12:47) [28]

А через BDE - ODBC будет лучше? Я уже полчаса пытаюсь подключиться в базе через БДЕ - нbкак не могу :-( А через ADO - Пять секунд настройки TAdoConnection


 
juster   (2002-08-28 12:57) [29]

Настройки может быть, но когда уже знаешь - подключаешься как по маслу даже в runtime. И насколько я знаю ADO работает медленне чем SQL Links


 
juster   (2002-08-28 12:59) [30]

может помогу тебе, спрашивай.


 
ЮЮ   (2002-08-28 13:19) [31]

А чего спрашивать?
1)В BDE Admine создаю алиас, тип Microsoft Access Driver (*.mdb)
Указываю DataBase Name.
Подключаюсь: Invalid configuration parameter.
2) Создаю DNS
Редактирую алиас, указывая DNS
3) Кладем DataBase. Подключаемся.OK.
Кладем Query,DataSource,DBGrid - Подключаем, в Design - OK
Запускаем - General SQL error.Слишком мало параметров. Требуется 1.
Кому требуется. После отключения Query в Design - та же ошибка и в Design



 
Alex Y   (2002-08-28 13:36) [32]

Не знаю в 97 Access-е будет работать или нет, но в 2000:

Select top 1 f1,f2,f3 From q Group By f2,f1,f3

А насчет редактирования, если простой запрос то с редактирование нет проблем как в ADO, так и в BDE. Если же используешь Group, то только ReadOnly.


 
juster   (2002-08-28 14:09) [33]

К ЮЮ.
Это что-то не то, че-то ты там намутил.
Сделай так:
не создавай алиас в BDE, создай в ODBC DSN, BDE его сам подхватит.
После этого можешь делать то же самое и LoginPromt в false - может из за этого. Еще можно попробовать в TDataBase.Params задать. Пиши подробней, сколько с базами не работал, никогда такого не было.


 
Alex Y   (2002-08-29 06:01) [34]

procedure TForm1.Button1Click(Sender: TObject);
var db : tDatabase;
begin
db := tDatabase.Create(nil);
db.AliasName := "AccessAlias"; // Создается в ODBC Manager (не в BDE !!!)
db.DatabaseName := "asd";
db.LoginPrompt := False;
with tQuery.Create(nil) do
begin
DatabaseName := db.DatabaseName;
RequestLive := True;
SQL.Add("Select * From MyTable");
Open;
First;
Edit;
FieldByName("f1").AsString := "2";
Post;
Close;
Free;
end;
db.Close;
db.Free;
end;



 
ЮЮ   (2002-08-29 07:11) [35]

Если у запроса RequestLive=False, то он открывается, а если True,
то General SQL error.Слишком мало параметров. Требуется 1.


 
Alex Y   (2002-08-29 07:15) [36]

Опиши запрос. Если в нем есть агрегатные функции то так и должнобыть и редактировать его не получится


 
ЮЮ   (2002-08-29 07:27) [37]

select * from Тур - это всё :-)


 
Alex Y   (2002-08-29 07:35) [38]

Тогда должно работать.

1. Заходишь в BDE Admin и срубаешь свой Alias
2. Заходишь в ODBC Admin
3. На вкладке User DNS - Add - Driver do Mivrosoft Access (*.mdb)
4. Вводишь имя источника данных
5. Нажимаешь выбрать и указываешь свой файл Access

Все.

У меня так работает без проблем.


 
ЮЮ   (2002-08-29 07:56) [39]

Cделал всё с нуля, результат тот же :-(


 
Alex Y   (2002-08-29 08:06) [40]

Тогда попробуй драйвер Microsoft Access Driver (*.mdb)
У меня он тоже работает.

А вообще лучше ADO использовать там даже запосы с агрегатными функциями редактируемые :)


 
juster   (2002-08-29 12:30) [41]

то ЮЮ
Для твоей проблемы предлагаю 2 варианта:
Создание алиаса
1.
a. Закрываешь Дельфу с проектом если она открыта.
б. Запускаешь odbcad32.exe
в. Делаешь DSN на базе Microsoft Access Driver (*.mdb)
г. Здесь можно остановиться, при следующем запуске bdeadmin
твой odbc DSN bde подхватит как свой алиас.
2. С шага г в 1
а. В bde admin зайди на вкладку configuration+drivers+odbc
и создай новый драйвер на базе твоего odbc DSN
б. Перейди на вкладку Databases и создай новый алиас в качестве
драйвера выбирай только что созданный в а
в. Заполни все поля database, name user name и т. д.
Запусти дельфу с проектом, в TDatabase попробуй законектиться,
если не получается, пропиши в параметрах
USERNAME=yourlogin
PASSWORD=yourpassword
свойство
LoginPrompt в false
Если тебе удалось законектиться в дезайн тайм, а в рантайм ошибка - значит на момент обращения компонент владеющий DataBase не создан, посмотри последовательность создания и уничтожения компонентов

Все сделаешь правильно - будет работать 100%



Страницы: 1 2 вся ветка

Форум: "Базы";
Текущий архив: 2002.09.19;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.55 MB
Время: 0.006 c
1-61143
race1
2002-08-30 12:41
2002.09.19
рисование


1-61052
liho26
2002-09-08 16:15
2002.09.19
Вот понять не могу!


14-61293
Mikhail
2002-08-23 20:27
2002.09.19
Каюк монитору


3-60967
Shtukatur
2002-08-28 19:41
2002.09.19
Как сортировать lookup поля?


3-60962
juster
2002-08-28 18:58
2002.09.19
Навигация по набору данных





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский