2009-05-02 2 views
0

Дубликат этого question, который сам перекрестно ссылается на 3 других небольших варианта того же вопроса.SQL ORDER BY issue


Привет всем,

Я сожалею, но я ставлю на мой вопрос как новый вопрос в этом post.I нужна вся ваша помощь очень много сейчас, и я ценю вашу помощь очень

SELECT * 
    FROM (SELECT distinct gl.group_id, 
       gl.group_name, 
       gl.group_description, 
       gl.status_code, 
       gl.member_count, 
       (SELECT grpp.group_name 
         FROM test_group_relationship grel JOIN test_group 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 test_group AS gl 
      WHERE gl.group_org_id = '3909' 
       AND (gl.group_name_key LIKE '%GROUP%') 
     ) AS data_set 
    ORDER BY DECODE(:sort_key, 
         'name',   'constant', 
         'description',  group_description_key, 
         'memberCount',  LPAD(member_count, 4), 
         'status',   LPAD(status_code, 4), 
         'parentGroupName', parent_group_name 
       )NULLS FIRST, 
     UPPER(SUBSTR(group_name, 1, 1)), 
     SUBSTR(group_name, 1, 1) DESC, 
     UPPER(group_name), 
     group_name DESC, 
     group_name_key, 
     ; 

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

Когда, sort_key: = 'name'.As мы можем видеть, что он оценивает константу, а затем остальные столбцы в предложении ORDER BY.

Теперь, когда переменная sort_key: = 'description' или 'memberCount' .... каждое из значений, , то ORDER BY LOGIC различается для каждого из них.

В качестве примера, когда выбрано «описание» - сортировка в ORDER BY cluase должна выполняться так же, как и для «name».

Пример как это: -

UPPER(SUBSTR(group_description, 1, 1)), 
      SUBSTR(group_description, 1, 1) DESC, 
      UPPER(group_description), 
      group_description DESC, 
      group_description_key, 

Короче говоря, каждый из вариантов, что sort_key переменная получает, заказ по логике отличается, и я должен реализовать его в тот же SQL только сейчас.

Если его можно с помощью того, в случае со всеми опциями, пожалуйста, вы можете помочь me.I нужна ваша помощь очень

+0

Что не работает для вас? – tpdi

+0

дубликат http://stackoverflow.com/questions/804110/plsql-order-by-issue, который имеет различные ответы. К сожалению, OP не может указать, что не работает по желанию, кроме «не работает» (см. вопрос и комментарии) – devio

+0

btw это 5-ая версия его вопроса в течение 2 дней – devio

ответ

1

Если я вас правильно понимаю, вы просите, если это возможно, чтобы изменить весь ORDER BY динамически основывается на связанном параметре, включая изменения ASC/DESC и т. Д.

Лучше всего использовать разные запросы с разными ORDER BY в зависимости от того, как вы хотите сортировать. Это намного проще и будет работать быстрее.

Если вы действительно хотите сделать это так, как вы просите, вы можете сделать это в определенной степени, используя тот же метод, который вы уже используете с ORDER BY DECODE (choice1, expression1, choice2, expression2, ...), за исключением того, что выражения должны быть намного сложнее. Каждое выражение будет иметь для получения сцепленной строки полех фиксированного размера в порядке приоритета сортировки, например:

ORDER BY DECODE('description',  UPPER(SUBSTR(group_description, 1, 1)) 
           || SUBSTR(group_description, 1, 1) 
           || RPAD(UPPER(group_description),40) 
           || RPAD(group_description_key,10) 

       ,'name',   UPPER(SUBSTR(group_name, 1, 1)), 
           || LPAD(1000-ASCII(group_name)), -- first char DESC 
           || RPAD(UPPER(group_name),20) 
           || RPAD(group_name_key,10) 

Кроме того, было бы трудно смешивать ASC и DESC поля. Вы можете переключать направление для числовых полей, используя что-то вроде LPAD (1000000 - n, 7), где 1000000 - это число выше любого возможного n. Вы также можете играть в другие трюки, как в моем примере, с первым символом group_name.

Этот метод предотвратит использование базы данных индексами для ускорения заказа (если вы не добавите некоторые сумасшедшие функциональные индексы).

Опять же, я рекомендую отказаться от этого подхода и просто отправить в базу данных целый другой запрос в зависимости от вашего желаемого предложения ORDER BY. Если вы используете PL/SQL, вы также можете использовать динамический SQL для построения запроса с требуемым предложением ORDER BY и выполнить его.

EDIT: Мой PL/SQL немного ржавый, но вот как вы можете это сделать в PL/SQL с динамическим SQL.

FUNCTION QueryGroups(sort_key in varchar2) RETURN REF CURSOR 
IS 
    sql_block VARCHAR2(2000); 
    order_by VARCHAR2(2000); 
    ret REF CURSOR; 
BEGIN 
    order_by := 
    CASE sort_key 
     WHEN 'name' 
     THEN q'{UPPER(SUBSTR(group_name, 1, 1)), 
        SUBSTR(group_name, 1, 1) DESC, 
        UPPER(group_name), 
        group_name DESC, 
        group_name_key}'; 
     WHEN 'description' 
     THEN q'{UPPER(SUBSTR(group_description, 1, 1)), 
        SUBSTR(group_description, 1, 1) DESC, 
        UPPER(group_description), 
        group_description DESC, 
        group_description_key}'; 
    END CASE; 

    sql_block = q'{SELECT * 
       FROM (SELECT distinct gl.group_id, 
       gl.group_name, 
       gl.group_description, 
       gl.status_code, 
       gl.member_count, 
       (SELECT grpp.group_name 
         FROM test_group_relationship grel JOIN test_group 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 test_group AS gl 
      WHERE gl.group_org_id = '3909' 
       AND (gl.group_name_key LIKE '%GROUP%') 
     ) AS data_set }' || order_by; 

    OPEN ret for sql_block; 
    return ret; 
END QueryGroups; 
+0

Спасибо. Я могу понять вашу точку в вышеуказанном подходе. Кроме того, я пытался сделать это, используя заказ с помощью CASE, но он не запускается и дает ошибку «ключевое слово». – 2009-05-02 15:52:20

+0

ORDER BY ПРИМЕР \t \t КОГДА: p_sortby = 'имя' ТОГДА ВЕРХНИЙ (SUBSTR (имя_группы, 1, 1)), SubStr (имя_группы, 1, 1) по убыванию, ВЕРХНИЙ (имя_группы), group_name_key, имя_группы убыванию /* Вышеуказанное предложение THEN работает, если у меня только один аргумент после THEN. Он не работает, если у меня есть все аргументы. */ /* Он дает ошибку с отсутствием ключевого слова */ Я чувствую, что мой синтаксис неверен когда мы передаем много аргументов. Можете вы меня исправить? если я хочу передать РАЗЛИЧНЫЙ SQL по значению в порядке по переменной - как бы я его написал? Только один пример написания это поможет мне сделать другие – 2009-05-02 16:01:05

+0

Вы не можете сделать это так. Вещь после THEN должна быть единственным выражением, возвращающим одну строку. То же, что и выражения в DECODE. Это не может быть список столбцов. Внимательно прочитайте мой ответ. Посмотрите, как я соединяюсь с помощью ||. Но лучше всего, не пытайтесь делать это таким образом вообще. Вместо этого создайте запрос и его ORDER BY как строку и выполните ее с помощью динамического SQL. –