Reputation: 21
I'm pretty new to SQL, but Excel has become far too slow to continue working with, so I'm trying SQLiteStudio. I'm looking to create a column in a query showing running total over time (characterized as Schedule Points, marking each percent through a project's run time). Complete marks whether a Location has completed the install (Y/NULL), and is used simply to filter out incomplete locations from further calculations.
I currently have
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
At this point, what I'm looking to do is a sum not for each Schedule Point, but all prior Schedule Points (i.e. the <=
operator in an Excel sumifs statement)
For reference, here is the sumifs I am trying to replicate:
=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)
N
is CY20$
, AU
is Complete
, AQ
is System
, AI
is Obligation/Actual
, AH
is HW/NonHW
, AJ
is Schedule Point.
Any help would be appreciated!
Upvotes: 1
Views: 61
Reputation: 76464
The equivalent to SUMIFS is a combination of SUM
and CASE
-WHEN
in SQL.
Abstract example:
SELECT
SUM(
CASE
WHEN <condition1> AND <condition2> AND <condition3> THEN 1
ELSE 0
END
)
FROM yourtable
In the above, condition1
, condition2
and condition3
are logical expressions, the <
and >
are just notifying that you have an expression there, it is not part of the syntax. It is also unnecessary to have exactly 3 conditions, you can have as many as you like. Also, it is unnecessary to use AND
as the operator, you can construct your own expression as you like. The reason for which I have used the AND
operator was that you intend to have a disjunction, presumably, based on the fact that you used SUMIFS
.
A more concrete example:
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;
EDIT
If we are interested to know how many people have a smaller age than the current person, then we can do a join:
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
Created a Fiddle based on the ideas described above, you can reach it at https://dbfiddle.uk/?rdbms=sqlite_3.27&fiddle=3cb0232e5d669071a3aa5bb1df68dbca
The code in the fiddle:
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;
Upvotes: 0