Thread: Сортировка в требуемом порядке
Есть такой запрос:
Select * from foo where catalog_id IN(2,3,6,1,4,66,44,23,45)
Возможно ли вывести результат в таком же порядке, как и условие в IN, тоесть первый елемент с catalog_id == 2, второй - catalog_id == 3, третий - catalog_id == 6, четвертый - catalog_id == 1 и т.д.
Select * from foo where catalog_id IN(2,3,6,1,4,66,44,23,45)
Возможно ли вывести результат в таком же порядке, как и условие в IN, тоесть первый елемент с catalog_id == 2, второй - catalog_id == 3, третий - catalog_id == 6, четвертый - catalog_id == 1 и т.д.
ОйВв> Есть такой запрос: ОйВв> Select * from foo where catalog_id IN(2,3,6,1,4,66,44,23,45) ОйВв> Возможно ли вывести результат в таком же порядке, как и условие в IN, тоесть ОйВв> первый елемент с catalog_id == 2, второй - catalog_id == 3, третий ОйВв> - catalog_id == 6, четвертый - catalog_id == 1 и т.д. скорее всего нет. когда таблица просматривается на предмет выборки строк то проверяется условие WHERE, а то в каком порядке это условие написано роли не играет, важно TRUE/FALSE ли оно возвращает. можно сортирнуть в хранимой процедуре или после выборки, имхо -- . ''`. Dmitry E. Oboukhov : :’ : email: unera@debian.org jabber://UNera@uvw.ru `. `~’ GPGKey: 1024D / F8E26537 2006-11-21 `- 1B23 D4F8 8EC0 D902 0555 E438 AB8C 00CF F8E2 6537
Attachment
Приветствую,
В этом примере foo - исходная таблица с данными,
id - псевдотаблица с 2-мя столбцами: значение (собственно id)
и его порядковый номер.
--
// Dmitriy.
14 марта 2011 г. 17:20 пользователь Олекс й Василь в <leopard_ne@inbox.ru> написал:
Есть такой запрос:
Select * from foo where catalog_id IN(2,3,6,1,4,66,44,23,45)
Возможно ли вывести результат в таком же порядке, как и условие в IN, тоесть первый елемент с catalog_id == 2, второй - catalog_id == 3, третий - catalog_id == 6, четвертый - catalog_id == 1 и т.д.
Данную задачу можно решить, заменив IN на JOIN, например:
dmitigr=>
SELECT foo.* FROM (VALUES(1),(2),(3),(4),(6)) AS foo(catalog_id)
JOIN (SELECT id.val, row_number() over() FROM (VALUES(3),(2),(6),(1),(4)) AS id(val)) AS id
ON (foo.catalog_id = id.val) ORDER BY row_number;
catalog_id
------------
3
2
6
1
4
dmitigr=>
SELECT foo.* FROM (VALUES(1),(2),(3),(4),(6)) AS foo(catalog_id)
JOIN (SELECT id.val, row_number() over() FROM (VALUES(3),(2),(6),(1),(4)) AS id(val)) AS id
ON (foo.catalog_id = id.val) ORDER BY row_number;
catalog_id
------------
3
2
6
1
4
В этом примере foo - исходная таблица с данными,
id - псевдотаблица с 2-мя столбцами: значение (собственно id)
и его порядковый номер.
--
// Dmitriy.
DI> 14 марта 2011 г. 17:20 пользователь Олекс й Василь в <leopard_ne@inbox.ru> DI> написал: DI> Есть такой запрос: DI> Select * from foo where catalog_id IN(2,3,6,1,4,66,44,23,45) DI> Возможно ли вывести результат в таком же порядке, как и условие в IN, DI> тоесть первый елемент с catalog_id == 2, второй - catalog_id == 3, третий DI> - catalog_id == 6, четвертый - catalog_id == 1 и т.д. DI> Данную задачу можно решить, заменив IN на JOIN, например: DI> dmitigr=> DI> SELECT foo.* FROM (VALUES(1),(2),(3),(4),(6)) AS foo(catalog_id) DI> JOIN (SELECT id.val, row_number() over() FROM (VALUES(3),(2),(6),(1),(4)) AS DI> id(val)) AS id DI> ON (foo.catalog_id = id.val) ORDER BY row_number; DI> catalog_id DI> ------------ DI> 3 DI> 2 DI> 6 DI> 1 DI> 4 кстати unnest как-то даже покороче выглядит SELECT foo.* FROM unnest('{3,2,6,1,4}'::int[]) idt JOIN foo ON catalog_id = idt WHERE foo.id IS NOT NULL; и от сортировки можно избавиться хотя может оптимизатор ее и сам выбросит. DI> В этом примере foo - исходная таблица с данными, DI> id - псевдотаблица с 2-мя столбцами: значение (собственно id) DI> и его порядковый номер. -- . ''`. Dmitry E. Oboukhov : :’ : email: unera@debian.org jabber://UNera@uvw.ru `. `~’ GPGKey: 1024D / F8E26537 2006-11-21 `- 1B23 D4F8 8EC0 D902 0555 E438 AB8C 00CF F8E2 6537
Attachment
On 22:22 Mon 14 Mar , Dmitry E. Oboukhov wrote: DI>> 14 марта 2011 г. 17:20 пользователь Олекс й Василь в <leopard_ne@inbox.ru> DI>> написал: DI>> Есть такой запрос: DI>> Select * from foo where catalog_id IN(2,3,6,1,4,66,44,23,45) DI>> Возможно ли вывести результат в таком же порядке, как и условие в IN, DI>> тоесть первый елемент с catalog_id == 2, второй - catalog_id == 3, третий DI>> - catalog_id == 6, четвертый - catalog_id == 1 и т.д. DI>> Данную задачу можно решить, заменив IN на JOIN, например: DI>> dmitigr=> DI>> SELECT foo.* FROM (VALUES(1),(2),(3),(4),(6)) AS foo(catalog_id) DI>> JOIN (SELECT id.val, row_number() over() FROM (VALUES(3),(2),(6),(1),(4)) AS DI>> id(val)) AS id DI>> ON (foo.catalog_id = id.val) ORDER BY row_number; DI>> catalog_id DI>> ------------ DI>> 3 DI>> 2 DI>> 6 DI>> 1 DI>> 4 Tprgpo> кстати unnest как-то даже покороче выглядит Tprgpo> SELECT Tprgpo> foo.* Tprgpo> FROM Tprgpo> unnest('{3,2,6,1,4}'::int[]) idt Tprgpo> JOIN Tprgpo> foo ON catalog_id = idt Tprgpo> WHERE Tprgpo> foo.id IS NOT NULL; WHERE конечно же не нужен, WHERE это если LEFT JOIN :) -- . ''`. Dmitry E. Oboukhov : :’ : email: unera@debian.org jabber://UNera@uvw.ru `. `~’ GPGKey: 1024D / F8E26537 2006-11-21 `- 1B23 D4F8 8EC0 D902 0555 E438 AB8C 00CF F8E2 6537
Attachment
Re: [pgsql-ru-general] Re: [pgsql-ru-general] Сортировка в требуемом порядке
From
Dmitriy Igrishin
Date:
14 марта 2011 г. 22:22 пользователь Dmitry E. Oboukhov <unera@debian.org> написал:
DI> 14 марта 2011 г. 17:20 пользователь Олекс й Василь в <leopard_ne@inbox.ru>
DI> написал:
DI> Есть такой запрос:
DI> Select * from foo where catalog_id IN(2,3,6,1,4,66,44,23,45)
DI> Возможно ли вывести результат в таком же порядке, как и условие в IN,
DI> тоесть первый елемент с catalog_id == 2, второй - catalog_id == 3, третий
DI> - catalog_id == 6, четвертый - catalog_id == 1 и т.д.
DI> Данную задачу можно решить, заменив IN на JOIN, например:
DI> dmitigr=>
DI> SELECT foo.* FROM (VALUES(1),(2),(3),(4),(6)) AS foo(catalog_id)
DI> JOIN (SELECT id.val, row_number() over() FROM (VALUES(3),(2),(6),(1),(4)) AS
DI> id(val)) AS id
DI> ON (foo.catalog_id = id.val) ORDER BY row_number;
DI> catalog_id
DI> ------------
DI> 3
DI> 2
DI> 6
DI> 1
DI> 4
кстати unnest как-то даже покороче выглядит
SELECT
foo.*
FROM
unnest('{3,2,6,1,4}'::int[]) idt
JOIN
foo ON catalog_id = idt
WHERE
foo.id IS NOT NULL;
и от сортировки можно избавиться
К сожалению, нигде не сказано, что unnest() обязан
вернуть набор элементов, сохраняя упорядоченность,
заданную в массиве. Предполагать и располагать -
суть разные подходы :-)
Кроме того, может возникнуть задача выбрать элементы
в обратном порядке.
вернуть набор элементов, сохраняя упорядоченность,
заданную в массиве. Предполагать и располагать -
суть разные подходы :-)
Кроме того, может возникнуть задача выбрать элементы
в обратном порядке.
хотя может оптимизатор ее и сам выбросит.
DI> В этом примере foo - исходная таблица с данными,
DI> id - псевдотаблица с 2-мя столбцами: значение (собственно id)
DI> и его порядковый номер.--
. ''`. Dmitry E. Oboukhov
: :’ : email: unera@debian.org jabber://UNera@uvw.ru
`. `~’ GPGKey: 1024D / F8E26537 2006-11-21
`- 1B23 D4F8 8EC0 D902 0555 E438 AB8C 00CF F8E2 6537
--
// Dmitriy.
Re: Re: [pgsql-ru-general] Re: [pgsql-ru-general] Сортировка в требуемом порядке
From
"Dmitry E. Oboukhov"
Date:
DI> К сожалению, нигде не сказано, что unnest() обязан DI> вернуть набор элементов, сохраняя упорядоченность, DI> заданную в массиве. Предполагать и располагать - DI> суть разные подходы :-) Вероятно Вы правы, однако мне крайне сложно представить себе реализацию функции преобразования матрицы вида [ 1 2 3 ] в матрицу вида [ 1 2 3 ] чтобы при этом мог пострадать порядок следования. это разве что специально что-то делать надо? DI> Кроме того, может возникнуть задача выбрать элементы DI> в обратном порядке. насколько я понимаю имеющуюся задачу - порядок приходит как результат работы чего-то там (юзерских выборок например) и, вероятно, в этом случае придет обратный же порядок на вход просто -- . ''`. Dmitry E. Oboukhov : :’ : email: unera@debian.org jabber://UNera@uvw.ru `. `~’ GPGKey: 1024D / F8E26537 2006-11-21 `- 1B23 D4F8 8EC0 D902 0555 E438 AB8C 00CF F8E2 6537
Attachment
On 15/03/11 08:22, Dmitry E. Oboukhov wrote: > > DI> 14 марта 2011 г. 17:20 пользователь Олекс й Василь в<leopard_ne@inbox.ru> > DI> написал: > > DI> Есть такой запрос: > DI> Select * from foo where catalog_id IN(2,3,6,1,4,66,44,23,45) > > DI> Возможно ли вывести результат в таком же порядке, как и условие в IN, > DI> тоесть первый елемент с catalog_id == 2, второй - catalog_id == 3, третий > DI> - catalog_id == 6, четвертый - catalog_id == 1 и т.д. > > DI> Данную задачу можно решить, заменив IN на JOIN, например: > > DI> dmitigr=> > DI> SELECT foo.* FROM (VALUES(1),(2),(3),(4),(6)) AS foo(catalog_id) > DI> JOIN (SELECT id.val, row_number() over() FROM (VALUES(3),(2),(6),(1),(4)) AS > DI> id(val)) AS id > DI> ON (foo.catalog_id = id.val) ORDER BY row_number; > DI> catalog_id > DI> ------------ > DI> 3 > DI> 2 > DI> 6 > DI> 1 > DI> 4 > > > кстати unnest как-то даже покороче выглядит > > SELECT > foo.* > > FROM > unnest('{3,2,6,1,4}'::int[]) idt > > JOIN > foo ON catalog_id = idt > Если оптимизатор выберет hashjoin или mergejoin вместо nested loop то порядок результатов в выдаче будет произволен. Лучше не использовать такой подход. PS: никакой запрос без order by не дает гарантированной сортировки. все ухищрения чтобы без этого обойтись или работают не всегда или могут перестать работать даже при смене минорной версии базы. -- SY, Maxim Boguk