2016-08-08 66 views
-1

Ich muss potenziell übereinstimmende Daten von 2 verschiedenen Herstelleranwendungen anzeigen. Daten müssen gestapelt werden, damit Benutzer die Übereinstimmung vergleichen, akzeptieren oder ablehnen können. Um dies zu tun, möchte ich nach Großbuchstaben von Nachname, dann Großbuchstaben von Vorname, dann von System, so dass der SH-System-Datensatz unmittelbar vor dem PR-System-Datensatz erscheint. Die Auswahl funktioniert großartig - mein Problem ist mit der Order by-Klausel. Wenn ich einen 'ORDER BY' verwenden vonIch kann keine ORDER BY-Arbeit machen, wenn ich eine Union mache

ORDER BY LName, FName, BkNum,RecordType DESC 

ich

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 

Beachten Sie, dass die Zeilen 3 und 4 in der falschen Reihenfolge sind. Ich mag die (vereinfachte für diese Buchung) Abfrage unten verwenden, aber wenn ich das tue, erhalte ich die Meldung,

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. 

Ich habe versucht, die ‚oberen‘ aus der CASE-Anweisung zu entfernen, sowie das Hinzufügen ' UPPER 'zu meiner vereinfachten ORDER BY-Anweisung von oben. Ich bekomme immer die gleiche Fehlermeldung. Ich bin auf MS SQL 2012. Was mache ich falsch? Vielen Dank im Voraus für Ihre Zeit und Einsicht!

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

Warum sagen Sie, dass Zeilen 3 und 4 in der falschen Reihenfolge sind? Sie sehen gut aus für mich. Sie haben 'Jesaja' gegen' ISIAIAH' bemerkt, oder? Sehen Sie das Extra "I" in der zweiten? – sstan

+0

Warte, welche Fehlermeldung bekommst du? Weil Sie eigentlich keine Fehlermeldung * auflisten. –

+0

Bei einer Sortierung ohne Groß- und Kleinschreibung wird die Sortierung nach UPPER oder LOWER nicht helfen, da alle Strings identisch sind. Sie würden eine Sortierung auf Spaltenebene für Ihre Sortierprädikate benötigen, um die Möglichkeit zu haben, das zu tun, was Sie versuchen. –

Antwort

0

Eine schnelle und schmutzige Lösung ist, Ihre Union in eine innere Auswahl zu wickeln. Dann können Sie Ihre Aliase LName und FName in einer Reihenfolge verwenden. das heißt

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

Wenn es keine UNION war Ihnen die gleichen Spalten aus der SELECT

verwenden würde, aber es ist alles allerdings belanglos. Wenn Sie keine Groß-/Kleinschreibung beachten, die UPPER() berücksichtigt, ist dies nicht erforderlich. So oder so „Jesaja“ wird vor „Isiaiah“

0

Wenn Vereinigung jeder Abfrage verwenden, wäre es nicht Bestellung durch, es sei denn Sie haben es in einer Klammer oder verschachtelte Abfrage einzuschließen,

versuchen, einen Blick zu nehmen dabei:

0

Ok - ich schuhte eine Lösung - hässlich, aber es funktioniert. Die Leistung ist in Ordnung, da ich in der Temp-Tabelle höchstens 3000 Zeilen haben werde. Ich bin offen für bessere Ideen - ich bin kein Fan des Temp-Tisches, aber auf der anderen Seite bin ich ziemlich glücklich, die richtige Ausgabe zu bekommen.

-- 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