My question looks similar to this one: How can I SELECT rows with MAX(Column value), DISTINCT by another column in SQL?, but I've some specific issues.
Let's assume that we have such table:
| title_id | title | type_id | crit_id |
+----------+----------+---------+---------+
| 1 | title_A1 | 0 | 1111 |
| 2 | title_A2 | 1 | 1111 |
| 3 | title_B1 | 50 | 2222 |
| 4 | title_B2 | 50 | 2222 |
| 5 | title_C1 | 72 | 3333 |
| 6 | title_C2 | 1 | 3333 |
| 7 | title_C4 | 0 | 3333 |
"title_id" is unique and indexed, "title" and "crit_id" are indexed.
As a result I'd like to have only rows grouped by "crit_id", holding the minimum value of custom rank (priority) that is calculated on type_id. For e.q. rank for type_id looks like:
type_id = 0 - rank = 10
type_id = 50 -rank = 11
type_id = 1 - rank = 15
type_id = 72- rank = 35
etc...
And at the end everything should be ordered alphabetically by "title" According to requirements results should be:
| title_id | title | type_id | crit_id | rank |
+----------+----------+---------+---------+------+
| 1 | title_A1 | 0 | 1111 | 10 |
| 3 | title_B1 | 50 | 2222 | 11 |
| 7 | title_C4 | 0 | 3333 | 10 |
I'm using SQLITE. I can get required results with query:
SELECT *, MIN(CASE WHEN type_id = 0 THEN 10
WHEN type_id = 1 THEN 11
WHEN type_id = 50 THEN 15
WHEN type_id = 72 THEN 35
ELSE 1000 END) as rank
FROM titles WHERE ... GROUP BY crit_id ORDER BY title
This query has really bad performance. On a 1 000 000 records it executes more than 10 seconds.
Here are couple problems:
- We have about 60% of records with type_id == 0. And in this case we are executing MIN and CASE clauses about 600 000 times. As rank is calculated we can't use index here. I'd like some how minimize execution of it.
- Using GROUP BY on such amount of data brings really bad performance. And after reading Selecting records holding group-wise maximum (on a unique column), I'm not sure if it always have correct behaviour. Hope that there is another way that does similar thing as Group By.
PS: I'm running this on embeded device, with slow memory card, thus access to DB is so slow.
I'm not SQL expert, so if there exist any solution I'd appreciate it. Thanks in advance.
Forgot to mention, we can LIMIT
amount of results that should be returned. For e.q. LIMIT 500
.