2012-04-10 3 views
0

Hier ist meine Frage: Wie kann ich die Integrität der Datensätze mithilfe von Aggregatfunktionen mit einer Gruppe beibehalten?SQL Server: Wie kann ich die Datenintegrität mithilfe von Aggregatfunktionen mit Gruppen verwalten?

Um weiter zu erklären, hier ein Beispiel.

Ich habe eine Tabelle mit den folgenden Spalten: (Denken Sie daran, als „Ordnung“ Tabelle)

Customer_Summary (first 10 char of name + first 10 char of address) 
Customer_Name 
Customer_Address 
Customer_Postal Code 
Order_weekday 

Es gibt eine Zeile pro „Ordnung“, so viele Zeilen mit demselben Kundennamen, Adresse und Zusammenfassung.

Ich möchte den Namen, die Adresse und die Postleitzahl des Kunden sowie die Anzahl der Bestellungen, die er an jedem Wochentag aufgegeben hat, in der Zusammenfassung des Kunden anzeigen.

die Daten sollten also wie folgt aussehen:

Summary    | Name  | Address | PCode | Monday | Tuesday | Wednesday | Thursday | Friday 

test custntest addre|test custname|test address|123456 | 1  | 1  | 1   | 1  | 1 

Ich will nur Gruppen Aufzeichnungen ähnlichen Kunden Zusammenfassung zusammen, aber natürlich möchte ich einen Namen, Adresse und Postleitzahl zu zeigen. Ich verwende min() im Moment, so meine Frage wie folgt aussieht:

ich meine Wochentag Logik weggelassen habe, da ich nicht glaube, es war notwendig.

Mein Problem ist dies - einige dieser Kunden mit der gleichen Kundenzusammenfassung haben unterschiedliche Adressen und Postleitzahlen. So

ich zwei Kunden haben könnte, die aussehen wie:

test custntest addre|test custname |test address |323456| 

test custntest addre|test custname2|test address2|123456| 

die Gruppe unter Verwendung von, meine Abfrage kehrt das folgende:

test custntest addre|test custname |test address |123456| 

Da ich min bin mit, es wird geben Sie mir den Mindestwert für alle Felder, aber nicht unbedingt aus dem gleichen Datensatz. Ich habe also meine Integrität verloren - die Adresse und der Name, die von der Abfrage zurückgegeben wurden, stimmen nicht mit der Postleitzahl überein.

Wie kann ich die Datenintegrität für nicht gruppierte Felder beibehalten, wenn ich eine group by-Klausel verwende?

Hoffentlich habe ich es klar genug erklärt, und danke im Voraus für die Hilfe.

BEARBEITEN: Gelöst. Danke allen!

+0

So würden Sie aggregieren mögen, aber was würden Sie tun, wenn ein Kunde mehr als eine Adresse hatte? Können Sie ein Beispiel für die Ergebnismenge geben, mit der Sie enden möchten? – Arne

+1

Die Kundendaten sollten in ihrer ** eigenen Tabelle sein ** - wenn du sie ständig in der "Bestellungen" Tabelle duplizierst, wirst du niemals in der Lage sein, Datenintegrität/Datenqualität zu garantieren ..... –

+0

habe ich zur Verfügung gestellt Ein Beispiel da oben - nur was die Adresse betrifft ist wichtig, dass sie mit dem Namen und der Postleitzahl übereinstimmen muss. Ich benutzte min, weil es am einfachsten war, aber wie ich oben gezeigt habe, verliere ich die Aufzeichnungsintegrität auf diese Weise. @marc: Das merke ich; Leider wurde mir diese DB-Struktur gegeben und ich kann sie nicht ändern. Mir ist klar, dass ich vielleicht die sprichwörtliche Kugel zu diesem Thema anbeißen muss, aber ich hoffe, dass es eine Lösung gibt, an die ich nicht gedacht habe ... – Mansfield

