2010-11-24 6 views
0

In meiner Produkttabelle habe ich eine Spalte namens 'order', die Ganzzahlen 1, 2, 3 usw. enthält, die durch eine Dropdown-Box vom Benutzer im CMS festgelegt werden.SQL Server: Änderungsauftragsspalte in DB

Ich möchte alle Zeilen in der Datenbank neu ordnen, indem ich die alte Bestellung, die neue Bestellung und die Produkt-ID entsprechend übergebe, wenn der Benutzer die Bestellung eines bestimmten Produkts ändert.

ZB:

Chair - order 1 
Pillow - order 2 
Bed - order 3 
Couch - order 4 

Wenn die Verwendung Couch ändert, um 2 zu sein, muss ich nach dieser Änderung auf alle anderen Produkte zurückzustellen.

Optimierung ist kein großes Problem, da es nicht viele Elemente in der Tabelle gibt.

Was ist die effizienteste Logik für diese Aufgabe?

Dank

+0

Ihre Logik scheint nicht vollständig zu sein. Wenn der Benutzer die Couch auf 2 umstellt, welche Logik gilt dann für das Zurücksetzen aller anderen Produkte? Kriterien für das Zurücksetzen? – InSane

+1

Sie schreiben * Was ist die effizienteste Logik * - aber auch * Optimierung ist kein großes Problem *. Was meinst du mit * effizient * in diesem Zusammenhang? –

+1

Was ist, wenn 2 Benutzer gleichzeitig neu bestellen? – gbn

Antwort

1

Ihre order Spalte braucht nicht aufeinanderfolgenden ganzen Zahlen enthalten - kann es Lücken geben. Das einzige, was wichtig ist, ist ihre relative Ordnung. Sie können mit 100, 200, 300, ... anstelle von 1, 2, 3, ... beginnen, was die Anpassung der relativen Reihenfolge erleichtert, ohne alle Elemente in der Datenbank aktualisieren zu müssen, nur weil Sie ein Element verschieben möchten.

 
100 foo ---  200 bar 
200 bar \  300 baz 
300 baz  ---> 350 foo 
400 qux   400 qux 

Gelegentlich werden Sie feststellen, dass am Einfügepunkt keine Lücke mehr vorhanden ist. Dann können Sie die gesamte Tabelle neu nummerieren.

+0

Ich habe Floats zuvor verwendet, aus dem gleichen Grund - Sie können fast immer einen Wert zwischen den beiden finden, zwischen denen Sie einfügen möchten. –

0

Wie wäre es so etwas wie dieses (Pseudo-Code)

UPDATE Table 
SET  Order = Order + 1 
WHERe Order >= NewOrderForCouch 
AND  Order < CurrentOrderForCouch; 
UPDATE Table 
SET  Order = NewOrderForCouch 
WHERe ID = CouchID; 
0

Um dies zu tun, Ihre Tabelle eine eindeutige Kennung haben muss, um in der Lage zu unterscheiden zwischen

Couch 2 

und

Pillow 2 

Erstellen Sie Ihre Bestellungen Tabelle wie diese

CREATE TABLE [dbo].[Orders](
    [ID] [int] NOT NULL, 
    [Item] [varchar](50) NOT NULL, 
    [Number] [int] NOT NULL, 
CONSTRAINT [PK_Orders] PRIMARY KEY CLUSTERED 
(
    [ID] ASC 
) ON [PRIMARY] 
) ON [PRIMARY] 

Einmal besiedelt, haben Sie diese (beachten Sie, wie ich zufällig einzigartigen idenitifiers in dem einzigartigen Schlüssel-ID gesetzt habe):

ID  Item Number 
593 Chair 1 
207 Pillow 2 
681 Bed  3 
117 Couch 4 

Sie die Anzahl der Couch zu 2 ändern:

ID  Item Number 
593 Chair 1 
207 Pillow 2 
681 Bed  3 
117 Couch 2 

Wir können ID verwenden, um Couch und Kissen zu unterscheiden, die beide Nummer 2 haben.Die ROW_NUMBER() Funktion gibt uns die gewünschte Nummerierung:

SELECT 
    id, Item, number, ROW_NUMBER() OVER(ORDER BY number) 
FROM 
    Orders 

geben
593 Chair 1 1 
117 Couch 2 2 
207 Pillow 2 3 
681 Bed  3 4 

Es ist dann nur eine Frage mit diesen neuen Zahlen aktualisieren, kann unter Verwendung einer WITH-Klausel:

WITH NewOrders(newnum, id) AS (
    SELECT 
     ROW_NUMBER() OVER(ORDER BY number), id 
    FROM 
     Orders 
) 
UPDATE 
    Orders 
SET 
    number = (
     SELECT 
      newnum 
     FROM 
      NewOrders 
     WHERE 
      neworders.id = orders.id  
    ) 

Ergebnisse:

ID Item Number 
593 Chair 1 
117 Couch 2 
207 Pillow 3 
681 Bed  4 
1
CREATE PROCEDURE ChangeProductOrder(@productID int, @order int) 
AS 

DECLARE @oldOrder int 
SET @oldOrder = (SELECT [Order] FROM dbo.Products WHERE productid = @productID) 

UPDATE p 
SET [order] = CASE WHEN ProductID = @productID 
       THEN @order 
       ELSE [Order] - SIGN(@order - @oldOrder) 
       END 
FROM dbo.Products p 
WHERE ([Order] BETWEEN @oldOrder AND @order 
OR [Order] BETWEEN @order AND @oldOrder) 
Verwandte Themen