This query returns 40319 records:
SELECT artist,
title,
composer AS alib_composer,
master.composer AS master_composer
FROM alib
INNER JOIN
master ON hex(alib.__path) = hex(master.__path) AND
alib.l_title = lower(master.title) AND
alib.composer != master.composer AND
length(alib.composer) != length(master.composer) AND
master.composer LIKE "% %" AND
alib.composer NOT LIKE "% %";
Translating above into the following UPDATE query results in all records in alib being updated. Could someone help me understand why this is the case?
UPDATE alib
SET composer = (
SELECT composer
FROM master
WHERE hex(alib.__path) = hex(master.__path) AND
alib.l_title = lower(master.title) AND
alib.composer != master.composer AND
length(alib.composer) != length(master.composer) AND
master.composer LIKE "% %" AND
alib.composer NOT LIKE "% %"
);
I suspect I know why, but turning the update into something like this:
UPDATE alib
SET composer = master.composer
WHERE hex(alib.__path) = hex(master.__path) AND
alib.l_title = lower(master.title) AND
alib.composer != master.composer AND
length(alib.composer) != length(master.composer) AND
master.composer LIKE "% %" AND
alib.composer NOT LIKE "% %";
causes SQLite to complain:
Error while executing SQL query on database 'x': no such column: master.composer
Because there is no WHERE clause on the outer/main UPDATE SQL ie it is basiclly
UPDATE alib SET composer = the_result_of_the_subquery;
You want a WHERE clause to say which rows to update along the lines of :-
UPDATE alib SET composer = the_result_of_the_subquery WHERE ??????;
Or to use your code :-
UPDATE alib
SET composer = (
SELECT composer
FROM master
WHERE hex(alib.__path) = hex(master.__path) AND
alib.l_title = lower(master.title) AND
alib.composer != master.composer AND
length(alib.composer) != length(master.composer) AND
master.composer LIKE "% %" AND
alib.composer NOT LIKE "% %"
)
WHERE the_expression_to_restrict_which_rows_are_updated
;
This hasn't been fully tested but this may be solution you are looking for :-
WITH cte AS
(
SELECT
master.composer AS master_composer,
alib.rowid AS arowid
FROM alib
INNER JOIN
master ON hex(alib.__path) = hex(master.__path)
AND alib.l_title = lower(master.title)
AND alib.composer != master.composer
AND length(alib.composer) != length(master.composer)
AND master.composer LIKE '% %'
AND alib.composer NOT LIKE '% %'
)
UPDATE alib
SET composer =
(
SELECT cte.master_composer FROM cte WHERE cte.arowid = alib.rowid
)
WHERE alib.rowid IN (SELECT arowid FROM cte);
The following SQL was used for testing :-
DROP TABLE IF EXISTS alib;
DROP TABLE IF EXISTS master;
CREATE TABLE IF NOT EXISTS alib (__path,l_title,composer);
CREATE TABLE IF NOT EXISTS master (__path,title,artist,composer);
INSERT INTO alib VALUES
('path1','this','bert'),
('path2','something else','Joe'),
('path2','something else','Joe'), -- duplicate likely irrelevant but still updated
('path2','something else','Joe Someone'), -- already has space in composer skipped
('path100','an so on','x') -- no equivalent in master
;
INSERT INTO master VALUES
('path1','this','fred','bert'), -- ignored as no space
('path1','this','fred bloggs','Julia smith'),
('path2','something else','Alison','Joe Brown')
;
/* DEMO OF EXTRACTED ROWS */
WITH cte AS
(
SELECT
master.composer AS master_composer,
alib.rowid AS arowid
FROM alib
INNER JOIN
master ON hex(alib.__path) = hex(master.__path)
AND alib.l_title = lower(master.title)
AND alib.composer != master.composer
AND length(alib.composer) != length(master.composer)
AND master.composer LIKE '% %'
AND alib.composer NOT LIKE '% %'
)
SELECT * FROM cte;
WITH cte AS
(
SELECT
master.composer AS master_composer,
alib.rowid AS arowid
FROM alib
INNER JOIN
master ON hex(alib.__path) = hex(master.__path)
AND alib.l_title = lower(master.title)
AND alib.composer != master.composer
AND length(alib.composer) != length(master.composer)
AND master.composer LIKE '% %'
AND alib.composer NOT LIKE '% %'
)
UPDATE alib
SET composer =
(
SELECT cte.master_composer FROM cte WHERE cte.arowid = alib.rowid
)
WHERE alib.rowid IN (SELECT arowid FROM cte);
SELECT * FROM alib;
DROP TABLE IF EXISTS alib;
DROP TABLE IF EXISTS master;
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.