Database Administrators
Q&A for database professionals who wish to improve their database skills
Latest Questions
66
votes
4
answers
149168
views
Does SQL Server CASE statement evaluate all conditions or exit on first TRUE condition?
Does the SQL Server (2008 or 2012, specifically) `CASE` statement evaluate all the `WHEN` conditions or does it exit once it finds a `WHEN` clause that evaluates to true? If it does go through the entire set of conditions, does that mean that the last condition evaluating to true overwrites what the...
Does the SQL Server (2008 or 2012, specifically)
CASE
statement evaluate all the WHEN
conditions or does it exit once it finds a WHEN
clause that evaluates to true? If it does go through the entire set of conditions, does that mean that the last condition evaluating to true overwrites what the first condition that evaluated to true did? For example:
SELECT
CASE
WHEN 1+1 = 2 THEN'YES'
WHEN 1+1 = 3 THEN 'NO'
WHEN 1+1 = 2 THEN 'NO'
END
The results is "YES" even though the last when condition should make it evaluate to "NO". It seems that it exits once it finds the first TRUE condition. Can someone please confirm if this is the *case*.
Juan Velez
(3303 rep)
May 29, 2013, 06:33 PM
• Last activity: Jun 23, 2025, 02:24 PM
-1
votes
1
answers
76
views
Oracle Violates Short-circuit in CASE Statement
**Problem** I am well aware that SQL is a declarative language and does not enforce short-circuiting. Oracle, on the other hand, [explicitly states][1] that short-circuiting takes place for CASE statements. I have the following example: ```SQL -- Query 1 SELECT CASE WHEN ASCII(SUBSTR(test_texts, 5,...
**Problem**
I am well aware that SQL is a declarative language and does not enforce short-circuiting. Oracle, on the other hand, explicitly states that short-circuiting takes place for CASE statements.
I have the following example:
-- Query 1
SELECT
CASE
WHEN ASCII(SUBSTR(test_texts, 5, 1)) < 110 THEN 1
ELSE 0
END
FROM test_data_types ORDER BY ID OFFSET 1 ROWS FETCH FIRST 1 ROWS ONLY;
-- Query 2
SELECT
CASE
WHEN ASCII(SUBSTR(test_texts, 5, 1)) < 110 THEN 1
ELSE 0/0 -- zero division
END
FROM test_data_types ORDER BY ID OFFSET 1 ROWS FETCH FIRST 1 ROWS ONLY;
Query1 returns 1 because the 5th character of the row ('world'
) is 'd'
with ASCII value 100 but Query2 raises a zero division error, meaning the short-circuiting did not take place.
I assumed this was because the expression 0/0
is constant and optimization kicked is, however, expression ln(ora_hash(test_texts) - 10)
, which is equivalent to ln(0)
, throws an error unconditionally as well. Hence, eager evaluation of constant expressions is not the (sole) reason.
Surprisingly enough, short-circuiting does take place when I increase the upper bound to 120, i.e., ASCII(...) < 120
. Again, the selected letter is 'd'
with ASCII value of 100, which is less than both 110 and 120, but only 120 works for some reason. I really can't wrap my mind around this.
**Additional Context**
I am doing research on blind SQL injection optimization so I'm limited to SELECT queries. Also, the error forcing is intentional, I'm just looking for a way to make it conditional. Lastly, I'm using Oracle Database 23ai Free.
**Setup for Reproduction**
CREATE TABLE test_data_types (
id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
test_texts CLOB
);
INSERT INTO test_data_types (test_texts) VALUES ('hello');
INSERT INTO test_data_types (test_texts) VALUES ('world');
INSERT INTO test_data_types (test_texts) VALUES ('hello world');
INSERT INTO test_data_types (test_texts) VALUES ('hello world');
INSERT INTO test_data_types (test_texts) VALUES ('hello world');
INSERT INTO test_data_types (test_texts) VALUES ('hello world');
INSERT INTO test_data_types (test_texts) VALUES ('hello world');
INSERT INTO test_data_types (test_texts) VALUES ('hello world');
INSERT INTO test_data_types (test_texts) VALUES ('hello world');
INSERT INTO test_data_types (test_texts) VALUES ('hello');
COMMIT;
**Question(s)**
1) Why is short-circuiting not respected here?
2) If it's is due to optimization, are there some expressions (e.g., heavy computation) that are evaluated last?
3) As a last resort, are there some other SELECT constructs that produce the desired behavior (conditional errors)?
**TL;DR of the Bellow Discussion**
The issue is not that CASE short-circuiting is violated, but that the SELECT part has precedence over the OFFSET and FETCH parts, leading to evaluation of the first row ("hello"
) which triggers the zero division.
Pruzo
(3 rep)
May 31, 2025, 11:09 AM
• Last activity: Jun 2, 2025, 02:07 PM
0
votes
2
answers
1133
views
Limit rows in Correlated Subquery
I have one big and two small issues with my query I need help with. First, I want a SQL (postgres if it matters) query that gets `SUM` of last two ratings of fruits and makes a new column for each fruit column on original table with corresponding result. Conditions are that it has to have happened i...
I have one big and two small issues with my query I need help with.
First, I want a SQL (postgres if it matters) query that gets
SUM
of last two ratings of fruits and makes a new column for each fruit column on original table with corresponding result. Conditions are that it has to have happened in the past (before current row date) and I only want the last 2 records and column for 'rush_order' has to have value 'yes'.
Right now my query gets all records but I only want last 2. I tried to use LIMIT
in each of the 4 subqueries and also tried OFFSET 0
and FETCH FIRST 2 ROWS ONLY
but can't get it to work. If there is a way to use the OFFSET
it could eliminate the need to use the comparison of date f2.delivered_on),0) +
COALESCE(
(SELECT sum(f3.rating2)
FROM fruit f3
WHERE f1.name1 = f3.name2 AND f1.delivered_on > f3.delivered_on) ,0)
AS fruit1_rating,
COALESCE(
(SELECT sum(f4.rating2)
FROM fruit f4
WHERE f1.name2 = f4.name2 AND f1.delivered_on > f4.delivered_on),0) +
COALESCE(
(SELECT sum(f5.rating1)
FROM fruit f5
WHERE f1.name2 = f5.name1 AND f1.delivered_on > f5.delivered_on) ,0) AS fruit2_rating
FROM fruit f1;
```
Expected result:

