2016-05-05 6 views
1

Dies ist ein vereinfachtes Beispiel für das, was ich tun möchte. Angenommen, es gibt Tabelle Auftragnehmer genannt, die wie folgt aussieht:SQL Server Insert mit der Ansicht

name | paid_adjustment_amount | adj_date 
Bob | 1000     | 4/7/2016 
Mary | 2000     | 4/8/2016 
Bill | 5000     | 4/8/2016 
Mary | 4000     | 4/10/2016 
Bill | (1000)     | 4/12/2016 
Ann | 3000     | 4/30/2016 

Es gibt einen Blick auf den Auftragnehmer Tisch ist, nennen wir es v_sum, dass nur eine Summe der paid_adustment_amount nach Namen gruppiert ist. So sieht es wie folgt aus:

name | total_paid_amount 
Bob | 1000 
Mary | 6000 
Bill | 4000 
Ann | 3000 

Schließlich gibt es eine andere Tabelle namens to_date_payment die wie folgt aussieht:

name | paid_to_date_amount 
Bob | 1000 
Mary | 8000 
Bill | 3000 
Ann | 3000 
Joe | 4000  

ich die Informationen in der to_date_payment Tabelle in die v_sum Ansicht vergleichen möchten, und legen Sie eine neue Zeile in der Auftragnehmertabelle, um eine Anpassung anzuzeigen. So etwas wie dieses:

INSERT INTO contractor 
SELECT to_date_payment.name, 
    to_date_payment.paid_to_date_amount - v_sum.total_paid_amount, 
    GETDATE() 
FROM to_date_payment 
LEFT JOIN v_sum ON to_date_payment.name = v_sum.name 
WHERE to_date_payment.paid_to_date_amount - v_sum.total_paid_amount <> 0 
    OR v_sum.name IS NULL 

Gibt es Probleme mit der Verwendung einer Ansicht für diese? Mein Verständnis, bitte korrigieren Sie mich, wenn ich falsch liege, ist, dass eine Ansicht nur eine Ergebnismenge einer Abfrage ist. Und da die Ansicht von der Tabelle ist, in die ich neue Datensätze einfüge, befürchte ich, dass es Datenintegritätsprobleme geben könnte.

Danke für die Hilfe!

Antwort

0

Um vollständig zu verstehen, was Sie tun, sollten Sie auch die Definition für v_sum angeben. Im Allgemeinen bieten Ansichten einige Vorteile, insbesondere wenn sie indiziert sind. Weitere Details finden Sie unter here und here.

Die einfache Verwendung von Ansichten bietet keine Leistungsvorteile, aber sie sind sehr gut, Abstraktion über Tabellen bereitzustellen.

In Ihrem speziellen Fall, ich sehe kein Problem mit dem Blick in Joining, aber ich würde über mögliche Probleme kümmern zu:

1) JOIN VARCHARs statt integer mit - ON to_date_payment.name = v_sum.name - Wenn möglich, versuchen Sie JOIN auf Integer (IDs oder Fremdschlüssel IDs) Werte, da es schneller ist (Indizes für Integer-Spalten haben einen kleineren Schlüssel, Vergleiche sind etwas schneller).

2) ODER in Abfragen - führt in der Regel zu Leistungsproblemen. Eine Sache, zu versuchen, die SELECT wie folgt zu ändern:

SELECT to_date_payment.name, 
    to_date_payment.paid_to_date_amount - v_sum.total_paid_amount, 
    GETDATE() 
FROM to_date_payment 
JOIN v_sum ON to_date_payment.name = v_sum.name 
WHERE to_date_payment.paid_to_date_amount - v_sum.total_paid_amount <> 0 

UNION ALL 

SELECT to_date_payment.name, 
    to_date_payment.paid_to_date_amount, -- or NULL if this is really intended 
    GETDATE() 
FROM to_date_payment 
-- NOT EXISTS is usually faster than LEFT JOIN ... IS NULL 
WHERE NOT EXISTS (SELECT 1 FROM v_sum V WHERE V.name = to_date_payment.name) 

3) Mögliche unerwünschtes Ergebnis - standardmäßig Arithmetik mit NULL NULL zurück. Wenn in v_sum keine Übereinstimmung vorhanden ist, ist v_sum.total_paid_amount NULL und to_date_payment.paid_to_date_amount - v_sum.total_paid_amount wird auf NULL ausgewertet. Ist das richtig? Vielleicht ist to_date_payment.paid_to_date_amount - ISNULL(v_sum.total_paid_amount, 0) beabsichtigt.

+0

Danke! # 1 Leider habe ich keine Kontrolle über die eindeutigen Kennungen. Sie sind keine Namen, aber sie sind alphanumerische Kombinationen (z. B. AB123), die von einer externen Quelle stammen, die VARCHAR benötigen. # 2 Ich habe zuvor UNIONs anstelle von OR verwendet. Aber sollte ich alle ORs und INs vermeiden? Ich kann mir eine nicht verwandte Abfrage vorstellen, bei der ich ein Kriterium mit 6 Elementen in der IN-Klausel habe. Soll ich stattdessen 6 Abfragen mit 5 Unionen schreiben ??? # 3 Guter Fang. Ich schätze die Hilfe! – dwarn

+0

# 2. Dies sollte basierend auf dem tatsächlichen Ausführungsplan berücksichtigt werden. Wenn Sie nicht über eine sehr große Anzahl von Datensätzen verfügen, kann OR/IN möglicherweise noch eine angemessene Zeit erhalten. Außerdem können Sie für komplexe Abfragen eine temporäre Tabelle definieren und mehrere Einfügungen durchführen.Neben möglichen Leistungsoptimierungen ermöglicht es auch ein einfacheres Debugging (nach jedem Einfügen temporär prüfen). – Alexei

Verwandte Themen