[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Запрос по postgresSQL
daemon
Здравствуйте, нужна помощь
Нужно перевести запрос с mysql на postgresSQL

Вот запрос mysql:

SELECT * FROM catalog WHERE (1=1)parent = 22140 AND visible = "true" AND type = 1 group by name ORDER BY name ASC LIMIT 0, 30



Спустя 2 минуты, 36 секунд (1.07.2009 - 23:52) kirik написал(а):
а что за "(1=1)"? Этот запрос должен работать в постгре..

SQL
SELECT * FROM `catalog` WHERE `parent` = 22140 AND `visible` = "true" AND `type` = 1 GROUP BY `name` ORDER BY `name` ASC LIMIT 0, 30

Спустя 2 минуты, 11 секунд (1.07.2009 - 23:54) daemon написал(а):
Ну (1=1) можно удалить))
После него еще должно идти AND (забыл просто)

Да ладно, это не столь важно
Нужно переделать запрос
SQL
SELECT * FROM catalog WHERE parent = 22140 AND visible = "true" AND type = 1 group by name ORDER BY name ASC LIMIT 0, 30

Спустя 2 минуты, 15 секунд (1.07.2009 - 23:56) daemon написал(а):
Ну в постре запрос который содержит косые кавычки не идет...(((
И проблема касаеться именно той части где group by name
Как только удалю все гуд

Спустя 30 минут, 33 секунды (2.07.2009 - 00:27) kirik написал(а):
Спец по постгре сейчас спит наверное smile.gif Завтра получишь ответ smile.gif

Спустя 7 часов, 42 минуты, 9 секунд (2.07.2009 - 08:09) sergeiss написал(а):
Цитата (kirik @ 2.07.2009 - 01:27)
Спец по постгре сейчас спит наверное

Надо по ночам иногда и спать, наверное smile.gif

daemon - для переделки запроса надо определиться, что же ты хочешь получить.
Твой запрос не работает потому, что ты не объяснил толком (не нам, а базе данных smile.gif), что же ты хочешь. Выбор через * всех полей тут не будет работать, это нормально.

Группируешь ты по имени, но не говоришь, что делать с другими полями.

Я не знаю структуру твоей таблицы, поэтому предположим, что там есть название (name) и цена (price). То есть, для одинаковых имен есть разные цены.

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

SQL
SELECT name, min(price) as min_price, max(price) as max_price, avg(price) as avg_price
FROM catalog WHERE parent = 22140 AND visible = "true" AND type = 1
group by name
ORDER BY name
ASC LIMIT 0, 30


Ну, а дальше, если поймешь принцип, сделаешь сам всё, что тебе нужно.

Спустя 11 часов, 55 минут, 32 секунды (2.07.2009 - 20:05) daemon написал(а):
Отлично, работает
Только проблемка, у выборке только name, а ка сделать чтоб у выборке были все ячейки?
Мне как бы нужно еще у выборке 3-4 поля

Спустя 1 час, 29 минут, 39 секунд (2.07.2009 - 21:34) kirik написал(а):
Цитата (daemon @ 2.07.2009 - 12:05)
а ка сделать чтоб у выборке были все ячейки?
Мне как бы нужно еще у выборке 3-4 поля

Ну как бы перечисли просто нужные поля через запятую
SQL
SELECT name, age, location, gender FROM catalog WHERE ....

Спустя 16 минут, 54 секунды (2.07.2009 - 21:51) sergeiss написал(а):
Ежели ты хочешь указать еще какие-то колонки, то укажи их в списке! И сделай это как сразу после SELECT, так и в GROUP BY.
Например, у тебя есть имя товара (name), его цена (price), и еще дополнительный код (code), который разбивает каждый товар на набор уникальных групп.
Тогда предыдущий запрос перепишется так (я только лимит убрал, чтобы он не загромождал место):
SQL
SELECT name, code, min(price) as min_price, max(price) as max_price, avg(price) as avg_price
FROM catalog WHERE parent = 22140 AND visible = "true" AND type = 1
GROUP BY name, code
ORDER BY name ASC

При этом будут выбраны все группы строк, содержащие уникальные комбинации имени товара и его кода. И так далее, для любых параметров. Вплоть до того, что ты можешь указать все имеющиеся ячейки. Это приведет к тому, что будут выбраны все из имеющихся уникальных комбинаций всех параметров. Если это твоя задача - тогда ОК.
Учти, что ты НЕ МОЖЕШЬ указать звёздочку в GROUP BY, там надо перечислять в явном виде поля, по которым идет группировка.

Но у меня есть одно смутное подозрение... Лучше скажи, что ты хочешь получить, какой результат. Какие еще поля есть в таблице, которые ты хочешь вывести. Возможно, что тебе нужен не GROUP BY, а другие средства?

PS. kirik - хочу обратить особое внимание, что эти же поля надо перечислить в GROUP BY!!!

Спустя 12 минут, 8 секунд (2.07.2009 - 22:03) daemon написал(а):
Но просто как бы в GROUP BY перечисляться поля по которым идет группировка, а мне нужно чтоб группировка была только по name!, а у выборке должны быть еще 3-4 поля

SQL
name varchar(255) NOT NULL default '',
short_description text NOT NULL,
full_description text NOT NULL,
parent integer NOT NULL default '0',
type integer NOT NULL default '0',
price float NOT NULL default '0',


Вот те поля которые нужны при выборке из таблицы

Спустя 5 минут, 40 секунд (2.07.2009 - 22:09) sergeiss написал(а):
Цитата (daemon @ 2.07.2009 - 23:03)
Но просто как бы в GROUP BY перечисляться поля по которым идет группировка, а мне нужно чтоб группировка была только по name!

А что будет делать Постгре с другими полями, которые не попали в выборку? Как их обрабатывать?

Или ты хочешь сделать некоторую выборку с потерей данных в тех полях, которые не попали в список?

Допустим, ты делаешь группировку только по полю name (попадают по 3-5 строк), но хочешь выводить name и short_description? Причем так, что бы только одно произвольное short_desctiption было в выборке? Если да, то для этого есть другие средства.

Спустя 4 минуты, 40 секунд (2.07.2009 - 22:14) daemon написал(а):
Мне нужна данные сгруппированные по name, но выборка должна также включать и еще несколько полей:

SQL
name varchar(255) NOT NULL default '',
short_description text NOT NULL,
full_description text NOT NULL,
parent integer NOT NULL default '0',
type integer NOT NULL default '0',
price float NOT NULL default '0',


Остальные поля в принципе не нужны, главное чтобы были эти

Спустя 6 минут, 27 секунд (2.07.2009 - 22:20) sergeiss написал(а):
Я еще раз повторю. Что делать с теми полями, которые будут разные для одинаковых имен?
Например, у тебя будут 2 такие записи:
(name, short_description, type, price)
('Suzuki', 'SX4',5,400000)
('Suzuki','SGV',3,500000)

Ну хорошо. Сгруппировали мы по имени 'Suzuki'. Нашли среднюю для группы и суммарную цены. А что делать с коротким описанием и типом, что ты хочешь получить в итоговой записи, которая будет всего лишь? Любую величину, т.е. либо 'SX4', либо 'SGV', и тип либо 3, либо5?
Или там должна быть не любая, а определенная величина из этих? Или надо найти "средний" тип?

А может, ты просто хочешь получить произвольную строку?

Спустя 5 минут, 10 секунд (2.07.2009 - 22:25) daemon написал(а):
одну выборку, где максимальная цена

SQL
SELECT name, max(price) as max_price
FROM catalog WHERE parent = 22140 AND visible = "true" AND type = 1
GROUP BY name
ORDER BY name ASC


Вот ваш запрос, но просто при выборке я получаю только поле name, а мне просто еще нужно еще несколько полей...вот и вся проблема

Спустя 19 минут, 22 секунды (2.07.2009 - 22:45) sergeiss написал(а):
Тогда забудь про GROUP BY!

SQL
SELECT DISTINCT ON (name) *
FROM catalog WHERE parent = 22140 AND visible = "true" AND type = 1
ORDER BY name, price DESC

Этот запрос сделает следующее:
1. Разобъет всю информацию на блоки, в каждом блоке будет уникальный name.
2. Внутри каждого блока отсортирует в обратном порядке по цене, т.е. максимальная цена будет в самом верху. Именно эта запись и попадет в итоговую выборку.
3. Полученные записи отсортирует по name.

Спустя 7 минут, 31 секунда (2.07.2009 - 22:52) daemon написал(а):
оно laugh.gif , спасибо за помощь

Спустя 1 день, 12 часов, 19 минут, 18 секунд (4.07.2009 - 11:11) daemon написал(а):
Извините, не посмотрел вовремя, есть еще проблемка

Нужно следующее:
Запрос, который вы написали правильный и точно то что мне нужно

SQL
SELECT name
FROM catalog WHERE parent = '22140' AND visible = 'true' AND type = '1'
GROUP BY name
ORDER BY name ASC


Вот и проблемка, у выборке только поле name.

SQL
SELECT DISTINCT ON (name) *
FROM catalog WHERE parent = 22140 AND visible = "true" AND type = 1
ORDER BY name


Запрос, который описаний выше при выборке иногда появляться одинаковые name, а я хочу чтоб у выборке должны быть уникальные name, чтоб не было повторения name.

В принципе в запросе нужно только сортировка по name, а по price не нужно.

Спустя 1 день, 11 часов, 42 минуты, 14 секунд (5.07.2009 - 22:54) sergeiss написал(а):
По последнему указанному тобой запросу появляются дублированные имена (name)??? Быть того не может!
Ты же в самом начале говоришь, что тебе нужны уникальные name, там не может быть дублирования.

Проверь, нет ли в "дублированных" именах различий типа русские/английские буквы или что-то в этом духе.

Спустя 8 часов, 8 минут, 7 секунд (6.07.2009 - 07:02) glock18 написал(а):
daemon
клауза GROUP BY исключает дублирование

Спустя 1 час, 15 минут, 57 секунд (6.07.2009 - 08:18) sergeiss написал(а):
Цитата (glock18 @ 6.07.2009 - 08:02)
клауза GROUP BY исключает дублирование

В Постгре есть другая "фишка", которая и используется в данном случае: "DISTINCT ON (name)", т.е. выбрать уникальные имена. Тем более, что надо выбрать все параметры, а сгруппировать по одному из них. Поэтому GROUP BY тут не поможет, а только навредит.

Спустя 21 минута, 47 секунд (6.07.2009 - 08:39) glock18 написал(а):
sergeiss
Я знаю об этой фишке. В postgre distinct подходит для этого лучше, но group by тут ничем не навредит.

PS: я так и не понял какой из приведенных запросов не работает как надо... по-моему, оба должны возвращать одно и то же.

Спустя 20 минут, 17 секунд (6.07.2009 - 09:00) sergeiss написал(а):
Цитата (glock18 @ 6.07.2009 - 09:39)
Я знаю об этой фишке. В postgre distinct подходит для этого лучше, но group by тут ничем не навредит.

Он не то, чтобы "навредит"... Но просто если ты вместо
SQL
//ДОЛЖНО РАБОТАТЬ ИДЕАЛЬНО
SELECT DISTINCT ON (name) *
FROM catalog WHERE parent = 22140 AND visible = "true" AND type = 1
ORDER BY name



напишешь что-то типа

SQL
// ТУТ ПОЛУЧИШЬ БОЛЬШУЮ И ЖИРНУЮ ОШИБКУ
SELECT DISTINCT ON (name) *
FROM catalog WHERE parent = 22140 AND visible = "true" AND type = 1
GROUP BY name
ORDER BY name


Ошибка (ее суть) будет гласить о том, что ты выбираешь колонки, которые не включил в группировку.

Спустя 20 минут, 37 секунд (6.07.2009 - 09:20) glock18 написал(а):
эээ... насколько я помню, стандарт sql: нельзя включать в GROUP BY колонки, которых нет в SELECT. а не наоборот.

по-моему, ты путаешь, потому что это странное вообще говоря требование. а может и я путаю - mysql в этом случае гораздо более либерален smile.gif

Спустя 19 минут, 32 секунды (6.07.2009 - 09:40) sergeiss написал(а):
Насчет стандартов не знаю, но вот тебе пример из Постгре.

Таблица:
SQL
CREATE TABLE table2
(
id integer,
field1 character(10),
field2 character(10)
)

В поле field1 занесены произвольные данные, а в поле field2 занесены данные из ограниченного набора, всего несколько штук. Всего записей очень много, сто тысяч (таблица - в тестовой базе, как раз для тестирования всяких "извратов" smile.gif).

Следующий запрос выдает результат, который ожидается.
SQL
SELECT DISTINCT ON (field2) *
FROM table2 ORDER BY field2 desc


Можно извращаться с сортировкой, например:
SQL
ORDER BY field2, random()
ORDER BY field2, field1

и разные другие варианты - результаты финальной выборки будут разные, но полностью ожидаемые.

А вот такой запрос
SQL
SELECT DISTINCT ON (field2) *
FROM table2 GROUP BY field2
ORDER BY field2

выдает ошибку
Код
ERROR:  column "table2.id" must appear in the GROUP BY clause or be used in an aggregate function

********** Ошибка **********

ERROR: column "table2.id" must appear in the GROUP BY clause or be used in an aggregate function
SQL state: 42803

Спустя 4 минуты, 55 секунд (6.07.2009 - 09:45) glock18 написал(а):
ладно, давно понял, что со знатоком postgre спорить мне пока рано smile.gif

я, это... так, вставил свое скромное слово просто... rolleyes.gif

Спустя 6 минут, 24 секунды (6.07.2009 - 09:51) sergeiss написал(а):
"Я не волшебник, я пока только учусь" (с) smile.gif

Но я прежде, чем выкладывать код, обычно его проверяю.
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.