Глюк с not in () или <>
Глюк с not in () или <>
Наткнулся случайно на такой глюк:
имеются две таблицы:
CREATE TABLE TEST1 (
TEST1_ID INTEGER NOT NULL,
TEST1_NAME VARCHAR(10)
);
ALTER TABLE TEST1 ADD CONSTRAINT PK_TEST1 PRIMARY KEY (TEST1_ID);
CREATE TABLE TEST2 (
TEST2_ID INTEGER NOT NULL,
TEST1_ID INTEGER,
TEST2_NAME VARCHAR(10)
);
ALTER TABLE TEST2 ADD CONSTRAINT PK_TEST2 PRIMARY KEY (TEST2_ID);
ALTER TABLE TEST2 ADD CONSTRAINT FK_TEST2_1 FOREIGN KEY (TEST1_ID) REFERENCES TEST1 (TEST1_ID);
INSERT INTO TEST1 VALUES (1,'11111');
INSERT INTO TEST2 VALUES (1,1,'11111');
INSERT INTO TEST2 VALUES (2,null,'22222');
Запрос
SELECT * FROM Test2 WHERE test2.test1_id not in (1) /*или test2.test1_id <> 1*/ не возвращает ничего
Запрос
SELECT * FROM test2 WHERE test2.test1_id not in (SELECT test1.test1_id FROM test1) возвращает 1 строку (как вроде и должен)
Стоит FireBird 1.5 Classsic
Наверняка с такой фишкой уже сталкивались и эта тема обсуждалась. К сожалению, ничего не нашел (видимо искал плохо).
имеются две таблицы:
CREATE TABLE TEST1 (
TEST1_ID INTEGER NOT NULL,
TEST1_NAME VARCHAR(10)
);
ALTER TABLE TEST1 ADD CONSTRAINT PK_TEST1 PRIMARY KEY (TEST1_ID);
CREATE TABLE TEST2 (
TEST2_ID INTEGER NOT NULL,
TEST1_ID INTEGER,
TEST2_NAME VARCHAR(10)
);
ALTER TABLE TEST2 ADD CONSTRAINT PK_TEST2 PRIMARY KEY (TEST2_ID);
ALTER TABLE TEST2 ADD CONSTRAINT FK_TEST2_1 FOREIGN KEY (TEST1_ID) REFERENCES TEST1 (TEST1_ID);
INSERT INTO TEST1 VALUES (1,'11111');
INSERT INTO TEST2 VALUES (1,1,'11111');
INSERT INTO TEST2 VALUES (2,null,'22222');
Запрос
SELECT * FROM Test2 WHERE test2.test1_id not in (1) /*или test2.test1_id <> 1*/ не возвращает ничего
Запрос
SELECT * FROM test2 WHERE test2.test1_id not in (SELECT test1.test1_id FROM test1) возвращает 1 строку (как вроде и должен)
Стоит FireBird 1.5 Classsic
Наверняка с такой фишкой уже сталкивались и эта тема обсуждалась. К сожалению, ничего не нашел (видимо искал плохо).
Я заметил, но SELECT test1.test1_id FROM test1 возвращает тот же набор значений, но в этом случае с null никаких проблем не возникает.NULL <> остальным значениям.
поэтому not in (1) не учитывает null.
Ну вот такой вариант вроде прокатывает -по идее здесь надо добавить проверку на null.
насколько это соответствует стандарту, не знаю.
SELECT * FROM Test2 WHERE (test2.test1_id <> 1 OR test2.test1_id is Null)
Но как это это искусственно, на мой взгляд. Только чтобы проблему обойти.
А может влияние оказывать то, что планы по разному строятся?
для SELECT * FROM Test2 WHERE test2.test1_id not in (1)
PLAN (TEST2 NATURAL)
для SELECT * FROM test2 WHERE test2.test1_id not in (SELECT test1.test1_id FROM test1)
PLAN (TEST1 INDEX (PK_TEST1)) PLAN (TEST2 NATURAL)
???
Re: Глюк с not in () или <>
И это правильноchaos писал(а):Запрос
SELECT * FROM Test2 WHERE test2.test1_id not in (1) /*или test2.test1_id <> 1*/ не возвращает ничего
А это - старая бага, iircchaos писал(а):Запрос
SELECT * FROM test2 WHERE test2.test1_id not in (SELECT test1.test1_id FROM test1) возвращает 1 строку (как вроде и должен)
На 2-ке проверьchaos писал(а):Стоит FireBird 1.5 Classsic
-
- Сообщения: 53
- Зарегистрирован: 11 мар 2005, 15:44
Re: Глюк с not in () или <>
Лежит у нас сейчас сервер тестовый, на котором 2.0 гоняем. Поэтому не мог проверить перед тем как писать сюда. Впрочем, как написали выше - в 2.0 исправили вроде все.hvlad писал(а):На 2-ке проверьchaos писал(а):Стоит FireBird 1.5 Classsic