noblerthanoedipus
(101 rep)
Apr 28, 2021, 02:34 PM
• Last activity: Feb 13, 2025, 03:02 PM
0
votes
2
answers
874
views
comparing a date value in one table against multiple values in another to categorise by age
I have created a form which allows users to enter multiple, unlimited month number values and label them to use against inventory to categorise the age of each item. **Table 1 - AgeConfig - Manually enterted by users** id | customer_id | start_month | label ---|-------------|-------------|----------...
I have created a form which allows users to enter multiple, unlimited month number values and label them to use against inventory to categorise the age of each item.
**Table 1 - AgeConfig - Manually enterted by users**
id | customer_id | start_month | label
---|-------------|-------------|----------
1 | 171 | 0 | Current
2 | 171 | 3 | 3-6 Months
3 | 171 | 6 | 6-12 Months
4 | 171 | 12 | 12+ Months
**Table 2 - Inventory**
id | customer_id | item_no | entry_date | qty | cost
----|-------------|---------|------------|-----|--------
1 | 171 | CH72394 | 2022-01-28 | 3 | 430.10
1 | 171 | CH72395 | 2022-02-28 | 4 | 30.10
1 | 171 | CH72396 | 2022-03-28 | 1 | 130.10
1 | 171 | CH72397 | 2022-01-22 | 5 | 320.50
1 | 171 | CH72398 | 2022-02-22 | 1 | 22.30
1 | 171 | CH72399 | 2022-01-22 | 1 | 92.30
1 | 171 | CH72400 | 2022-01-24 | 1 | 392.80
I am trying to present this in SQL using CASE but I dont know how to compare it against a variable number of rows and make sure I start at the highest and work to the lowest.
I am trying to use CASE but am stumped
SELECT customer_id,
item_no,
entry_date,
CASE
WHEN (TIMESTAMPDIFF(MONTH, entry_date, NOW()) > MAX(start_month)) THEN label
WHEN (TIMESTAMPDIFF(MONTH, entry_date, NOW()) > 2NDMAX(start_month)) THEN label
WHEN (TIMESTAMPDIFF(MONTH, entry_date, NOW()) > 3RDMAX(start_month)) THEN label
...
END,
qty,
cost
FROM Inventory
INNER JOIN AgeConfig USING (customer_id)
WHERE customer_id = 171
I dont know how to incrementally test against highest down to lowest and then use the corresponding label so that the result is:
id | customer_id | item_no | entry_date | age | qty | cost
----|-------------|---------|------------|-------------|-----|------
1 | 171 | CH72394 | 2022-01-28 | 3-6 Months | 3 | 430.10
1 | 171 | CH72395 | 2022-02-28 | Current | 4 | 30.10
1 | 171 | CH72396 | 2021-03-28 | Current | 1 | 130.10
1 | 171 | CH72397 | 2022-01-22 | 3-6 Months | 5 | 320.50
1 | 171 | CH72398 | 2021-08-22 | 6-12 Months | 1 | 22.30
1 | 171 | CH72399 | 2021-01-22 | 12+ Months | 4 | 92.30
1 | 171 | CH72400 | 2022-01-24 | 3-6 Months | 1 | 392.80
php-b-grader
(101 rep)
Apr 28, 2022, 11:37 PM
• Last activity: Feb 5, 2025, 12:02 PM
0
votes
3
answers
2440
views
Query for getting the sum of all unique entries in a column
Currently I'm using mysql to return the sum of all data in a column that have the same word. To do this I'm using the following query: SELECT SUM(CASE WHEN status_to = 'Draft' THEN 1 END) AS draft, SUM(CASE WHEN status_to = 'Unpublish' THEN 1 END) AS unpublish, SUM(CASE WHEN status_to = 'Publish' TH...
Currently I'm using mysql to return the sum of all data in a column that have the same word. To do this I'm using the following query:
SELECT SUM(CASE WHEN status_to = 'Draft' THEN 1 END) AS draft,
SUM(CASE WHEN status_to = 'Unpublish' THEN 1 END) AS unpublish,
SUM(CASE WHEN status_to = 'Publish' THEN 1 END) AS publish,
SUM(CASE WHEN status_to = 'Action' THEN 1 END) AS action,
SUM(CASE WHEN status_to = 'Unlisted' THEN 1 END) AS unlisted,
SUM(CASE WHEN status_to = 'Sold' THEN 1 END) AS sold,
SUM(CASE WHEN status_to = 'Let' THEN 1 END) AS let
FROM
crm_logs
This gives out the correct output in my database for all the terms I've specified, but now I've found that there are more status variables in the database other than these specified above. So I want a way to have the same functionality of this statement, but make the status variable dynamic.
Basically if this is the query, SUM(CASE WHEN status_to = 'Draft' THEN 1 END) AS draft
, both the occurrences of draft should be dynamic.
JJM50
(103 rep)
Oct 12, 2021, 12:39 PM
• Last activity: Jul 24, 2024, 06:35 AM
1
votes
1
answers
2779
views
Problem with SELECT CASE WHEN THEN, 0 result
Need an advice in `SELECT CASE WHEN THEN`. In main, removed all unimportant function, make as simply as can, usual `select i.fav_id FROM users;` i see original table: fav_id 1 2 6 7 but i need change some id's for result will be: fav_id 1 3 6 8 i do: SELECT i.fav_id = CASE WHEN 2 THEN 3 WHEN 3 THEN...
Need an advice in
SELECT CASE WHEN THEN
. In main, removed all unimportant function, make as simply as can, usual select i.fav_id FROM users;
i see original table:
fav_id
1
2
6
7
but i need change some id's for result will be:
fav_id
1
3
6
8
i do:
SELECT i.fav_id =
CASE
WHEN 2 THEN 3
WHEN 3 THEN 2
WHEN 7 THEN 8
WHEN 8 THEN 7
ELSE i.fav_id
END fav_id
FROM favorites
AS i WHERE i.member = '123456'
i got:
fav_id
0
0
0
0
I'm new to select CASE selection but after searching a lot of manuals and examples, and did not fund how to solve my problem.
used:
libmysql - mysqlnd 5.0.11-dev - 20120503
PHP: 5.6.28-1+deb.sury.org~xenial+1
phpMyAdmin 4.5.4.1deb2ubuntu2
Vladimir Ch
(159 rep)
Nov 28, 2016, 06:51 AM
• Last activity: Apr 19, 2024, 11:51 PM
0
votes
1
answers
132
views
How to Avoid Duplicates with multiple joins and multiple case statements
I have a query which has multiple joins and need case statements for multiple columns to get the correct data. Although I can manage to get the data, it creates a lot of duplicate rows. Seems like 1 row per case statement search. As an example the code is below. Any help will be appreciated. CREATE...
I have a query which has multiple joins and need case statements for multiple columns to get the correct data. Although I can manage to get the data, it creates a lot of duplicate rows. Seems like 1 row per case statement search.
As an example the code is below. Any help will be appreciated.
CREATE TABLE
#TABLE1 (id INT,
VAL INT,
SAMP NVARCHAR(20))
INSERT INTO #TABLE1
VALUES (1,1,'1-1'),(1,2,'1-2'),(1,3,'1-3'),(2,1,'2-1'),(2,2,'2-2'),(3,1,'3-1')
CREATE TABLE #TABLE2 (id INT, VAL INT)
INSERT INTO #TABLE2
VALUES (1,1),(1,2),(1,3),(2,1),(3,1)
SELECT
CASE WHEN T2.id = 2 AND T1.VAL = T2.VAL THEN T1.SAMP END
AS SAMPLE_2,
CASE WHEN T2.id = 3 AND T1.VAL = T2.VAL THEN T1.SAMP END
AS SAMPLE_3
FROM #TABLE1 T1 LEFT JOIN #TABLE2 T2
ON T1.id = T2.id
DROP TABLE #TABLE1
DROP TABLE #TABLE2
Result
-----------------
Sample2 | Sample3
NULL | NULL
NULL | NULL
NULL | NULL
NULL | NULL
NULL | NULL
NULL | NULL
NULL | NULL
NULL | NULL
2-1 | NULL
NULL | NULL
NULL | 3-1
=====================
Preferred Result would be
-----------------#
Sample2 | Sample3
2-1 | 3-1
=====================
Gibbs Khan
(1 rep)
Apr 16, 2024, 04:01 PM
• Last activity: Apr 16, 2024, 05:16 PM
1
votes
1
answers
636
views
Regex help in Snowflake
I am trying to write a regex that can replace '[', ']' and '].' with '_' and in cases where ']' is the last character it should be replaced with '' but I am struggling to come up with a regex for it that works in all cases because Snowflake does not support lookahead & lookbehind. My question is, ha...
I am trying to write a regex that can replace '[', ']' and '].' with '_' and in cases where ']' is the last character it should be replaced with '' but I am struggling to come up with a regex for it that works in all cases because Snowflake does not support lookahead & lookbehind.
My question is, has anyone tried/achieved to do this before? or is it impossible and I should just give up??
Eg:
-
look_behind --> look_behind_0
- look_behind_positive --> look_behind_0_positive_1
Pepe Silvia
(11 rep)
Apr 14, 2024, 11:20 PM
• Last activity: Apr 15, 2024, 11:40 PM
0
votes
0
answers
23
views
MySQL case sensitivity setting
Does anyone know the file name or path where I can change the lower_case_tables_names value on the latest version of MySQL Windows 11?
Does anyone know the file name or path where I can change the lower_case_tables_names value on the latest version of MySQL Windows 11?
Tubatse Katlego Moloi
(1 rep)
Jan 14, 2024, 02:35 PM
0
votes
2
answers
842
views
Comparing 2 count columns with case
I have 2 tables, size and cost. My query does a count with a greater than comparison of cost and counts different sizes. table1: size u table2: cred t Here is my query: select u.size as size ,count(u.size) * .4 as "40% of size" ,count(case when (t.cred * 12) > (t.inc *.3) then 1 end) as "30% cost" f...
I have 2 tables, size and cost. My query does a count with a greater than comparison of cost and counts different sizes.
table1: size u
table2: cred t Here is my query:
select u.size as size
,count(u.size) * .4 as "40% of size"
,count(case when (t.cred * 12) > (t.inc *.3) then 1 end) as "30% cost"
from cred t
join size u on t.id = u.id
group by u.size
The result is as follows:
|Size|40% of size|30% cost| |:---|:----------|:-------| |0 |75.6 |50 | |1 |470.4 |160 | |2 |414.8 |114 | |3 |202.8 |59 | |4 |40 |21 | |5 |8.8 |9 | |6 |0.4 |1 | I want the query to show a 'Y' if the cost column is larger than the size column and a 'N' if it is smaller. Here would be the result I'm looking for:
|Size|40% of size|30% cost|Y/N| |:---|:----------|:-------|:--| |0 |75.6 |50 |N | |1 |470.4 |160 |N | |2 |414.8 |114 |N | |3 |202.8 |59 |N | |4 |40 |21 |N | |5 |8.8 |9 |Y | |6 |0.4 |1 |Y | Is there a way to show this? I tried to use the following, but I get this: Boolean value cannot be operated with non-Boolean value. ,case when ((t.cred * 12) > (t.inc * .3)) > (count(u.size) * .4) then 'Y' else 'N' end as "Y/N"
Not sure if I need to do a subquery?
table2: cred t Here is my query:
select u.size as size
,count(u.size) * .4 as "40% of size"
,count(case when (t.cred * 12) > (t.inc *.3) then 1 end) as "30% cost"
from cred t
join size u on t.id = u.id
group by u.size
The result is as follows:
|Size|40% of size|30% cost| |:---|:----------|:-------| |0 |75.6 |50 | |1 |470.4 |160 | |2 |414.8 |114 | |3 |202.8 |59 | |4 |40 |21 | |5 |8.8 |9 | |6 |0.4 |1 | I want the query to show a 'Y' if the cost column is larger than the size column and a 'N' if it is smaller. Here would be the result I'm looking for:
|Size|40% of size|30% cost|Y/N| |:---|:----------|:-------|:--| |0 |75.6 |50 |N | |1 |470.4 |160 |N | |2 |414.8 |114 |N | |3 |202.8 |59 |N | |4 |40 |21 |N | |5 |8.8 |9 |Y | |6 |0.4 |1 |Y | Is there a way to show this? I tried to use the following, but I get this: Boolean value cannot be operated with non-Boolean value. ,case when ((t.cred * 12) > (t.inc * .3)) > (count(u.size) * .4) then 'Y' else 'N' end as "Y/N"
Not sure if I need to do a subquery?
tkmagnet
(75 rep)
Sep 13, 2023, 03:56 PM
• Last activity: Sep 13, 2023, 10:03 PM
-1
votes
1
answers
61
views
how to GROUP BY so that not all results are grouped
When I use my query to select all data from the table I have a problem with the custnumber field. If custnumber is returned within the same month then it should group the results but only then. This is my query: SELECT MONTH(periode) AS maand, YEAR(periode) AS jaar, maandfacturen.verzenddatum, maand...
When I use my query to select all data from the table I have a problem with the custnumber field. If custnumber is returned within the same month then it should group the results but only then.
This is my query:
SELECT MONTH(periode) AS maand,
YEAR(periode) AS jaar,
maandfacturen.verzenddatum,
maandfacturen.factuurnr,
maandfacturen.custnumber,
klantgegevens.bedrijfsnaam AS bedrijfsnaam,
maandfacturen.totaalbedragexcl,
maandfacturen.totaalbedragincl,
maandfacturen.betaald
FROM maandfacturen
LEFT JOIN klantgegevens ON maandfacturen.custnumber = klantgegevens.custnumber
WHERE
periode
LIKE '2023%'
GROUP BY custnumber
ORDER BY periode ASC, factuurnr ASC
This query does not work cause if I use GROUP BY custnumber it groups all records and thats not the result I need as all months also get grouped. After googling I found that I might need to use CASE to solve this but I am not sure how to use this.
Any help would be greatly appreciated.
James
(1 rep)
Jul 13, 2023, 11:28 AM
• Last activity: Jul 13, 2023, 02:30 PM
0
votes
1
answers
153
views
Set variable on multiple case within each group
Say I have below table | | | | | | | | | |-|-|-|-|-|-|-|-| | cis|aid|cid|apid|ntime|buid|flg|jid| |30|1208|229067737|1026|9|DDDD400C|0|0| |30|1209|229067737|1026|11|DDDD400C|0|0| |30| 0|229067737|1026|12|DDDD400C|1|100| |30|1210|229067737|1026|13|DDDD400C|0|0| |30| 0|229067737|1026|14|DDDD400C|1|101...
Say I have below table
| | | | | | | | |
|-|-|-|-|-|-|-|-|
| cis|aid|cid|apid|ntime|buid|flg|jid|
|30|1208|229067737|1026|9|DDDD400C|0|0|
|30|1209|229067737|1026|11|DDDD400C|0|0|
|30| 0|229067737|1026|12|DDDD400C|1|100|
|30|1210|229067737|1026|13|DDDD400C|0|0|
|30| 0|229067737|1026|14|DDDD400C|1|101|
**Note** that I don't want to split the statements, need to do above in a single statement.
CREATE TABLE Aiarcle
(cis INT, aid INT, cid INT, apid INT, ntime INT, buid VARCHAR(MAX), flg INT, jid INT)
INSERT INTO Aiarcle
(cis, aid, cid, apid, ntime, buid, flg, jid)
VALUES (30, 1208, 229067737, 1026, 9, 'DDDD400C', 0, 0)
,(30, 1209, 229067737, 1026, 11, 'DDDD400C', 0, 0)
,(30, 0, 229067737, 1026, 12, 'DDDD400C', 1, 100)
,(30, 1210, 229067737, 1026, 13, 'DDDD400C', 0, 0)
,(30, 0, 229067737, 1026, 14, 'DDDD400C', 1, 101);
Now I need to do following here. First filter out rows WHERE ntime > 10
.
SELECT * FROM Aiarcle WHERE ntime > 10
Then all I need to do is check in a single statement if flg 0
and flg 1
esists in my table and set both variables.
This is what I did, but this does not works.
DECLARE @flg0Exists BIT = 1
DECLARE @flg1Exists BIT = 1
SELECT @flg0Exists = CASE WHEN flg = 0 THEN 1 ELSE 0 END,
@flg1Exists = CASE WHEN flg = 1 THEN 1 ELSE 0 END
FROM Aiarcle WITH (NOLOCK) WHERE nTime > 10
SELECT @flg0Exists, @flg1Exists
The output of which was

