SQL ORDER BY问题

时间:2009-05-02 13:56:43

标签: sql plsql

重复此question,它本身交叉引用同一问题的其他3个小变体。


大家好,

我很抱歉,但我在这篇文章中将我的问题作为一个新问题。我现在非常需要你的帮助,我非常感谢你的帮助

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'。我们可以看到它评估为常量,然后是ORDER BY子句中的其余列。

现在,当变量sort_key:='description'或'memberCount'....每个值, 那么ORDER BY LOGIC对于每一个都是不同的。

例如,当选择'description'时,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变量获取的每个选项 - ORDER BY逻辑都是不同的,我现在必须在同一个SQL中实现它。

如果可以通过CASE订购所有选项 - 你可以帮助我。我需要你的 非常帮助

1 个答案:

答案 0 :(得分: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子句构建查询并执行该操作。

编辑:我的PL / SQL有点生疏,但这里是如何使用动态SQL在PL / 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;