2017-12-05 1 views
1

Ich habe einen Datensatz von 300.000 Zeilen, Blick auf geerntete Anbaufläche in den Vereinigten Staaten. Einige, aber nicht alle meine Daten werden doppelt gezählt und ich versuche, die Doppelzählung zu entfernen. Die Daten wie folgt aussehen:SQL Zeile entfernen, wenn andere Zeilen Teilmenge sind, Zeile beibehalten, wenn keine Teilmenge

Year | State | Crop | Practice | Acres Harvested | Acres 
------------------------------------------------------------- 
2008  1  1  1   1000 or more  40 
2008  1  1  1   1000 to 1999  10 
2008  1  1  1   2000 to 2999  30 
2008  2  1  1   1000 or more  87 
2008  3  2  2   1.0 to 14.9  15 
2008  3  2  2   1.0 to 4.9   5 
2008  3  2  2   5.0 to 14.9  10 

einige Zeilen sind Teilmengen für die anderen Zeilen in der [Acre Geerntete] Spalte (Zeilen 2 und 3 sind eine Untergruppe der Reihe 1 und die Zeilen 6 und 7 sind eine Untergruppe von Zeilen 5). In Situationen, in denen ich detailliertere Informationen für [Acres Harvested] habe (Zeilen 2 und 3 liefern mehr Details als Zeile 1), möchte ich die Detailinformationen (Zeile 2 und 3) behalten und die allgemeinen Informationen (Zeile 1) weglassen. In anderen Szenarien habe ich nur die allgemeinen Informationen (Zeile 4), also werde ich das behalten.

Ich habe Probleme beim Schreiben des Codes, um die allgemeinen Informationen wegzulassen, wenn die detaillierten Informationen vorhanden sind, aber um die allgemeinen Informationen zu behalten, wenn die detaillierteren Informationen nicht existieren.

Ich habe versucht, einen "inneren Join" zu schreiben, um meine Tabelle mit sich selbst zu verbinden, aber bin mir nicht sicher, wie Zeilen weggelassen werden, wenn bestimmte Bedingungen erfüllt sind. Was ich habe:

SELECT * 
FROM A 
INNER JOIN (SELECT * 
      FROM A 
      GROUP BY [YEAR], [STATE], [CROP], [PRACTICE] 
      HAVING COUNT (*) > 1) AS B 

ON A.Year  = B.Year 
AND A.State = B.State 
AND A.Crop  = B.Crop 
AND A.Practice = B.Practice 

Und jetzt stecken Ich bin ...

Die Ergebnisse sollten wie folgt aussehen:

Year | State | Crop | Practice | Acres Harvested | Acres 
    ------------------------------------------------------------- 
    2008  1  1  1   1000 to 1999  10 
    2008  1  1  1   2000 to 2999  30 
    2008  2  1  1   1000 or more  87 
    2008  3  2  2   1.0 to 4.9   5 
    2008  3  2  2   5.0 to 14.9  10 

jede Hilfe dankbar!

+0

Was sind Ihre Kriterien für "detailliertere Informationen"? Für Ihre Beispieldaten scheinen es die Datensätze für eine übereinstimmende Menge zu sein, die nicht auf "oder mehr" enden. Ist das alles? – Rominus

+0

Danke, dass du das herausgebracht hast! Ich habe den Beispielcode bearbeitet, um ein anderes Szenario in den Daten anzuzeigen. Ich möchte so viele Details wie möglich für [Acres Harvested] haben und gleichzeitig dafür sorgen, dass ich die Daten nicht doppelt zähle. – user9057195

+0

Ok, habe meine Antwort aktualisiert, um deine neuen Daten wiederzugeben. Die überlappenden Nummernbereiche machen dies ein * Los * komplizierter. – Rominus

Antwort

0

Ihre Frage ist ein bisschen vage. Dadurch wird das Ergebnis zurück legen Sie für die Eingabedaten angegeben haben Sie angegeben haben:

select a.* 
from a 
where a.acres_harvested not like '% or more' or 
     not exists (select 1 
        from a a2 
        where a2.year = a.year and a2.state = a.state and a2.crop = a.crop and 
         a2.acres_harvested like '[0-9]%to%[0-9]' 
       ); 
+0

Vielen Dank, dass Sie darauf hingewiesen haben. Ich habe einige weitere Beispieldaten hinzugefügt und versucht zu klären, wonach ich suche. – user9057195

0

Ihre Kriterien für „detailliertere Informationen“ ist Unter der Annahme, Datensätze für einen aufeinander abgestimmten Satz, der am Ende nicht in „oder mehr "Wie ich in meinem Kommentar erraten habe, können Sie auf diese Weise Ihre gewünschte Ausgabe erhalten. Sie tun die Datensätze mit nur einem Datensatz und diejenigen mit mehreren Datensätzen getrennt und UNION sie statt es mit einem SELECT zu tun.

SELECT A.* 
FROM A 
GROUP BY [YEAR], [STATE], [CROP], [PRACTICE] 
HAVING 
    COUNT (*) = 1 

UNION 

SELECT A.* 
FROM A 
INNER JOIN 
    (SELECT [YEAR], [STATE], [CROP], [PRACTICE] 
     FROM A 
     GROUP BY [YEAR], [STATE], [CROP], [PRACTICE] 
     HAVING 
      COUNT (*) > 1 
    ) AS B 
ON A.[Year]  = B.[Year] 
AND A.[State] = B.[State] 
AND A.[Crop]  = B.[Crop] 
AND A.[Practice] = B.[Practice] 
WHERE [ACRES HARVESTED] not like '%%or more' 

Wenn Ihre Kriterien nicht, was ich die WHERE Klausel nur erraten ändern.

Angesichts Ihrer aktualisierten Beispieldaten müssen Sie auch nach überlappenden Nummernbereichen suchen. Diese Frage hat einige Optionen, wie man das macht: Discard existing dates that are included in the result, SQL Server. Sie müssen Ihre "X zu Y" -Werte auch in zwei numerische Felder aufteilen.

Verwandte Themen