sqlite 的意外行为
Unexpected behaviour with sqlite
我有 2 个表,一个是 {number,letter},另一个是 {number,number}
我想select {number,letter} 其中在 {number,number} 中的任何地方都提到了数字
看起来你的 post 主要是代码;请添加更多详细信息。因此,在遇到一些麻烦之后,我会胡扯一会儿,通过下面的代码使问题非常容易重现。
/*
Unexpected behaviour with sqlite.
Save this as problem.sql and do sqlite3 < problem.sql
to demonstrate the effect.
I have 2 tables, 1 is {number,letter} the other {number,number}
I want to select {number,letter} where number is mentioned
anywhere in {number,number}
So my query is
SELECT ALL num,letter
FROM numberLetter
WHERE num IN (
(
SELECT n1 FROM pairs
UNION
SELECT n2 FROM pairs;
)
);
I've actually wrapped this up with some views in the sql below,
results are the same whatever way you do it.
I think I'm making a stupid mistake or have a conceptual problem?
results:
$ sqlite3 < problem.sql
this is pairList
n1
2
3
4
5
7
8
this is selectedNumberLetter which I expect to have 6 rows...
num|letter
2|b
*/
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE pairs(
"n1" TEXT,
"n2" TEXT
);
INSERT INTO pairs VALUES('2','3');
INSERT INTO pairs VALUES('5','4');
INSERT INTO pairs VALUES('8','7');
CREATE TABLE numberLetter(
"num" TEXT,
"letter" TEXT
);
INSERT INTO numberLetter VALUES('1','a');
INSERT INTO numberLetter VALUES('2','b');
INSERT INTO numberLetter VALUES('3','c');
INSERT INTO numberLetter VALUES('4','d');
INSERT INTO numberLetter VALUES('5','e');
INSERT INTO numberLetter VALUES('6','f');
INSERT INTO numberLetter VALUES('7','g');
INSERT INTO numberLetter VALUES('8','h');
INSERT INTO numberLetter VALUES('9','i');
INSERT INTO numberLetter VALUES('10','j');
CREATE VIEW pairList AS
SELECT n1 FROM pairs
UNION
SELECT n2 FROM pairs;
CREATE VIEW selectedNumberLetter AS
SELECT ALL num,letter
FROM numberLetter
WHERE num IN (
(
SELECT n1 FROM pairList
)
);
COMMIT;
SELECT 'this is pairList';
.header on
SELECT * FROM pairList;
.header off
SELECT '
this is selectedNumberLetter which I expect to have 6 rows...';
.header on
SELECT * FROM selectedNumberLetter;
问题出在这里:
WHERE num IN ((SELECT n1 FROM pairList));
您不能将 SELECT
语句括在另一组括号中,因为如果这样做,SQLite 最终将 return 只有 pairList
中的 1 行而不是所有行。
更改为:
CREATE VIEW selectedNumberLetter AS
SELECT num,letter
FROM numberLetter
WHERE num IN (SELECT n1 FROM pairList);
但是用EXISTS
更容易解决这个需求:
select n.*
from numberLetter n
where exists (select 1 from pairs p where n.num in (p.n1, p.n2));
参见demo。
我有 2 个表,一个是 {number,letter},另一个是 {number,number}
我想select {number,letter} 其中在 {number,number} 中的任何地方都提到了数字
看起来你的 post 主要是代码;请添加更多详细信息。因此,在遇到一些麻烦之后,我会胡扯一会儿,通过下面的代码使问题非常容易重现。
/*
Unexpected behaviour with sqlite.
Save this as problem.sql and do sqlite3 < problem.sql
to demonstrate the effect.
I have 2 tables, 1 is {number,letter} the other {number,number}
I want to select {number,letter} where number is mentioned
anywhere in {number,number}
So my query is
SELECT ALL num,letter
FROM numberLetter
WHERE num IN (
(
SELECT n1 FROM pairs
UNION
SELECT n2 FROM pairs;
)
);
I've actually wrapped this up with some views in the sql below,
results are the same whatever way you do it.
I think I'm making a stupid mistake or have a conceptual problem?
results:
$ sqlite3 < problem.sql
this is pairList
n1
2
3
4
5
7
8
this is selectedNumberLetter which I expect to have 6 rows...
num|letter
2|b
*/
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE pairs(
"n1" TEXT,
"n2" TEXT
);
INSERT INTO pairs VALUES('2','3');
INSERT INTO pairs VALUES('5','4');
INSERT INTO pairs VALUES('8','7');
CREATE TABLE numberLetter(
"num" TEXT,
"letter" TEXT
);
INSERT INTO numberLetter VALUES('1','a');
INSERT INTO numberLetter VALUES('2','b');
INSERT INTO numberLetter VALUES('3','c');
INSERT INTO numberLetter VALUES('4','d');
INSERT INTO numberLetter VALUES('5','e');
INSERT INTO numberLetter VALUES('6','f');
INSERT INTO numberLetter VALUES('7','g');
INSERT INTO numberLetter VALUES('8','h');
INSERT INTO numberLetter VALUES('9','i');
INSERT INTO numberLetter VALUES('10','j');
CREATE VIEW pairList AS
SELECT n1 FROM pairs
UNION
SELECT n2 FROM pairs;
CREATE VIEW selectedNumberLetter AS
SELECT ALL num,letter
FROM numberLetter
WHERE num IN (
(
SELECT n1 FROM pairList
)
);
COMMIT;
SELECT 'this is pairList';
.header on
SELECT * FROM pairList;
.header off
SELECT '
this is selectedNumberLetter which I expect to have 6 rows...';
.header on
SELECT * FROM selectedNumberLetter;
问题出在这里:
WHERE num IN ((SELECT n1 FROM pairList));
您不能将 SELECT
语句括在另一组括号中,因为如果这样做,SQLite 最终将 return 只有 pairList
中的 1 行而不是所有行。
更改为:
CREATE VIEW selectedNumberLetter AS
SELECT num,letter
FROM numberLetter
WHERE num IN (SELECT n1 FROM pairList);
但是用EXISTS
更容易解决这个需求:
select n.*
from numberLetter n
where exists (select 1 from pairs p where n.num in (p.n1, p.n2));
参见demo。