On 2019/02/12 1:13 PM, Ivan Krylov wrote:
Hi!
I have a table of some values obtained from different sources:
create table test (
id, source_id, value,
primary key(id, source_id)
);
insert into test values
(1, 1, 11), (1, 2, 12), (1, 3, 13),
(2, 1, 21),
(3, 2, 32);
//...//
select id, value from (
select
id, value, row_number() over win as priority
from test
where
id IN (1,2)
window win as (
partition by id
order by abs(source_id-3)
)
) where priority = 1;
which results in the following query plan:
QUERY PLAN
|--CO-ROUTINE 1
| |--CO-ROUTINE 3
| | |--SEARCH TABLE test USING INDEX sqlite_autoindex_test_1 (id=?)
| | `--USE TEMP B-TREE FOR RIGHT PART OF ORDER BY
| `--SCAN SUBQUERY 3
`--SCAN SUBQUERY 1
Is this the most effective way to express my query? Can the more general
problem of assigning a priority to all sources (e.g. "I want records
from source_id 3, otherwise 1, otherwise 2") be solved in a similar way?
The Window function solution is good, but it can be done easily without
it, resulting in a bit more efficient query.
Here is the query set recreated showing first your previous stated query
and then an alternate. The semantics are made more legible using a CTE
here, but can be done without it. The essential difference is that it
uses a sub-query to obtain the minimum priority as opposed to
introducing a sub-table sort.
-- SQLite version 3.25.1 [ Release: 2018-09-18 ] on SQLitespeed
version 2.1.1.37.
--
================================================================================================
create table test (
id, source_id, value,
primary key(id, source_id)
);
insert into test values
(1, 1, 11), (1, 2, 12), (1, 3, 13),
(2, 1, 21),
(3, 2, 32);
select * from test;
-- id | source_id | value
-- --- | --------- | ------------
-- 1 | 1 | 11
-- 1 | 2 | 12
-- 1 | 3 | 13
-- 2 | 1 | 21
-- 3 | 2 | 32
-- Original proposed Query:
select id, value from (
select
id, value, row_number() over win as priority
from test
where
id IN (1,2)
window win as (
partition by id
order by abs(source_id-3)
)
) where priority = 1;
-- id | value
-- ------------ | ------------
-- 1 | 13
-- 2 | 21
EXPLAIN QUERY PLAN
select id, value from (
select
id, value, row_number() over win as priority
from test
where
id IN (1,2)
window win as (
partition by id
order by abs(source_id-3)
)
) where priority = 1;
-- id | parent | notused | detail
-- ------------ | ------ | ------- |
------------------------------------------------------------
-- 2 | 0 | 0 | CO-ROUTINE 1
-- 6 | 2 | 0 | CO-ROUTINE 3
-- 10 | 6 | 0 | SEARCH TABLE test USING INDEX
sqlite_autoindex_test_1 (id=?)
-- 42 | 6 | 0 | USE TEMP B-TREE FOR RIGHT PART
OF ORDER BY
-- 58 | 2 | 0 | SCAN SUBQUERY 3
-- 95 | 0 | 0 | SCAN SUBQUERY 1
-- New proposed Query
WITH AV(id, value, priority) AS (
SELECT id, value, abs(source_id-3)
FROM test
)
SELECT id, value
FROM AV AS AV1
WHERE AV1.id IN (1,2) AND AV1.priority = (SELECT MIN(priority) FROM AV
AS AV2 WHERE AV2.id = AV1.id)
;
-- id | value
-- ------------ | ------------
-- 1 | 13
-- 2 | 21
EXPLAIN QUERY PLAN
WITH AV(id, value, priority) AS (
SELECT id, value, abs(source_id-3)
FROM test
)
SELECT id, value
FROM AV AS AV1
WHERE AV1.id IN (1,2) AND AV1.priority = (SELECT MIN(priority) FROM AV
AS AV2 WHERE AV2.id = AV1.id)
;
-- id | parent | notused | detail
-- ------------ | ------ | ------- |
------------------------------------------------------------
-- 3 | 0 | 0 | SEARCH TABLE test USING INDEX
sqlite_autoindex_test_1 (id=?)
-- 21 | 0 | 0 | CORRELATED SCALAR SUBQUERY
-- 27 | 21 | 0 | SEARCH TABLE test USING INDEX
sqlite_autoindex_test_1 (id=?)
-- Script Stats: Total Script Execution Time: 0d 00h 00m and
00.078s
-- Total Script Query Time: 0d 00h 00m and
00.016s
-- Total Database Rows Changed: 5
-- Total Virtual-Machine Steps: 600
-- Last executed Item Index: 7
-- Last Script Error:
--
------------------------------------------------------------------------------------------------
-- 2019-02-12 13:48:56.260 | [Success] Script Success.
-- 2019-02-12 13:48:56.260 | [Success] Transaction Rolled back.
-- ------- DB-Engine Logs (Contains logged information from all DB
connections during run) ------
-- [2019-02-12 13:48:56.166] APPLICATION : Script
E:\Documents\SQLiteAutoScript.sql started at 13:48:56.166 on 12 February.
--
================================================================================================
_______________________________________________
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users