2015-08-13 14 views
7

Sto scrivendo una semplice query in SQL Server:Visualizzazione ordine di una query SQL senza ordine dalla clausola

Select 
    EmpId, EmpName, Sal 
from 
    Emp 
where 
    EmpId in (10,9,5,7,3,8); 

voglio ottenere l'output in uno stesso ordine che è dato cioè; 10,9,5,7,3,8

In realtà qualunque cosa darò il risultato verrà visualizzato con un dato ordine senza ordine in ordine ascendente o discendente.

Come posso farlo? Per favore aiuto.

+0

cosa op si ottiene da questa query –

+0

'clausola IN' NON fornisce un modo per modificare l'ordine dei dati. –

+0

Come stai chiamando questo? Potrebbe esserci un modo dinamico per farlo –

risposta

13

Nessun modo per farlo in modo nativo. Prova:

SELECT EmpId,EmpName,Sal 
FROM Emp 
WHERE EmpId IN (10,9,5,7,3,8) 
ORDER BY CASE EmpId 
    WHEN 10 THEN 1 
    WHEN 9 THEN 2 
    WHEN 5 THEN 3 
    WHEN 7 THEN 4 
    WHEN 3 THEN 5 
    WHEN 8 THEN 6 
    ELSE 7 
END; 
7

È possibile utilizzare una variabile di tabella per passare gli input. È necessario inserire i record in questa variabile di tabella nell'ordine desiderato.

Declare @empids table(id int identity(1,1),empid int) 
insert into @empids values(10),(9),(5),(7),(3),(8) 

Select e.EmpId,e.empname,e.sal from Emp e 
join @empids t on e.EmpId = t.empid 
order by t.id 

Prova questo.

+0

Mi piace questo +1 –

1

È possibile eseguire questa operazione in modo dinamico se l'elenco è una stringa delimitata da virgole. Innanzitutto, devi avere una funzione di splitter. Ecco il DelimitedSplit8k scritto da Jeff Moden:

CREATE FUNCTION [dbo].[DelimitedSplit8K](
    @pString VARCHAR(8000), @pDelimiter CHAR(1) 
) 
RETURNS TABLE WITH SCHEMABINDING AS 
RETURN 
WITH E1(N) AS (
    SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL 
    SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 
) 
,E2(N) AS (SELECT 1 FROM E1 a, E1 b) 
,E4(N) AS (SELECT 1 FROM E2 a, E2 b) 
,cteTally(N) AS(
    SELECT TOP (ISNULL(DATALENGTH(@pString), 0)) ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E4 
) 
,cteStart(N1) AS(
    SELECT 1 UNION ALL 
    SELECT t.N+1 FROM cteTally t WHERE SUBSTRING(@pString, t.N, 1) = @pDelimiter 
), 
cteLen(N1, L1) AS(
SELECT 
    s.N1, 
    ISNULL(NULLIF(CHARINDEX(@pDelimiter, @pString, s.N1),0) - s.N1, 8000) 
FROM cteStart s 
) 
SELECT 
    ItemNumber = ROW_NUMBER() OVER(ORDER BY l.N1), 
    Item  = SUBSTRING(@pString, l.N1, l.L1) 
FROM cteLen l 

Poi, si dichiara l'elenco dei empId s come stringa csv e utilizzare il divisore:

DECLARE @empIds VARCHAR(MAX) = '10,9,5,7,3,8'; 

SELECT e.EmpId, e.EmpName, e.Sal 
FROM Emp e 
INNER JOIN dbo.DelimitedSplit8K(@empIds, ',') s 
    ON s.Item = l.EmpId 
ORDER BY s.ItemNumber 
0

seguente query vi darà il risultato esatto (senza ORDER bY):

SELECT EmpId,EmpName,Sal 
FROM Emp 
WHERE EmpId IN (10) 
union all 
SELECT EmpId,EmpName,Sal 
FROM Emp 
WHERE EmpId IN (9) 
union all 
SELECT EmpId,EmpName,Sal 
FROM Emp 
WHERE EmpId IN (5) 
union all 
SELECT EmpId,EmpName,Sal 
FROM Emp 
WHERE EmpId IN (7) 
union all 
SELECT EmpId,EmpName,Sal 
FROM Emp 
WHERE EmpId IN (3) 
union all 
SELECT EmpId,EmpName,Sal 
FROM Emp 
WHERE EmpId IN (8) 
0

