GOOGLE ADS

Samstag, 30. April 2022

Wie kann ich eine Running Total Sumifs-ähnliche Funktion in SQL erstellen?

Ich bin ziemlich neu in SQL, aber Excel ist viel zu langsam geworden, um weiter damit zu arbeiten, also versuche ich es mit SQLiteStudio. Ich möchte eine Spalte in einer Abfrage erstellen, die die laufende Summe im Laufe der Zeit anzeigt (gekennzeichnet als Zeitplanpunkte, die jeden Prozentsatz durch die Laufzeit eines Projekts markieren). Abgeschlossen markiert, ob ein Standort die Installation abgeschlossen hat (J/NULL), und wird einfach verwendet, um unvollständige Standorte aus weiteren Berechnungen herauszufiltern.

Ich habe derzeit

With cte as(
Select [Location]
,[HW/NonHW]
,[Obligation/Actual]
,[Schedule Point]
,[CY20$]
,[Vendor Name]
,[Vendor Zip Code]
,[Complete]
,[System Rollup (Import)]
,IIf([Complete] = "Y", [CY20$], 0) As [Completed Costs]
FROM data)
Select [Location]
,[HW/NonHW]
,[Obligation/Actual]
,[Schedule Point]
,[CY20$]
,[Vendor Name]
,[Vendor Zip Code]
,[Complete]
,[System Rollup (Import)]
,[Completed Costs]
,SUM([Completed Costs]) OVER (PARTITION BY [Obligation/Actual], [Normalized Schedule Location 1%],[System Rollup (Import)], [HW/NonHW]) As [CY20$ Summed]
FROM cte

An diesem Punkt möchte ich eine Summe nicht für jeden Zeitplanpunkt, sondern für alle vorherigen Zeitplanpunkte (dh den <=Operator in einer Excel-Summenaussage) erstellen.

Als Referenz sind hier die Summen, die ich versuche zu replizieren:

=SUMIFS($N$2:$N$541790,$AU$2:$AU$541790,"Y",$AQ$2:$AQ$541790,AQ2,$AI$2:$AI$541790,AI2,$AH$2:$AH$541790,AH2,$AJ$2:$AJ$541790, "<=" & AJ2)

Nist CY20$, AUist Complete, AQist System, AIist Obligation/Actual, AHist HW/NonHW, AJist Zeitplanpunkt.

Jede Hilfe wäre willkommen!


Lösung des Problems

Das Äquivalent zu SUMIFS ist eine Kombination aus SUMund CASE- WHENin SQL.

Abstraktes Beispiel:

SELECT
SUM(
CASE
WHEN <condition1> AND <condition2> AND <condition3> THEN 1
ELSE 0
END
)
FROM yourtable

Oben sind condition1, condition2und condition3logische Ausdrücke, die <und >teilen nur mit, dass Sie dort einen Ausdruck haben, er ist nicht Teil der Syntax. Es ist auch unnötig, genau 3 Bedingungen zu haben, Sie können so viele haben, wie Sie möchten. Außerdem ist es nicht erforderlich, ANDals Operator zu verwenden, Sie können Ihren eigenen Ausdruck nach Belieben erstellen. Der Grund, warum ich den ANDOperator verwendet habe, war, dass Sie beabsichtigen, eine Disjunktion zu haben, vermutlich basierend auf der Tatsache, dass Sie verwendet haben SUMIFS.

Ein konkreteres Beispiel:

CREATE TABLE person(
number int,
name text,
age int
);
INSERT INTO person(number, name, age)
VALUES(1, 'Joe', 12);
INSERT INTO person(number, name, age)
VALUES(2, 'Jane' 12);
INSERT INTO person(number, name, age)
VALUES(3, 'Robert', 16);
INSERT INTO person(number, name, age)
VALUES(4, 'Roberta', 15);
INSERT INTO person(number, name, age)
VALUES(5, 'Blian', 18);
INSERT INTO person(number, name, age)
VALUES(6, 'Bigusdqs', 19);
SELECT
SUM(
CASE
WHEN age <= 16 AND name <> 'Joe' THEN 1
ELSE 0
END
) AS MySUMIFS
FROM person;

BEARBEITEN

Wenn wir wissen möchten, wie viele Personen jünger als die aktuelle Person sind, können wir einen Join durchführen:

SELECT 
SUM(
CASE
WHEN p2.age <= p1.age THEN 1
ELSE 0
END
) AS MySUMIFS, name
FROM person p1
JOIN person p2
ON p1.name <> p2.name
GROUP BY p1.name;

EDIT2

Erstellte eine Fiddle basierend auf den oben beschriebenen Ideen, Sie können sie unter https://dbfiddle.uk/?rdbms=sqlite_3.27&fiddle=3cb0232e5d669071a3aa5bb1df68dbca erreichen

Der Code in der Geige:

CREATE TABLE person(
number int,
name text,
age int
);
INSERT INTO person(number, name, age)
VALUES(1, 'Joe', 12);
INSERT INTO person(number, name, age)
VALUES(2, 'Jane' 12);
INSERT INTO person(number, name, age)
VALUES(3, 'Robert', 16);
INSERT INTO person(number, name, age)
VALUES(4, 'Roberta', 15);
INSERT INTO person(number, name, age)
VALUES(5, 'Blian', 18);
INSERT INTO person(number, name, age)
VALUES(6, 'Bigusdqs', 19);
SELECT
SUM(
CASE
WHEN p2.age <= p1.age THEN 1
ELSE 0
END
) AS MySUMIFS, p1.name
FROM person p1
JOIN person p2
ON p1.name <> p2.name
GROUP BY p1.name;

Geben Sie hier die Bildbeschreibung ein

Keine Kommentare:

Kommentar veröffentlichen

Warum werden SCHED_FIFO-Threads derselben physischen CPU zugewiesen, obwohl CPUs im Leerlauf verfügbar sind?

Lösung des Problems Wenn ich das richtig verstehe, versuchen Sie, SCHED_FIFO mit aktiviertem Hyperthreading ("HT") zu verwenden, ...