2016-03-21 5 views
2

Ich brauche die dritte und größere Datensätze, die nach Produkten, die Art und Anzeigereihenfolge aus den folgenden Tabellen sortiert zu löschen:Firebird und SQL Server höchsten Reihen in Gruppen löschen

Stockist Tabelle :

CREATE TABLE INVENTORYWEBSTOCKISTS 
(
    STOCKISTID  NUMERIC(10,0) NOT NULL, 
    PRODUCTID NUMERIC(10,0) NOT NULL, 
    DISPLAYORDER NUMERIC(10,0), 
    CUSTOMERID  NUMERIC(10,0), 
CONSTRAINT PK_INVENTORYWEBSTOCKISTS PRIMARY KEY (STOCKISTID) 
); 

STOCKISTID ist die eindeutige autoinc-Spalte für die Tabelle und kann als ID verwendet werden. PRODUCTID und CUSTOMERID verweisen beide auf andere Tabellen.

Customer Tabelle:

CREATE TABLE CUSTOMERS 
(
    CUSTOMERID  NUMERIC(10,0) NOT NULL, 
    WEBSTOCKISTSTOCKISTTYPE VARCHAR(100), 
CONSTRAINT PK_CUSTOMERS PRIMARY KEY (CUSTOMERID) 
); 

Customers Tabelle hat Datensätze:

insert into CUSTOMERS (CUSTOMERID, WEBSTOCKISTSTOCKISTTYPE) values (1, 'Reseller'); 
insert into CUSTOMERS (CUSTOMERID, WEBSTOCKISTSTOCKISTTYPE) values (2, 'Reseller'); 
insert into CUSTOMERS (CUSTOMERID, WEBSTOCKISTSTOCKISTTYPE) values (3, 'Reseller'); 
insert into CUSTOMERS (CUSTOMERID, WEBSTOCKISTSTOCKISTTYPE) values (4, 'Installer'); 
insert into CUSTOMERS (CUSTOMERID, WEBSTOCKISTSTOCKISTTYPE) values (5, 'Installer'); 
insert into CUSTOMERS (CUSTOMERID, WEBSTOCKISTSTOCKISTTYPE) values (6, 'Installer'); 
insert into CUSTOMERS (CUSTOMERID, WEBSTOCKISTSTOCKISTTYPE) values (7, 'Installer'); 

Stockist Tabelle hat Datensätze:

insert into INVENTORYWEBSTOCKISTS (STOCKISTID, PRODUCTID, DISPLAYORDER, CUSTOMERID) values (1, 1, -100, 1); 
insert into INVENTORYWEBSTOCKISTS (STOCKISTID, PRODUCTID, DISPLAYORDER, CUSTOMERID) values (2, 1, -101, 2); 
insert into INVENTORYWEBSTOCKISTS (STOCKISTID, PRODUCTID, DISPLAYORDER, CUSTOMERID) values (3, 1, -102, 3); 
insert into INVENTORYWEBSTOCKISTS (STOCKISTID, PRODUCTID, DISPLAYORDER, CUSTOMERID) values (4, 1, -103, 4); 
insert into INVENTORYWEBSTOCKISTS (STOCKISTID, PRODUCTID, DISPLAYORDER, CUSTOMERID) values (5, 1, -104, 5); 
insert into INVENTORYWEBSTOCKISTS (STOCKISTID, PRODUCTID, DISPLAYORDER, CUSTOMERID) values (6, 1, -105, 6); 
insert into INVENTORYWEBSTOCKISTS (STOCKISTID, PRODUCTID, DISPLAYORDER, CUSTOMERID) values (7, 1, -106, 7); 
insert into INVENTORYWEBSTOCKISTS (STOCKISTID, PRODUCTID, DISPLAYORDER, CUSTOMERID) values (10, 2, -107, 3); 
insert into INVENTORYWEBSTOCKISTS (STOCKISTID, PRODUCTID, DISPLAYORDER, CUSTOMERID) values (13, 2, -108, 6); 
insert into INVENTORYWEBSTOCKISTS (STOCKISTID, PRODUCTID, DISPLAYORDER, CUSTOMERID) values (14, 2, -109, 7); 

Für die kombinierten Ergebnisse:

select 
    INVENTORYWEBSTOCKISTS.STOCKISTID, 
    INVENTORYWEBSTOCKISTS.PRODUCTID, 
    INVENTORYWEBSTOCKISTS.DISPLAYORDER, 
    CUSTOMERS.WEBSTOCKISTSTOCKISTTYPE 
from 
    INVENTORYWEBSTOCKISTS 
left join 
    CUSTOMERS on CUSTOMERS.CUSTOMERID = INVENTORYWEBSTOCKISTS.CUSTOMERID 
order by 
    INVENTORYWEBSTOCKISTS.PRODUCTID, 
    CUSTOMERS.WEBSTOCKISTSTOCKISTTYPE, 
    INVENTORYWEBSTOCKISTS.DISPLAYORDER 

Ausgang:

STOCKISTID, PRODUCTID, DISPLAYORDER, WEBSTOCKISTSTOCKISTTYPE 
7, 1, -106, Installer 
6, 1, -105, Installer 
5, 1, -104, Installer 
4, 1, -103, Installer 
3, 1, -102, Reseller 
2, 1, -101, Reseller 
1, 1, -100, Reseller 
14, 2, -109, Installer 
13, 2, -108, Installer 
10, 2, -107, Reseller 

Ich brauche die 3. und oben Datensatz für jede Produkt/Händler Typgruppe von Anzeige-Reihenfolge geordnet zu löschen, so erwarten würde es Zeilen 5 zu löschen, 4 und 1.