Se Ids è una variabile passata come parametro di input a una stored procedure, è possibile dividere utilizzando 0.123..

[email protected] VARCHAR(300) => '10,9,5,7,3,8' 

;WITH MyIds AS 
(
    SELECT 1 AS Position, CONVERT(INT, LEFT(@inputIds, CHARINDEX(',', @inputIDs)-1)) AS MyId, 
     RIGHT(@inputIds, LEN(@inputIds) - CHARINDEX(',', @inputIDs)) AS Remainder 
    WHERE CHARINDEX(',', @inputIDs)>0 
    UNION ALL 
    SELECT Position +1 AS Position, CONVERT(INT, LEFT(Remainder, CHARINDEX(',', Remainder)-1)) AS MyId, 
     RIGHT(Remainder, LEN(Remainder) - CHARINDEX(',', Remainder)) AS Remainder 
    FROM MyIds 
    WHERE CHARINDEX(',', Remainder)>0 
    UNION ALL 
    SELECT Position +1 AS Position, CONVERT(INT, Remainder) AS MyId, 
     NULL AS Remainder 
    FROM MyIds 
    WHERE CHARINDEX(',', Remainder)=0 
) 
SELECT e.EmpId, e.EmpName, e.Sal 
FROM Emp AS e INNER JOIN MyIds AS a ON e.EmpId = a.MyId 
ORDER BY a.Position 
2

È possibile utilizzare la funzione CHARINDEX in un modo strano: cercare l'ID nella lista separati da virgola e ordinare il risultato per la posizione.

Considerate questo elenco per esempio 10,9,5,7,3,8 ... sottostringa 10 appare al 1 ° posizione mentre 9 appare al 4 ° . Basta ordinare dalla posizione della sottostringa.

CREATE TABLE Emp 
    (EmpId int, EmpName varchar(100), Sal int) 
; 

INSERT INTO Emp 
    (EmpId, EmpName, Sal) 
VALUES 
    (1, 'John', NULL), 
    (2, 'Jane', NULL), 
    (3, 'Smith', NULL), 
    (4, 'Doe', NULL), 
    (5, 'Ben', NULL), 
    (6, 'Steve', NULL), 
    (7, 'Andrew', NULL), 
    (8, 'Simon', NULL), 
    (9, 'Jack', NULL), 
    (10, 'Allen', NULL) 
; 

SELECT 
    EmpId, EmpName, Sal 
FROM 
    Emp 
WHERE 
    EmpId in (10,9,5,7,3,8) 
ORDER BY 
    CHARINDEX(CONCAT(',', EmpId, ','), CONCAT(',', '10,9,5,7,3,8', ',')) 
; 

Risultato:

EmpId | EmpName | Sal 
------+---------+----- 
10 | Allen | NULL 
9  | Jack | NULL 
5  | Ben  | NULL 
7  | Andrew | NULL 
3  | Smith | NULL 
8  | Simon | NULL 
+0

Mentre questo è decisamente un hack, è il tipo di hack che un problema come questo merita - e uno che utilizzerei volentieri per una query ad hock! –

0

Il modo più semplice per raggiungere questo obiettivo è probabilmente quello di utilizzare un costruttore con valori di tabella come un'espressione di tabella che contiene gli ID con un valore di sorta, quindi ordine su questo valore:

Select 
    Emp.EmpId, Emp.EmpName, Emp.Sal 
from 
     Emp 
    Inner Join 
     (
      Values 
       (10, 1), 
       (9, 2), 
       (5, 3), 
       (7, 4), 
       (3, 5), 
       (8, 6) 
     ) 
     EmpIds (EmpId, Sort) 
      On 
       Emp.EmpId = EmpIds.EmpId 
Order By 
    EmpIds.Sort Asc