2016-02-18 6 views
6

Ho una tabella Items ad es.Permanentemente e riordinando i record in modo permanente

ID Name  ItemOrder 
---------------------- 
16 Albania 1 
13 Chile 2 
11 Barbados 3 
10 France 4 
... 

che visualizzo nella mia applicazione client come

SELECT * FROM Items ORDER BY ItemOrder 

Voglio essere in grado di "muovere", per esempio Albania e Barbados dopo (o prima a seconda del mio parametro) France o qualsiasi altra registrazione . quindi il risultato è (per il movimento After record di France):

13 Chile 1  
10 France 2 
16 Albania 3 
11 Barbados 4 

e risultato Before è:

13 Chile 1   
16 Albania 2 
11 Barbados 3 
10 France 4 

ho bisogno di aggiornamento in modo permanente il ItemOrder per riflettere il nuovo ordine. Esiste un modo semplice ed efficace per farlo?

+1

Come si fa w E sapere quale record "spostare" dove (non è realmente commovente, il suo ordinamento)? – sagi

+0

@sagi, Sì, ho bisogno di aggiornare l'ItemOrder per riflettere il nuovo ordine – zig

+0

ci sono solo 4 record nella tabella – TheGameiswar

risposta

5

È possibile utilizzare un'espressione di tabella comune (CTE) per eseguire l'operazione UPDATE. Questo è come la vostra richiesta potrebbe apparire come per il 'dopo' caso:

;WITH ToUpdate AS (
    SELECT ID, Name, ItemOrder, 
     ROW_NUMBER() OVER (ORDER BY temp_order) AS NewOrder 
    FROM (
    SELECT ID, Name, ItemOrder, 
     CASE 
      WHEN Name IN ('Albania', 'Barbados') THEN x.o + ItemOrder * 0.1 
      ELSE ItemOrder 
     END AS temp_order 
    FROM mytable 
    CROSS JOIN (SELECT ItemOrder FROM mytable WHERE Name = 'France') AS x(o)) AS t 
) 
UPDATE ToUpdate 
SET ItemOrder = NewOrder 

Il trucco è quello di ottenere France's numero d'ordine e aggiungere un frazione dell'ordine di 'Albania', 'Barbados', in modo che :

  • 'Albania', 'Barbados' sono posizionati dopo 'Francia'
  • 'Albania' e 'Barbados' mantenere l'ordine tra loro
  • l'ordine dei record seguenti 'France' è anche mantenuta .

Demo here

Edit:

La 'prima' caso può essere implementato se sostituiamo questa linea:

WHEN Name IN ('Albania', 'Barbados') THEN x.o + ItemOrder * 0.1 

con questa linea:

WHEN Name IN ('Albania', 'Barbados') THEN x.o - 1.0/ItemOrder * 0.1 
+0

Che cosa significano 'x.o' e' x (o) '? – zig

+0

@zig È solo un alias utilizzato per accedere al risultato restituito dall'operazione 'CROSS JOIN'. –

+0

Questo sembra funzionare bene. Sto ancora testando (non riesco ancora a capire pienamente questo codice) Ho provato a fare un 'Prima' cambiando' xo + ItemOrder * 0.1' a 'xo - ItemOrder * 0.1' ma il risultato è invertito anche se i record sono Prima della Francia ma il l'ordine non mantiene tra loro "Albania", "Barbados". Puoi per favore mostrarmi come fare un caso "Prima"? – zig

1

(Nota: Questa risposta è stata scritta prima dell'aggiornamento tua domanda di dire che è necessario aggiornamento l'ItemOrder.)

In primo luogo, fare un po 'spazio tra le voci:

SELECT ID, name, ItemOrder * 10 AS newOrder FROM Items 

Ora modifichiamo quella SQL per inserire "speciali" tra:

SELECT ID, name, ItemOrder 
     CASE WHEN name = 'Albania' 
      THEN (SELECT ItemOrder FROM Items WHERE name = 'France') * 10 + 1 
      WHEN name = 'Barbados' 
      THEN (SELECT ItemOrder FROM Items WHERE name = 'France') * 10 + 2 
      ELSE ItemOrder * 10 
     END AS newOrder 
    FROM Items 

E ora siamo in grado di ordinare in base a essa:

SELECT ID, name, ItemOrder 
    FROM (... see previous SQL ...) AS t 
ORDER BY newOrder