On 2016/06/04 11:34 PM, Simon Slavin wrote:
On 4 Jun 2016, at 10:15pm, Jean-Christophe Deschamps <j...@antichoc.net> wrote:
Can't the same update be done more efficiently with a CTE?
The command inside the WITH has to be a SELECT command.
I wonder if there's a good reason for that. If the command inside WITH could
make changes to the database the result might be ambiguous, and very sensitive
to how the SQL engine works.
Well yes, WITH is a form of SELECT, so the function clause inside the
WITH has to be SELECT, in the same way that the function clause inside
an UPDATE statement has to be SET. However, the result of the WITH can
be applied to any Insert or Update or such (wherever a SELECT can be
used) - to demonstrate:
-- SQLite version 3.9.2 [ Release: 2015-11-02 ] on SQLitespeed
version 2.0.2.4.
-- Script Items: 5 Parameter Count: 0
-- 2016-06-05 02:26:52.452 | [Info] Script Initialized, Started
executing...
--
================================================================================================
CREATE TABLE Testy(
a INT,
b INT
);
WITH CTE(x) AS (
SELECT 1
UNION ALL
SELECT x+1 FROM CTE WHERE x<10
)
INSERT INTO Testy(a,b)
SELECT x,x*2 FROM CTE;
SELECT * FROM Testy;
-- a | b
-- ------------ | ------------
-- 1 | 2
-- 2 | 4
-- 3 | 6
-- 4 | 8
-- 5 | 10
-- 6 | 12
-- 7 | 14
-- 8 | 16
-- 9 | 18
-- 10 | 20
WITH CTE(x,y) AS (
SELECT 1,100
UNION ALL
SELECT x+1,y+(x*5) FROM CTE WHERE x<10
)
UPDATE Testy SET b=(SELECT CTE.y FROM CTE WHERE CTE.x = Testy.a
LIMIT 1) WHERE Testy.a < 8
SELECT * FROM Testy;
-- a | b
-- ------------ | -----
-- 1 | 100
-- 2 | 105
-- 3 | 115
-- 4 | 130
-- 5 | 150
-- 6 | 175
-- 7 | 205
-- 8 | 16
-- 9 | 18
-- 10 | 20
As to the OP's question of whether it can be done in a CTE (I assume he
means /using/ a CTE, and not necessarily having the working bits
/inside/ the CTE), there still is no way to use the UPDATE-FROM, even
from a CTE.
I might be wrong, but I think there is a problem with the UPDATE FROM
implementation; it has to require a scan one way or the other. Whether
you look up the value in the referenced table according to the key in
the updated table, or vice versa, there is no single-pass way of
avoiding the per-item lookup (unless somebody has done this - I'd be
very interested how). There is no way even for the QP to be sure a Key
column from both (or even one) of the tables will be involved in the
WHERE clause.
Perhaps if you have two tables that are exactly in sync (same Key-list,
same length), but that must be a serious edge-case.
The only advantage using the UPDATE-FROM syntax, which I can see, is
human legibility in SQL terms - which is not nothing btw.
Cheers,
Ryan
_______________________________________________
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users