Antwort

3

Sie können jederzeit verwenden ROW_NUMBER statt GROUP BY

WITH A AS (
    SELECT Customer_Summary, customer_name, customer_address, customer_postal_code, 
     ROW_NUMBER() OVER (PARTITION BY Customer_Summary ORDER BY customer_name, customer_address) AS rn 
    FROM Order 
) 
SELECT Customer_Summary, customer_name, customer_address, customer_postal_code 
FROM A 
WHERE rn = 1 

Dann sind Sie frei zu bestellen sind die Kunden in der ORDER BY-Klausel zu verwenden. Momentan bestelle ich sie mit Namen und dann an Adresse.

Edit:

Meine Lösung tut, was für Sie gefragt. Aber ich stimme sicherlich mit den anderen überein: Wenn Sie die Datenbankstruktur ändern dürfen, wäre das eine gute Idee ... was Sie nicht sind (Ihren Kommentar gesehen). Nun, dann ist ROW_NUMBER() ein guter Weg.

+0

Das sieht interessant aus - lass mich es versuchen. – Mansfield

+0

Scheint so weit zu arbeiten. Dies ist eigentlich ein kleiner Teil einer viel größeren Abfrage, also werde ich versuchen, es in den Rest davon zu stecken und hoffe, es funktioniert immer noch. Der eine Vorbehalt ist auch, dass die Leistung akzeptabel sein muss - ich habe versucht, eine benutzerdefinierte Funktion zum Nachschlagen zu verwenden, aber ein großer Overhead hat diesen Plan zunichte gemacht. – Mansfield

+0

@Mansfield: ROW_NUMBER() ist meiner Erfahrung nach kein großer Overhead im Vergleich zu GROUP BY. Ich arbeite auch mit riesigen Tischen. Ich denke, Sie werden sehen, dass es ziemlich gut vorformuliert, besonders im Vergleich zu benutzerdefinierten Funktionen! – ANisus

3

Ich denke, Sie müssen Ihre Struktur neu denken.

Idealerweise hätten Sie eine Customer Tabelle mit einer eindeutigen ID. Dann würden Sie diese eindeutige ID in der Tabelle Order verwenden. Dann brauchen Sie nicht die seltsame "erste 10 Zeichen" -Methode, die Sie verwenden. Stattdessen gruppieren Sie nur nach der eindeutigen ID aus der Tabelle Customer.

Man könnte sogar dann auch eine separate Tabelle für Adressen, wobei jede Adresse auf den Kunden bezieht, mit mehreren Reihen (mit Feldern, sie als Heimatadresse Markierung, Lieferadresse, Rechnungsadresse, etc.).

Auf diese Weise trennen Sie die Kundeninformationen von den Adressinformationen und den Bestellinformationen. Wenn der Kunde seinen Namen (Heirat) oder seine Adresse (nach Hause) ändert, unterbricht er Ihre Daten nicht - Alles hängt mit den IDs zusammen, nicht mit den Daten selbst.

[Diese Beziehung wird als Fremdschlüssel bekannt.]

+0

Wie ich oben erwähnt habe, bin ich nicht in der Lage, die Struktur zu ändern (obwohl ich wünschte, ich wäre). Wenn das die einzige Lösung ist, dann habe ich kein Glück .... leider ist es in meiner Situation nicht machbar :( – Mansfield

+0

Wenn und wenn Sie eine Lösung bekommen, kann es sich lohnen, zu einer Entscheidung zurückzukehren, dass die aktuelle Struktur fast bricht Alle Best Practices für relationale Datenbanken, und dass der aktuelle und materielle Effekt darin besteht, die Analyse und das Reporting der Daten unglaublich zu erschweren – MatBailie

+0

Der Entscheider weiß es bereits - leider wird es nicht machbar sein, das Problem bald zu beheben . Danke für den Hinweis! – Mansfield

Verwandte Themen