I am using MySql and supposed to create a very complicated report that shows events state.
For example:
event_id | state | create_time
----------------------------------------------------
1 | PENDING | 2019-04-21 12:55:59.312
1 | COMPLETED | 2019-04-21 12:55:59.339
2 | PENDING | 2019-04-21 11:40:21.699
3 | PENDING | 2019-04-21 11:40:21.699
3 | FAILED | 2019-04-21 11:40:21.600
3 | COMPLETED | 2019-04-21 11:40:21.578
I need to select rows according to states preferences:
This should be paginated using OFFSET and SIZE.
Each event will be shown once.
expected result:
event_id | state | create_time
----------------------------------------------------
1 | COMPLETED | 2019-04-21 12:55:59.339
2 | PENDING | 2019-04-21 11:40:21.699
3 | FAILED | 2019-04-21 11:40:21.600
How can I do this in a single SQL query.
Regards, Ido
I suspect you want aggregation with some conditional logic, like this:
select event_id,
(case when sum(state = 'FAILED') > 0 then 'FAILED'
when sum(state = 'COMPLETED') > 0 then 'COMPLETED'
when sum(state = 'PENDING') > 0 then 'PENDING'
end) as new_state
from t
group by event_id;
You can do aggregation with coalesce()
:
select event_id,
coalesce(max(case when state = 'FAILED' then 'FAILED' end),
max(case when state = 'COMPLETED' then 'COMPLETED' end),
'PENDING'
)
from table t
group by event_id;
A other option is handling those states preferences as bitmasks.
Note This method assumes that there are no duplicated stats for a event_id.
Query
SELECT
t.*
FROM (
SELECT
t.event_id
, SUM(bitmask_table.bitmask) AS total_bitmask
FROM (
SELECT
DISTINCT
state
, CASE
WHEN state = 'PENDING'
THEN 2
WHEN state = 'COMPLETED'
THEN 4
WHEN state = 'FAILED'
THEN 8
END AS bitmask
FROM
t
) AS bitmask_table
INNER JOIN
t
ON
t.state = bitmask_table.state
GROUP BY
t.event_id
) AS group_bitmasked
INNER JOIN
t
ON
group_bitmasked.event_id = t.event_id
AND
t.state = CASE
WHEN group_bitmasked.total_bitmask & 8 AND group_bitmasked.total_bitmask & 4 AND group_bitmasked.total_bitmask & 2
THEN 'FAILED'
WHEN group_bitmasked.total_bitmask & 4 AND group_bitmasked.total_bitmask & 2
THEN 'COMPLETED'
WHEN group_bitmasked.total_bitmask & 2
THEN 'PENDING'
END
Result
| event_id | state | create_time |
| -------- | --------- | ----------------------- |
| 1 | COMPLETED | 2019-04-21 12:55:59.339 |
| 2 | PENDING | 2019-04-21 11:40:21.699 |
| 3 | FAILED | 2019-04-21 11:40:21.600 |
see demo
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.