我正在使用Oracle。我的sql返回一个像这样的列
名称:
约翰史密斯
大卫李
...
如果我按名称订购,它将按名字排序。我如何按姓氏订购?如果我按姓氏排序,名字oracle将返回无效标识符。我试过substr,instr但它不起作用。我知道sql很乏味但只是想让数据快速解决这个问题。
完整SQL: http://pastebin.com/hYkdHBDM
答案 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”这样的空格隔开,则会失败。