Ich habe Heaps von verschiedenen Abfragen von hier und dem Web im Allgemeinen ausprobiert, ich kann nichts finden, das für das Löschen gruppieren und bestellen wird und an MS SQL und Firebird 1.5 arbeitet.

SQL Fiddle experimentieren mit: http://sqlfiddle.com/#!3/7101de/1

So nach dem Löschen sollte die Tabelle wie folgt aussehen:

Ausgang:

STOCKISTID, PRODUCTID, DISPLAYORDER, WEBSTOCKISTSTOCKISTTYPE 
7, 1, -106, Installer 
6, 1, -105, Installer 
3, 1, -102, Reseller 
2, 1, -101, Reseller 
14, 2, -109, Installer 
13, 2, -108, Installer 
10, 2, -107, Reseller 

Die Lösch als eine Abfrage ausgeführt werden soll, so kann ich Übergeben Sie es an den Server.

*** Edit:

Vielleicht zu vereinfachen, wenn ich einen Select-Befehl tun können, die die STOCKISTID ‚s zurück gelöscht werden, kann ich dann separat die Löschbefehle auszuführen.

*** Edit 2:

Als Test, habe ich den Händler Typ-Feld auf die INVENTORYWEBSTOCKISTS Tabelle, und diese Abfrage ausführen können:

SELECT INVENTORYWEBSTOCKISTS.STOCKISTID 
FROM INVENTORYWEBSTOCKISTS IWS1 
WHERE 
(SELECT COUNT(*) 
FROM INVENTORYWEBSTOCKISTS IWS2 
WHERE IWS2.PRODUCTID = IWS1.PRODUCTID 
AND IWS2.STOCKISTTYPE = IWS1.STOCKISTTYPE 
AND IWS2.DISPLAYORDER <= IWS1.DISPLAYORDER) > 2 

und geben die richtigen Felder (dh die diejenigen, die gelöscht werden sollen). Dies basierte auf einer Frage, die zuvor zu SO gestellt wurde.

Sobald ich versuche, in der Tabelle KUNDE zu verknüpfen, wie die Abfrage sein sollte, gibt es andere Ergebnisse, weniger Zeilen. Vielleicht könnte jemand dabei helfen?

+0

Ich verstehe nicht. Können Sie bitte Ihre erwartete Leistung zeigen? –

+0

Ich brauche einen Löschbefehl, der die Datensätze nach PRODUCTID und WEBSTOCKISTTYPE gruppiert, dann in DISPLAYORDER setzt und dann alle Datensätze in dieser Gruppe nach den zweiten löscht. Also von diesem Ausgang würde es nur STOCKISTIDs von 5, 4 und 1 löschen. – Darren

Antwort

3

die Sie interessieren, ich habe ROW_NUMBER verwendet, um Ihren Fall zu beseitigen (Von dem, was ich aus Ihrer Frage verstanden)

;WITH CTE AS(
    SELECT ROW_NUMBER()OVER(PARTITION BY PRODUCTID,WEBSTOCKISTSTOCKISTTYPE 
          ORDER BY (SELECT 1))SNO, INVENTORYWEBSTOCKISTS.*, 
         CUSTOMERS.WEBSTOCKISTSTOCKISTTYPE FROM 
    INVENTORYWEBSTOCKISTS 
    LEFT JOIN 
     CUSTOMERS ON INVENTORYWEBSTOCKISTS.CUSTOMERID = CUSTOMERS.CUSTOMERID 
    ) 

    SELECT * FROM CTE WHERE SNO <3 

Edit: Aus Ihren Kommentaren:

;WITH CTE AS(
    SELECT ROW_NUMBER()OVER(PARTITION BY PRODUCTID,WEBSTOCKISTSTOCKISTTYPE 
     ORDER BY (SELECT DISPLAYORDER))SNO, INVENTORYWEBSTOCKISTS.*, 
     CUSTOMERS.WEBSTOCKISTSTOCKISTTYPE FROM 
    INVENTORYWEBSTOCKISTS 
    LEFT JOIN 
    CUSTOMERS ON INVENTORYWEBSTOCKISTS.CUSTOMERID = CUSTOMERS.CUSTOMERID 
    ) 
    SELECT STOCKISTID FROM CTE WHERE SNO>2 

Wenn es ein Problem ist, mit CTE

DELETE FROM INVENTORYWEBSTOCKISTS WHERE STOCKISTID IN ( 

    SELECT STOCKISTID FROM (
    SELECT ROW_NUMBER()OVER(PARTITION BY PRODUCTID,WEBSTOCKISTSTOCKISTTYPE 
       ORDER BY (SELECT DISPLAYORDER))SNO, INVENTORYWEBSTOCKISTS.*, 
       CUSTOMERS.WEBSTOCKISTSTOCKISTTYPE FROM 
      INVENTORYWEBSTOCKISTS 
      LEFT JOIN 
      CUSTOMERS ON INVENTORYWEBSTOCKISTS.CUSTOMERID = CUSTOMERS.CUSTOMERID 
      ) AS A WHERE SNO>2 
      ) 
+0

Das ist gut, ersetzen Sie einfach 'ORDER BY (SELECT 1)' mit 'ORDER BY DISPLAYORDER)'. –

+0

@FelixPamitan Yup, ich habe es zuerst falsch verstanden. Von Kommentaren habe ich es klar gemacht –

+0

Entschuldigung, Firebird 1.5 hat kein CTE. Außerdem muss ich in der Lage sein, es als eine Abfrage zu tun (alle Abfragen, die ich sah, hatte er in einer Abfrage ausgewählt und gelöscht, also dachte ich nicht, das hinzuzufügen). – Darren

Verwandte Themen