Разбирался со старым глюком в своей
программе и наткнулся на странное
поведение селекта со вложенным
подзапросом.

Есть 2 таблицы (master-detail, хотя потом для
воспроизведения данного поведения
оказалость достаточно одной detail):
CREATE TABLE MASTER_TABLE (
    ID      INTEGER NOT NULL,
    STATUS  SMALLINT NOT NULL
);
ALTER TABLE MASTER_TABLE ADD CONSTRAINT PK_MASTER_TABLE PRIMARY KEY
(ID);


CREATE TABLE DETAIL_TABLE (
    ID         INTEGER NOT NULL,
    ID_MASTER  INTEGER,
    NAME       VARCHAR(100)
);
ALTER TABLE DETAIL_TABLE ADD CONSTRAINT PK_DETAIL_TABLE PRIMARY KEY
(ID);
ALTER TABLE DETAIL_TABLE ADD CONSTRAINT FK_DETAIL_TABLE_M FOREIGN KEY
(ID_MASTER) REFERENCES MASTER_TABLE (ID);

Данные:
MASTER_TABLE
INSERT INTO MASTER_TABLE (ID, STATUS) VALUES (1, 0);
INSERT INTO MASTER_TABLE (ID, STATUS) VALUES (2, 1);
INSERT INTO MASTER_TABLE (ID, STATUS) VALUES (3, 0);

DETAIL_TABLE:

INSERT INTO DETAIL_TABLE (ID, ID_MASTER, NAME) VALUES (1, 2, '2-1');
INSERT INTO DETAIL_TABLE (ID, ID_MASTER, NAME) VALUES (2, 2, '2-2');
INSERT INTO DETAIL_TABLE (ID, ID_MASTER, NAME) VALUES (3, 1, '1-3');
INSERT INTO DETAIL_TABLE (ID, ID_MASTER, NAME) VALUES (4, 3, '3-4');

Обычный запрос с left outer join:
select
  dt.id,
  dt.id_master,
  dt.name
from
  DETAIL_TABLE dt LEFT OUTER JOIN MASTER_TABLE mt
    on dt.id_master = mt.id
where
  mt.status = 1
order by dt.id_master, id

возвращает ожидаемые результаты:
ID      ID_MASTER       NAME
1       2               2-1
2       2               2-2

А запрос со вложенным во from
подзапросом с left outer join:
select
  dt.id,
  dt.id_master,
  dt.name
from
  DETAIL_TABLE dt LEFT OUTER JOIN
    (
    select id
    from MASTER_TABLE mt
    where
      mt.status = 1

    -- select 2 from rdb$database
    ) as m (id)
    on dt.id_master = m.id
order by dt.id_master, id

возвращает все строки из DETAIL_TABLE:
ID      ID_MASTER       NAME
3       1               1-3
1       2               2-1
2       2               2-2
4       3               3-4

И даже более простой запрос
select
  dt.id,
  dt.id_master,
  dt.name
from
  DETAIL_TABLE dt LEFT OUTER JOIN
    (
   select 2 from rdb$database
    ) as m (id)
    on dt.id_master = m.id
order by dt.id_master, id
тоже возвращает все строки из DETAIL_TABLE.

Вопрос: это так и должно быть или это
ошибка?

В Release Notes такое поведение не
обозначено.

Ответить