Порядок SQL по продолжению проблемы - PullRequest
1 голос
/ 30 апреля 2009

Эта проблема является продолжением моего более раннего запроса . Это все еще не работает. Это о предложении ORDER BY. Я пытаюсь отсортировать, используя переменную "sortby".

Здесь, теперь предложение ORDER BY выбрано в качестве отдельного столбца с помощью функции DECODE () (, как предложено в ответе @devio в исходной версии этого вопроса ).

Давайте скажем, что sortby = by memberCount ’, в этом случае я передал его в качестве первого аргумента в decode (); memberCount - КОЛОННА в таблице grptest.

select distinct gl.group_id,
       decode('memberCount', 'name',        gl.group_name_key,
                             'description', gl.group_description_key,
                             'memberCount', gl.member_count)
             as p_sortby,
       gl.group_name,
       gl.group_description,
       gl.status_code,
       gl.member_count,
       (select grpp.group_name
           from grptest_relationship grel join grptest grpp
                   on grel.parent_group_id = grpp.group_id
           where grel.child_group_id = gl.group_id) as parent_group_name,
       gl.group_name_key,
       gl.group_description_key
   from grptest gl
   where gl.group_org_id = '3909'
     and (gl.group_name_key like '%' || 'GROUP' || '%')
order by 2;

Это не работает.

Но если я передам 'name' в качестве первого аргумента в декодировании выше, это сработает. Это мой оригинальный вопрос о том, почему он не распространяется на memberCount.

Ответы [ 2 ]

2 голосов
/ 30 апреля 2009

Я прокомментировал:

Какую ошибку вы получаете? Или какое ошибочное поведение вы получаете? При адаптации вашего вопроса к моей базе данных я должен был убедиться, что числовой столбец был преобразован в символьный тип, прежде чем DECODE () был приемлемым - остальные два столбца были символьными столбцами. После того, как это сделано, и с незначительной проблемой, что сортировка чисел в алфавитном порядке ставит «8» после «79» и до «80», я получил соответствующий результат.

Рохит спросил:

Спасибо за вклад. Я предполагаю, что меня смущает незначительная проблема, о которой вы упомянули: «эта сортировка чисел в алфавитном порядке ставит« 8 »после« 79 »и до« 80 »». Я не мог понять, что здесь? Кроме того, не могли бы вы помочь в моем запросе о том, как «обеспечить преобразование числового столбца в символьный тип до того, как DECODE () будет приемлемым». Можете ли вы изменить мой запрос выше в этом отношении?


Таблица, которую я использовал для таблицы элементов:

-- Tables for storing information about chemical elements and chemical compounds
-- See: http://www.webelements.com/ for elements.
-- See: http://ie.lbl.gov/education/isotopes.htm for isotopes.

CREATE TABLE elements
(
    atomic_number   INTEGER NOT NULL UNIQUE
                    CHECK (atomic_number > 0 AND atomic_number < 120),
    symbol          CHAR(3) NOT NULL UNIQUE,
    name            CHAR(20) NOT NULL UNIQUE,
    atomic_weight   DECIMAL(8,4) NOT NULL,
    stable          CHAR(1) DEFAULT 'Y' NOT NULL
                    CHECK (stable IN ('Y', 'N'))
);

Это интересная таблица, поскольку в ней есть три подлинных ключа-кандидата (атомный номер, имя и символ каждый являются уникальными), и в зависимости от контекста (изотопы или химические вещества) лучше использовать атомный номер или символ в качестве присоединяющего ключа.

Я использовал следующие запросы:

select decode('atomic_number',
                    'name',          name,
                    'symbol',        symbol,
                    'atomic_number', atomic_number||''),
        name, symbol, atomic_number
    from elements
    order by 1;

select decode('name',
                    'name',          name,
                    'symbol',        symbol,
                    'atomic_number', atomic_number||''),
        name, symbol, atomic_number
    from elements
    order by 1;

select decode('symbol',
                    'name',          name,
                    'symbol',        symbol,
                    'atomic_number', atomic_number||''),
        name, symbol, atomic_number
    from elements
    order by 1;

Они продемонстрировали три порядка: по символу, по имени и по атомному номеру.

Часть набора результатов для заказа атомного номера была:

77      Iridium         Ir      77
78      Platinum        Pt      78
79      Gold            Au      79
8       Oxygen          O       8
80      Mercury         Hg      80
81      Thallium        Tl      81

Поскольку атомный номер был приведен в строку, сортировка выполнялась в строковом порядке, и при рассмотрении в виде строки «8» появляется после «79» и до «80», как показано. Один из способов избежать этой проблемы:

select decode('atomic_number',
                    'name',          name,
                    'symbol',        symbol,
                    'atomic_number', lpad(atomic_number, 3)),
        name, symbol, atomic_number
    from elements
    order by 1;

Создание следующего (которое, хотя и не очевидно, имеет дополнительный пробел в начале первого столбца):

 77     Iridium         Ir      77
 78     Platinum        Pt      78
 79     Gold            Au      79
 80     Mercury         Hg      80
 81     Thallium        Tl      81
 82     Lead            Pb      82

При этом используется знание, что пробел предшествует любой цифре в последовательности сортировки (ASCII, Latin-1, Unicode), и что атомные номера не более 3 цифр. В качестве альтернативы я мог бы использовать «LPAD(atomic_number, 3, '0')» для заполнения нуля данных. Я протестировал с IBM Informix Dynamic Server (IDS) 11.50.FC3W2 на Solaris 10. IDS очень терпимо относится к несоответствиям типов и автоматически преобразует аргумент atomic_number в LPAD в строку. Другие СУБД могут быть не так терпимы; вам нужно явно привести значение.

Возвращаясь к вопросу ...

Предполагая, что memberCount - это числовой столбец, а значения не длиннее 4 цифр (корректируйте, если они длиннее), запрос можно записать так:

select distinct gl.group_id,
       decode('memberCount', 'name',        gl.group_name_key,
                             'description', gl.group_description_key,
                             'memberCount', LPAD(gl.member_count, 4))
             as p_sortby,
       gl.group_name,
       gl.group_description,
       gl.status_code,
       gl.member_count,
       (select grpp.group_name
           from grptest_relationship grel join grptest grpp
                   on grel.parent_group_id = grpp.group_id
           where grel.child_group_id = gl.group_id) as parent_group_name,
       gl.group_name_key,
       gl.group_description_key
   from grptest gl
   where gl.group_org_id = '3909'
     and (gl.group_name_key like '%' || 'GROUP' || '%')
order by 2;

Или вам может понадобиться:

LPAD(CAST(memberCount AS CHAR(4)), 4)

или какое-то другое слегка специфичное для СУБД заклинание, которое достигает того же общего эффекта.

Поскольку вы не предоставили схему (а тем более примерные данные) для запроса, у меня нет вашей таблицы в моей базе данных, поэтому я не могу продемонстрировать ваш запрос работающим

0 голосов
/ 30 апреля 2009

Я знаю, что

order by p_sortby

не сработает, но не могли бы вы попробовать

order by decode('memberCount', 
  'name', gl.group_name_key,
  'description', gl.group_description_key, 
  'memberCount', gl.member_count)

EDIT:

Я вспомнил другой путь:

select * from (
  select column1, decode(....) as column2, .... from table1
) t1
order by 2

и этот способ может быть даже быстрее

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...