Himanshuman
(197 rep)
Jul 13, 2023, 10:24 AM
• Last activity: Jul 13, 2023, 11:05 AM
-1
votes
1
answers
2039
views
Get percentage from results from two case results
How i can get percentage from two resuts from case staments? SELECT *, COUNT(CASE WHEN estado_rep >=11 and RELATION=1 THEN 1 ELSE NULL END) as pendiente, COUNT(CASE WHEN estado_rep >=11 and RELATION=2 THEN 1 ELSE NULL END) as realizada from AVERIES GROUP BY ID_AV Result query now aa bb cc pendiente...
How i can get percentage from two resuts from case staments?
SELECT *,
COUNT(CASE WHEN estado_rep >=11 and RELATION=1 THEN 1 ELSE NULL END) as pendiente,
COUNT(CASE WHEN estado_rep >=11 and RELATION=2 THEN 1 ELSE NULL END) as realizada
from AVERIES GROUP BY ID_AV
Result query now
aa bb cc pendiente realizada
----------- --------- ---------
xxx xxx xxx 2 1
xxx xxx xxx 3 0
I want add a query percentage to root query.
(realizada*100)/(realizada+pendiente) as Progress
aa bb cc pendiente realizada progress
-- -- -- --------- --------- --------
xxx xxx xxx 2 1 33%
xxx xxx xxx 3 0 0%
Thanks
reksoz
(1 rep)
Mar 7, 2019, 09:34 PM
• Last activity: May 17, 2023, 06:24 PM
2
votes
1
answers
120
views
MySQL - multiple CASE ordering with joined table
I have two tables: **EVENTS** | ID | Name | |----|--------------| | 1 | First event | | 2 | Second event | | 3 | Third event | | 4 | Fourth event | | 5 | Fifth event | **EVENTS_META** | ID | EventID | MetaKey | MetaValue | |----|---------|--------------|---------------------| | 1 | 2 | date_expired...
I have two tables:
**EVENTS**
| ID | Name |
|----|--------------|
| 1 | First event |
| 2 | Second event |
| 3 | Third event |
| 4 | Fourth event |
| 5 | Fifth event |
**EVENTS_META**
| ID | EventID | MetaKey | MetaValue |
|----|---------|--------------|---------------------|
| 1 | 2 | date_expired | 2023-02-09 00:00:00 |
| 2 | 2 | date_expired | 2023-01-23 00:00:00 |
| 3 | 3 | date_expired | 2023-04-30 00:00:00 |
| 4 | 3 | date_expired | 2023-01-22 00:00:00 |
| 5 | 4 | date | 2023-06-12 00:00:00 |
| 6 | 4 | date | 2023-02-03 00:00:00 |
| 7 | 5 | date_expired | 2023-02-13 00:00:00 |
| 8 | 5 | date | 2023-01-02 00:00:00 |
| 9 | 5 | date | 2023-01-01 00:00:00 |
I would like to select all items from events table ordered by the following logic:
1. First "group" of items on the list are the ones that have any "date" rows in events_meta table.
2. Second "group" of items on the list are the ones that have any "date_expired" rows in events_meta table.
3. Third "group" of items on the list are the ones that don't have "date" nor "date_expired" rows.
Also, within each of those groups (except the last one) events are ordered by their "date" or "date_expired" **minimum** date values. So the first group is ordered by "date" dates. Second group is ordered by "date_expired" dates.
Each event can have any number of "date" or "date_expired" rows attached to them.
**The desired outcome would be:**
1. Fifth event
2. Fourth event
3. Third event
4. Second event
5. First event
I think I have managed to create the "groups" but I'm struggling to sort the groups by dates:
SELECT events.Name FROM
events
LEFT JOIN events_meta
ON events.ID = events_meta.EventId
GROUP BY events.Name
ORDER BY
CASE WHEN (SELECT COUNT(*) FROM events_meta WHERE events.ID = events_meta.EventID AND events_meta.MetaKey = 'date') > 0 THEN 0
WHEN (SELECT COUNT(*) FROM events_meta WHERE events.ID = events_meta.EventID AND events_meta.MetaKey = 'date_expired' AND events_meta.MetaKey != 'date') > 0 THEN 1
ELSE 2
END;
Here's a dbfiddle with the exact same dataset: https://dbfiddle.uk/55vp__vZ
Martin J
(23 rep)
Mar 30, 2023, 03:41 PM
• Last activity: Mar 31, 2023, 05:15 AM
10
votes
2
answers
141681
views
How do I select data with a case statement and group by?
I'm trying to manipulate data a little by using a case statement but can't seem to figure it out. Stops -------------------- 1Stop 1-Stop 1 stop 1 Stop 1stop 1 Stop 2-Stop Im trying to come up with: 1-Stop.... 6 2-Stop.... 1 What I've tried is: select CASE when Stops = '1Stop' OR Stops = '1 Stop' OR...
I'm trying to manipulate data a little by using a case statement but can't seem to figure it out.
Stops
--------------------
1Stop
1-Stop
1 stop
1 Stop
1stop
1 Stop
2-Stop
Im trying to come up with:
1-Stop.... 6
2-Stop.... 1
What I've tried is:
select CASE when
Stops = '1Stop' OR
Stops = '1 Stop' OR
Stops = '1 stop' then '1-Stop'
ELSE Stops END, count(*)
from table group by Stops
KingKongFrog
(373 rep)
Sep 19, 2014, 09:28 PM
• Last activity: Feb 3, 2023, 12:44 PM
0
votes
2
answers
196
views
SQL multiple condition case when
SQL Case When - I have a column with job status options B & D. I want to create a case when SQL statement that will check and retrieve employee IDs with both statuses in the column. In thise case shown it should only return John Doe, not Doe John or John Jr. [![enter image description here][1]][1] [...
SQL Case When - I have a column with job status options B & D. I want to create a case when SQL statement that will check and retrieve employee IDs with both statuses in the column. In thise case shown it should only return John Doe, not Doe John or John Jr.

jones0207
(9 rep)
Jan 24, 2023, 07:55 PM
• Last activity: Jan 25, 2023, 08:16 AM
1
votes
1
answers
352
views
Problem with case statement and dynamic table name
I have the following case statement ```sql case %1$s::text when ''lookup_relation_job'' then case %1$s.relation when ''followers'' then ''get-followers'' when ''following'' then ''get-following'' when ''blocking'' then ''get-blocking'' when ''muting'' then ''get-muting'' end when ''manage_list_membe...
I have the following case statement
case %1$s::text
when ''lookup_relation_job'' then
case %1$s.relation
when ''followers'' then ''get-followers''
when ''following'' then ''get-following''
when ''blocking'' then ''get-blocking''
when ''muting'' then ''get-muting''
end
when ''manage_list_members_job'' then
case %1$s.add
when true then ''add-list-member''
else ''remove-list-member''
end
when ''manage_relation_job'' then
case %1$s.relation
when ''follow'' then
case %1$s.add
when true then ''add-follow''
else ''remove-follow''
end
when ''block'' then
case %1$s.add
when true then ''add-block''
else ''remove-block''
end
when ''mute'' then
case %1$s.add
when true then ''add-mute''
else ''remove-mute''
end
end
end
Here %1$s
is an argument of type regclass
.
When I run the above with %1$s
= lookup_relation_job
, Postgres throws an error saying: column lookup_relation_job.add does not exist
. But it shouldn't even check for the add column when the argument is lookup_relation_job
according to the case logic. What's going wrong here?
I suspect either there's some kind of fall-through happening here (I double checked that I've closed all case
statements with end
), or Postgres checks for all the conditions even if the parent condition is false (this is unlikely).
Any help would be appreciated!
Edit: Below is the whole relevant PL/pgSQL function
create or replace function get_jobs_to_add
(job_table regclass, active_jobs bigint[], failed_jobs bigint[], out result bigint[])
as $$
begin
execute format('
select array(
select
distinct on (%1$s.user_id)
%1$s.id
from %1$s
left join user_profile on user_profile.id = %1$s.user_id
left join twitter_api_rate_limit on
twitter_api_rate_limit.user_twitter_id = user_profile.twitter_id and
twitter_api_rate_limit.endpoint = (
case %1$s::text
when ''lookup_relation_job'' then
case %1$s.relation
when ''followers'' then ''get-followers''
when ''following'' then ''get-following''
when ''blocking'' then ''get-blocking''
when ''muting'' then ''get-muting''
end
when ''manage_list_members_job'' then
case %1$s.add
when true then ''add-list-member''
else ''remove-list-member''
end
when ''manage_relation_job'' then
case %1$s.relation
when ''follow'' then
case %1$s.add
when true then ''add-follow''
else ''remove-follow''
end
when ''block'' then
case %1$s.add
when true then ''add-block''
else ''remove-block''
end
when ''mute'' then
case %1$s.add
when true then ''add-mute''
else ''remove-mute''
end
end
end
)
where %1$s.finished = false
and %1$s.paused = false
and %1$s.deleted = false
and (twitter_api_rate_limit.resets_at is null or twitter_api_rate_limit.resets_at < now())
and not (%1$s.id = any(%3$L))
and %1$s.user_id not in (
select user_id from %1$s where id = any(%2$L)
)
order by %1$s.user_id, %1$s.priority desc
);', job_table, active_jobs, failed_jobs) into result;
end
$$ language plpgsql;
Sumit Ghosh
(111 rep)
Jan 1, 2023, 06:23 PM
• Last activity: Jan 1, 2023, 07:15 PM
3
votes
2
answers
763
views
Zero/NULL Case Trick
In the book *Getting Started with SQL*, Thomas Nield talks about a technique he calls the ***zero/null case trick***: > There is a simple but powerful tool that can apply different filtering > conditions to different aggregations. We can create separate total > counts when a tornado was present vers...
In the book *Getting Started with SQL*, Thomas Nield talks about a technique he calls the ***zero/null case trick***:
> There is a simple but powerful tool that can apply different filtering
> conditions to different aggregations. We can create separate total
> counts when a tornado was present versus not present in two separate
> columns:
>
> SELECT year, month,
> SUM(CASE WHEN tornado = 1 THEN precipitation ELSE 0 END) as tornado_precipitation,
> SUM(CASE WHEN tornado = 0 THEN precipitation ELSE 0 END) as non_tornado_precipitation
> FROM station_data
> WHERE year >= 1990
> GROUP BY year, month
>
> What we have effectively done is get rid of the WHERE conditions when
> tornado = 1 or tornado = 0, and then move those conditions to CASE
> expressions inside the SUM() functions. If the condition is met, the
> precipitation value is added to the sum. If not, a 0 is added, having
> no effect. We do these for both columns, on for when a tornado was
> present and one for when a tornado was not present respectively.
>
> You can make the CASE expression have as many condition/value pairs as
> you need, giving you the ability to do highly particular interceptions
> of values with your aggregations. You can also use this trick to
> emulate crosstabs and pivot tables, expressing aggregations into
> separate columns rather than in rows. A common example of this is
> doing current year/previous year analysis, as you can express separate
> years with different columns.
----------------
As a novice, that technique seems like it could come in really handy for summarizing data. I want to look up that technique online to get more information.
The author of that book calls the technique the "zero/null case trick". But when I google that term, I don't get many results.
Question:
Is there a generally accepted name for that technique? (that would yield more results when searching online)
User1974
(1527 rep)
Sep 6, 2021, 07:23 AM
• Last activity: Dec 5, 2022, 09:39 AM
0
votes
0
answers
482
views
Replacing Part of a string within a group Concat
I have part of a string that I would like to remove when selecting. The Problem is that there are a few pieces within the string that changes. This is what I have so far. Select GROUP_CONCAT(DISTINCT Substr(Concat(Round(ms_cart.cart_qty), 'x', ms_cart.cart_sku), 1, 12), Concat(' | ', ms_cart_options...
I have part of a string that I would like to remove when selecting. The Problem is that there are a few pieces within the string that changes. This is what I have so far.
Select
GROUP_CONCAT(DISTINCT Substr(Concat(Round(ms_cart.cart_qty), 'x', ms_cart.cart_sku), 1, 12), Concat(' | ', ms_cart_options.co_opt_name), Replace(ms_cart_options.co_opt_name, '
This is a buddy package. Who will the buddy photo be taken with
: THIS PART CHANGESWhat team?: THIS PART CHANGES', '')) as Items FROM ms_cart INNER JOIN ms_orders ON ms_orders.order_id = ms_cart.cart_order INNER JOIN ms_cart_options ON ms_cart_options.co_cart_id=ms_cart.cart_id
Joey Freeman
(1 rep)
Nov 21, 2022, 05:58 AM
• Last activity: Nov 21, 2022, 01:50 PM
0
votes
1
answers
1222
views
How to conditionally return multiple different columns in sqlite?
I am trying to return multiple columns only if a condition matches, else, return something else. Using Sqlite3, my understanding is that the way to do this is using CASE, so something like this: ``` SELECT CASE WHEN EXISTS(SELECT 1 FROM disk_encryption WHERE user_uuid IS NOT "" AND vault_status = 'o...
I am trying to return multiple columns only if a condition matches, else, return something else. Using Sqlite3, my understanding is that the way to do this is using CASE, so something like this:
SELECT
CASE
WHEN EXISTS(SELECT 1 FROM disk_encryption WHERE user_uuid IS NOT "" AND vault_status = 'on' LIMIT 1) then "Passing" else "Failing"
END AS Status,
'Encryption Enabled' AS Policy;
This all works great, it returns the following:
Status | Policy
------------------------------
Passing | Encryption Enabled
Now, I am trying to return contextual data if Status = 'Failing'
.
For example, if Status = 'Failing'
, I would like to return the Policy
and Status
columns, as well as the output of:
SELECT name, type, vault_status FROM disk_encryption;
How would I do this?
Here is simplified test data I am working with:
CREATE TABLE disk_encryption(name
TEXT, type
TEXT, user_uuid
TEXT, vault_status
TEXT, PRIMARY KEY (name
)) WITHOUT ROWID;
INSERT INTO disk_encryption
VALUES ('/dev/disk1s1', 'APFS Encryption', '504', 'on');
Josh Brower
(113 rep)
Oct 21, 2022, 04:18 PM
• Last activity: Oct 24, 2022, 11:19 AM
Showing page 1 of 20 total questions