在做工会时我无法使ORDER BY工作

时间:2016-08-08 20:57:03

标签: sql sql-server sql-server-2012

我需要显示来自2个不同供应商应用程序的潜在匹配数据。数据需要堆叠,以便用户可以比较,然后接受或拒绝匹配。 为此,我想按姓氏的大写字母排序,然后按名字大写,然后按系统排序,这样SH系统的记录就会出现在PR系统记录之前。选择工作得很好 - 我的问题是order by子句。当我使用

的'ORDER BY'时
ORDER BY LName, FName, BkNum,RecordType DESC

我得到了

RecordType  LName   FName   BkNum       PIN
SH          SANCHEZ MICHAEL 1600010808  54727
PR          SANCHEZ MICHAEL 1600010808  54727
PR          Suarez  Isaiah  1600010838  30019800
SH          SUAREZ  ISIAIAH 1600010838  30019800
SH          SYKES   ROBERT  1600010831  588572
PR          SYKES   ROBERT  1600010831  588572

请注意,第3行和第4行的顺序错误。我想使用下面显示的(此发布简化版)查询,但是当我这样做时,我收到了消息,

Msg 207, Level 16, State 1, Line 53
Invalid column name 'LName'.
Msg 104, Level 16, State 1, Line 53
ORDER BY items must appear in the select list if the statement contains a UNION, INTERSECT or EXCEPT operator.

我尝试从CASE语句中删除'UPPER',并将'UPPER'添加到上面的简化ORDER BY语句中。我总是得到相同的错误消息。我正在使用MS SQL 2012.我做错了什么?提前感谢您的时间和见解!

DECLARE @FromDate    DATETIME, @ToDate      DATETIME, @TempSortOrder char(2)

-- For testing
SET @FromDate = CAST('07-12-2016' as DATETIME)
SET @ToDate = CAST('07-13-2016' as DATETIME)
SET @TempSortOrder = '1A'

SELECT 'SH'                    AS RecordType,
       ISNULL(LastName,'')     AS LName, 
       ISNULL(FirstName,'')    AS FName,
       SH.BkNum                AS BkNum,
       SHCX.PIN                AS PIN
FROM BkSher AS SH
JOIN BkSherCase AS SHCX  ON SH.BkNum = SHCX.BkNum
WHERE SH.ArrDate BETWEEN @FromDate AND @ToDate AND SH.LastName like 'S%'

UNION

SELECT 'PR'                     AS RecordType,
       ISNULL(OffLastName,'')   AS LName,
       ISNULL(OffFirstName,'')  AS FName,
       SHCX.BkNum               AS BkNum,
       CX.PIN                   AS PIN
FROM BkCase AS CX
JOIN BkSherCase AS SHCX ON CX.PIN = SHCX.PIN
JOIN BkSher AS SH  ON SH.BkNum = SHCX.BkNum
WHERE SH.ArrDate BETWEEN @FromDate AND @ToDate  AND SH.LastName like 'S%'

ORDER BY 
  CASE WHEN @TempSortOrder = '1A' THEN UPPER(LName) END ASC,
  CASE WHEN @TempSortOrder = '1A' THEN UPPER(FName) END ASC,
  CASE WHEN @TempSortOrder = '1A' THEN RecordType END DESC,

  CASE WHEN @TempSortOrder = '1D' THEN LName END DESC, 
  CASE WHEN @TempSortOrder = '1D' THEN FName END DESC,
  CASE WHEN @TempSortOrder = '1D' THEN RecordType END DESC

3 个答案:

答案 0 :(得分:0)

快速而肮脏的解决方案是将联合包装在内部选择中。然后,您可以按顺序使用别名LNameFName。即。

SELECT * FROM 
(
  -- put the select with union here
) Result
ORDER BY 
  CASE WHEN @TempSortOrder = '1A' THEN UPPER(LName) END ASC, ...

如果没有UNION,您必须使用SELECT

中的相同列

但是这一切都无关紧要。除非您使用区分大小写的排序规则UPPER(),否则无关紧要,因此没有必要。无论哪种方式,“以赛亚”都将出现在“以赛亚”之前

答案 1 :(得分:0)

当使用每个Query的并集时,它不会接受order by,除非你必须将它括在括号或嵌套查询中,

试着看看这个:

select all.id,all.fname
(select a.id,a.fname from
(select id,fname from table1 order by fname) as a

union

select id,fname from table2) as all order by all.fname

答案 2 :(得分:0)

好的 - 我提出了一个解决方案 - 丑陋,但它确实有效。性能还可以,因为临时表中最多有3000行。我对更好的想法持开放态度 - 我不是临时表的粉丝,但另一方面,我很高兴得到正确的输出。

-- Create temp table.
DECLARE @ResultsList table
        (RecordType      char(2),
         LName           varchar(30),
         FName           varchar(30),
         ArrDate         datetime,
         BkNum           varchar(10),
         PIN             varchar(10),
         SHRowNum        bigint             )

--Find all the SH records, and order them, putting the order into SHRowNum
INSERT INTO @ResultsList(RecordType,LName,FName,ArrDate,BkNum,PIN,SHRowNum)
SELECT 'SH',
       ISNULL(LastName,''), 
       ISNULL(FirstName,''),
       [DOB],
       ArrDate, 
       SH.BookingNum,
       SHCX.PIN,
       ROW_NUMBER() OVER (ORDER BY 
            CASE WHEN @InputSortOrder = '1A' THEN LastName END ASC,
            CASE WHEN @InputSortOrder = '1A' THEN FirstName END ASC,

            CASE WHEN @InputSortOrder = '1D' THEN LastName END DESC, 
            CASE WHEN @InputSortOrder = '1D' THEN FirstName END DESC)
FROM BkSher AS SH
LEFT OUTER JOIN BkSherCase AS SHCX
  ON SH.BookingNum = SHCX.BookingNum
WHERE SH.ArrDate BETWEEN @InputRecdFromDate AND @InputRecdToDate

-- Find the corresponding PR records, and copy the order from the temp table
INSERT INTO @ResultsList(RecordType,LName,FName,ArrDate,BkNum,PIN,SHRowNum)
SELECT 'PR',
       ISNULL(OffenderLastName,''),
       ISNULL(OffenderFirstName,''),
       ArrDate,
       BookingNum,
       CX.PIN,
       RES.SHRowNum
FROM tblMWBookingsCaseload AS CX
JOIN @ResultsList AS RES ON CX.PIN = RES.PIN

-- If a SH record matches several PR records, the above query results in 
-- duplicate SH records, which we don't want.  (We want to see 1 SH record 
-- followed by a list of possible matches.)  This deletes the dups.
DELETE R
From @ResultsList R
INNER JOIN @ResultsList R2 ON R2.BookingNum = R.BookingNum
WHERE R.RecordType = 'SH'
  AND R2.RecordType = 'SH'
  AND R.BookingNum = R2.BookingNum
  AND R.SHRowNum > R2.SHRowNum

-- Return sorted results.  Each SH record is followed by 
-- its corresponding PR records.
SELECT RecordType, LName, FName, ArrDate, BookingNum, PIN
FROM @ResultsList
ORDER BY SHRowNum, RecordType DESC