Sql返回列有“FirstName LastName”为1字符串如何按姓氏排序?

时间:2011-10-13 17:42:23

标签: sql oracle

我正在使用Oracle。我的sql返回一个像这样的列

名称:
约翰史密斯 大卫李 ...

如果我按名称订购,它将按名字排序。我如何按姓氏订购?如果我按姓氏排序,名字oracle将返回无效标识符。我试过substr,instr但它不起作用。我知道sql很乏味但只是想让数据快速解决这个问题。

完整SQL: http://pastebin.com/hYkdHBDM

4 个答案:

答案 0 :(得分:2)

你说你的SQL“以这种格式返回一列”。你的意思是列是存储那样,还是它存储为两个字段并在SQL语句中组成一个?

如果以这种方式存储,则很难创建一个算法,该算法可以可靠地确定多部分名称的哪个部分是姓氏部分(实际上,这有时取决于拥有该名称的人的个人偏好)。

如果存储在两个单独的字段中,您应该能够ORDER BY LastName,FirstName,具体取决于SQL的构造方式以及您和表之间是否存在任何中间视图。请发布SQL和表结构。

答案 1 :(得分:1)

Matthew PK所说的是正确的,但他没有提到INSTR可以向后解析,在这种情况下,他的“失败”情景将得到解决。

这里试试这个:

create table test_name (f_name varchar2(20), l_name varchar2(20), full_name varchar2(20));
insert into test_name (f_name, l_name, full_name) values ('John', 'Mellencamp', 'John 2Mellen');
insert into test_name (f_name, l_name, full_name) values ('John', 'Mellencamp', 'John C. 1Mellen');
select f_name, l_name, substr(full_name,instr(full_name,' ',-1,1)) as substr, full_name from test_name order by substr(full_name,instr(full_name,' ',-1,1));

基本上拍摄的钱是: substr(full_name,instr(full_name,'', - 1,1))

答案 2 :(得分:1)

首先,为了按LastName排序,它必须是您在Union All中的每个查询中返回的列之一。其次,您可以使用公用表表达式大大简化查询。第三,不要对连接使用逗号分隔语法(例如From TableA,TableB,TableC ...)。而是使用ISO Join语法。

With RootQuery As
    (
    Select MeetingID
        , FirstName || ' ' || LastName AS Name
        , LastName
        , CASE WHEN RSVP = 1 THEN 1 ELSE NULL END AS Yes
        , CASE WHEN RSVP = 0 THEN 1 ELSE NULL END AS No
        , CASE WHEN RSVP = 2 THEN 1 ELSE NULL END AS Phone
        , CASE WHEN RSVP = -1 THEN 1 ELSE NULL END AS No_Reply
        , MysteryTable0.Response1
        , MysteryTable1.Response2
        , Note
        , groupname      
      From Attendance A
        Join Allusers As B
            And B.MemberId = A.PersonId
        Join MembershipGroups As M
            And M.MemberId = B.MemberID
        Join    (
                SELECT TD.MEMBERID AS MEM0
                    , Response AS Response1
                FROM TRACKINGDETAILS TD, ALLUSERS U
                Where TD.MEMBERID = U.MEMBERID 
                    And TD.TRACKINGID = 64
                ) MysteryTable0
            On MysteryTable0.Mem0 = B.MemberId

        Join    (
                SELECT TD.MEMBERID AS MEM1
                    , Response AS Response2
                FROM TRACKINGDETAILS TD, ALLUSERS U
                Where TD.MEMBERID = U.MEMBERID 
                    And TD.TRACKINGID = 65
                ) As MysteryTable1
            On MysteryTable1.Mem1 = B.MemberId
        Where Meetingid = :1
        )
Select MeetingId, Name, LastName, Yes, No, Phone, No_Reply
    , Response1, Response2
    , Note, GroupName
From RootQuery
Union All
Select Null, 'Total', LastName, SUM(Yes), SUM(No), SUM(Phone), SUM(No_Reply)
    , TO_CHAR(SUM(Response1))
    , TO_CHAR(SUM(Response2))
    , NULL, Groupname 
From RootQuery
Group By GroupName
Union All 
Select Null, 'Grand Total', LastName, SUM(Yes), SUM(No), SUM(Phone), SUM(No_Reply)
    , TO_CHAR(SUM(Response1))
    , TO_CHAR(SUM(Response2))
    ,NULL, ' '
From RootQuery
Group By ???
Order By GroupName Desc, LastName Asc, Name Asc

顺便说一句,最后一个查询可能会遇到一个问题,即它没有Group By(我用Group By ???表示),但你使用的是聚合函数。

答案 3 :(得分:0)

如果您知道该字段将始终为“FirstName LastName”,请用空格分隔:

ORDER BY RIGHT(Name, INSTR(Name,' '))

这是从空格开始的右侧字符数。

如果任何其他名称被“John Cougar Mellencamp”这样的空格隔开,则会失败。