Die Datenbank ist Postgres, aber jede SQL-Logik sollte helfen.SQL Filtern von doppelten Zeilen wegen schlechter ETL
Ich erhalte die Menge von Verkaufsangeboten, die ein bestimmtes Produkt in der Stückliste enthalten. Ich mache das in zwei Schritten: Schritt 1, rufen Sie alle DISTINCT-Angebotsnummern ab, die ein bestimmtes Produkt (nach Produktnummer) enthalten.
Der zweite Schritt, rufen Sie das vollständige Angebot mit allen Produkten für jede eindeutige Angebotsnummer aufgeführt.
So weit, so gut. Jetzt das schwierige Stück. Einige Zeilen sind Duplikate, andere nicht. Diejenigen, die Duplikate sind (Angebotsnummer & Angebotsversion & Leitungsnummer), können oder müssen möglicherweise keine Wartung für sie haben. Ich möchte die Zeile auswählen, die Wartung hat, die größer als 0 ist. Die doppelten Zeilen, die ich ausschließen möchte, sind die, die eine 0 Wartung haben. Das Problem ist, dass einige Zeilen, die keine Duplikate haben, 0 Wartung haben, so dass ich nicht nur nach Wartung filtern kann.
Um dies spannend zu machen, enthält die Datenbank Zitate aus mehr als 20 Jahren. Und die Daten Wissenschaftler Jungs haben gerade zugegeben, dass vielleicht der ETL-Prozess einige Fehler hat ...
--- step 0
--- cleanup the workspace
SET CLIENT_ENCODING TO 'UTF8';
DROP TABLE IF EXISTS product_quotes;
--- step 1
--- get list of Product Quotes
CREATE TEMPORARY TABLE product_quotes AS (
SELECT DISTINCT master_quote_number
FROM w_quote_line_d
WHERE item_number IN (<< model numbers >>)
);
--- step 2
--- Now join on that list
SELECT
d.quote_line_number,
d.item_number,
d.item_description,
d.item_quantity,
d.unit_of_measure,
f.ref_list_price_amount,
f.quote_amount_entered,
f.negtd_discount,
--- need to calculate discount rate based on list price and negtd discount (%)
CASE
WHEN ref_list_price_amount > 0
THEN 100 - (ref_list_price_amount + negtd_discount)/ref_list_price_amount *100
ELSE 0
END AS discount_percent,
f.warranty_months,
f.master_quote_number,
f.quote_version_number,
f.maintenance_months,
f.territory_wid,
f.district_wid,
f.sales_rep_wid,
f.sales_organization_wid,
f.install_at_customer_wid,
f.ship_to_customer_wid,
f.bill_to_customer_wid,
f.sold_to_customer_wid,
d.net_value,
d.deal_score,
f.transaction_date,
f.reporting_date
FROM w_quote_line_d d
INNER JOIN product_quotes pq ON (pq.master_quote_number = d.master_quote_number)
INNER JOIN w_quote_f f ON
(f.quote_line_number = d.quote_line_number
AND f.master_quote_number = d.master_quote_number
AND f.quote_version_number = d.quote_version_number)
WHERE d.net_value >= 0 AND item_quantity > 0
ORDER BY f.master_quote_number, f.quote_version_number, d.quote_line_number
Die Logik die doppelten Zeilen zu filtern ist wie folgt: Für jeden master_quote_number/version_number Paar, Scheck um zu sehen, ob es doppelte Zeilennummern gibt. Wenn ja, wählen Sie die mit Wartung> 0.
Selbst in einer CASE-Anweisung bin ich nicht sicher, wie man das schreibt.
Gedanken? Die Datenbank ist Postgres, aber jede SQL-Logik sollte helfen.
Dies funktioniert, aber ein Self-Join ist fast immer teurer als die entsprechende Abfrage mit Fensterfunktionen – SlimsGhost