Здравствуйте, garant, Вы писали:
G>Помогите, пожалуйста. Уже весь мозг сломал. G>Есть две таблицы, A и B, примерно такие: G>CREATE TABLE A ( G> id INTEGER, G> link INTEGER G>); G>CREATE TABLE B ( G> id INTEGER G>); G>Мне нужно выбрать из таблицы A те id, для которых существуют ВСЕ link, G>содержащиеся в B.id. Если я пишу: G>SELECT DISCTINCT id FROM A WHERE link IN (SELECT id FROM B); G>то B.id складываются по OR, а мне надо по AND. Это вообще возможно?
Может быть как-то так:
SELECT DISCTINCT id FROM A WHERE id NOT IN (SELECT A.id FROM A LEFT JOIN B ON A.link=B.id WHERE B.id IS NULL)
Здравствуйте, garant, Вы писали:
G>Помогите, пожалуйста. Уже весь мозг сломал.
G>Есть две таблицы, A и B, примерно такие:
G>CREATE TABLE A ( G> id INTEGER, G> link INTEGER G>);
G>CREATE TABLE B ( G> id INTEGER G>);
G>Мне нужно выбрать из таблицы A те id, для которых существуют ВСЕ link, G>содержащиеся в B.id. Если я пишу:
G>SELECT DISCTINCT id FROM A WHERE link IN (SELECT id FROM B);
G>то B.id складываются по OR, а мне надо по AND. Это вообще возможно?
Вроде бы примерно так, если не задумываться, а в лоб решить. На SQLite не проверял, может быть нужна доработка напильником.
select
id
from
(
select
a.id,
COUNT(a.link) as qty_a,
max(b.qty) as qty_b
from
(select distinct id, link from @a) a
left join
(select COUNT(id) qty from (select distinct id from @b) b) b on 1=1
group by
id
) t
where
qty_a = qty_b
10.02.2012 9:22, Sergey Lizin пишет: > Может быть как-то так: > SELECT DISCTINCT id FROM A WHERE id NOT IN (SELECT A.id FROM A LEFT JOIN B ON A.link=B.id WHERE B.id IS NULL)
10.02.2012 9:37, _ABC_ пишет: > Вроде бы примерно так, если не задумываться, а в лоб решить. На SQLite не проверял, может быть нужна доработка напильником.
Работает! Спасибо. Но, похоже, действительно в лоб. Буду допиливать.
10.02.2012 9:37, _ABC_ пишет: > Вроде бы примерно так, если не задумываться, а в лоб решить. На SQLite не проверял, может быть нужна доработка напильником.
Не, рано я обрадовался. Тут заточено на количество link в A, а когда
количество их одинаково, но значения разные, то работает неверно.
Вот такое:
CREATE TABLE "A" (
"id" INTEGER,
"link" INTEGER
);
INSERT INTO "A" VALUES(1,1);
INSERT INTO "A" VALUES(1,2);
INSERT INTO "A" VALUES(2,1);
INSERT INTO "A" VALUES(3,2);
INSERT INTO "A" VALUES(3,3);
CREATE TABLE "b" (
"id" INTEGER
);
INSERT INTO "b" VALUES(1);
INSERT INTO "b" VALUES(2);
По условию должно возвращаться только "1", а возвращается "1" и "3".
Здравствуйте, garant, Вы писали:
G>Помогите, пожалуйста. Уже весь мозг сломал.
G>Есть две таблицы, A и B, примерно такие:
G>CREATE TABLE A ( G> id INTEGER, G> link INTEGER G>);
G>CREATE TABLE B ( G> id INTEGER G>);
G>Мне нужно выбрать из таблицы A те id, для которых существуют ВСЕ link, G>содержащиеся в B.id. Если я пишу:
G>SELECT DISCTINCT id FROM A WHERE link IN (SELECT id FROM B);
G>то B.id складываются по OR, а мне надо по AND. Это вообще возможно?
SELECT DISTINCT id FROM A WHERE id NOT IN (SELECT A.id FROM A WHERE A.link NOT IN (SELECT id FROM B) )
Здравствуйте, garant, Вы писали:
G>10.02.2012 9:37, _ABC_ пишет: >> Вроде бы примерно так, если не задумываться, а в лоб решить. На SQLite не проверял, может быть нужна доработка напильником.
G>Не, рано я обрадовался. Тут заточено на количество link в A, а когда G>количество их одинаково, но значения разные, то работает неверно.
G>По условию должно возвращаться только "1", а возвращается "1" и "3".
Ну я же говорил — допили напильником. Я же твоих данных и ограничений не знаю.
Попробуй что-то вроде этого:
select
a.id
from
(select distinct a.id, link from a inner join b on a.link = b.id) a
left join
(select COUNT(b.id) qty from (select distinct id from b) b) b on 1=1
group by
id
having
COUNT(a.link) = max(b.qty)
Здравствуйте, garant, Вы писали:
G>10.02.2012 11:15, _ABC_ пишет: >> on 1=1
G>А вот этот хак какой смысл несёт? Очень хочется разобраться в твоём G>запросе...
Это не совсем хак, это просто форма записи декартова произведения, левое соединение без условий (1=1 всегда истина). По сути эта форма записи аналогична cross join. По фактическому способу выполнения — нужно смотреть для конкретной СУБД. Можно перезаписать вот так (наверное, будет проще для понимания):
select
a_with_constr.id
from
(select distinct a.id, link from a inner join b on a.link = b.id) a_with_constr /* 1.а выбираем из таблицы А те уникальные записи, у которых поле link имеется в таблице B*/cross join
(select COUNT(b.id) qty_b from (select distinct id from b) b) b /* 1.б присоединяем к ней подсчитанное количество уникальных id в таблице B.
такое количество подзапросов и скобок вызавно ограничениями SQLite.*/group by
a_with_constr.id /* 2. группируем полученный результат (это a_with_constr.id, count(a_with_constr.link), max(qty_b)) по полю id таблицы А*/having
COUNT(a_with_constr.link) = max(qty_b) /* 3. фильтруем записи выбирая те записи, в которых количество link в a_with_constr совпадает с количеством уникальных id в
таблице B. max нужен для устранения теоретически возможной неоднозначности при группировке.*/