[SQLite] помогите с выборкой!
От: garant  
Дата: 10.02.12 05:04
Оценка:
Помогите, пожалуйста. Уже весь мозг сломал.

Есть две таблицы, A и B, примерно такие:

CREATE TABLE A (
id INTEGER,
link INTEGER
);

CREATE TABLE B (
id INTEGER
);

Мне нужно выбрать из таблицы A те id, для которых существуют ВСЕ link,
содержащиеся в B.id. Если я пишу:

SELECT DISCTINCT id FROM A WHERE link IN (SELECT id FROM B);

то B.id складываются по OR, а мне надо по AND. Это вообще возможно?
Posted via RSDN NNTP Server 2.1 beta
Re: [SQLite] помогите с выборкой!
От: Sergey Lizin Россия  
Дата: 10.02.12 05:22
Оценка:
Здравствуйте, 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)
Re: [SQLite] помогите с выборкой!
От: _ABC_  
Дата: 10.02.12 05:37
Оценка:
Здравствуйте, 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
Re[2]: [SQLite] помогите с выборкой!
От: garant  
Дата: 10.02.12 06:30
Оценка:
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)

Неа, не работает. Возвращает все id из A...
Posted via RSDN NNTP Server 2.1 beta
Re[2]: [SQLite] помогите с выборкой!
От: garant  
Дата: 10.02.12 06:31
Оценка:
10.02.2012 9:37, _ABC_ пишет:
> Вроде бы примерно так, если не задумываться, а в лоб решить. На SQLite не проверял, может быть нужна доработка напильником.

Работает! Спасибо. Но, похоже, действительно в лоб. Буду допиливать.
Posted via RSDN NNTP Server 2.1 beta
Re[2]: [SQLite] помогите с выборкой!
От: garant  
Дата: 10.02.12 06:35
Оценка:
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".
Posted via RSDN NNTP Server 2.1 beta
Re: [SQLite] помогите с выборкой!
От: urquan  
Дата: 10.02.12 07:00
Оценка:
Здравствуйте, 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) )
Re[3]: [SQLite] помогите с выборкой!
От: _ABC_  
Дата: 10.02.12 07:15
Оценка:
Здравствуйте, 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)
Re[2]: [SQLite] помогите с выборкой!
От: garant  
Дата: 10.02.12 07:16
Оценка:
10.02.2012 11:00, urquan пишет:
> SELECT DISTINCT id FROM A WHERE id NOT IN (SELECT A.id FROM A WHERE A.link NOT IN (SELECT id FROM B) )

Неа... Не работает. Я выше привёл данные, на которых проверяю... Уже всё
перепробовал, что в голову пришло.
Posted via RSDN NNTP Server 2.1 beta
Re[3]: [SQLite] помогите с выборкой!
От: _ABC_  
Дата: 10.02.12 07:32
Оценка:
Здравствуйте, garant, Вы писали:

G>Неа... Не работает. Я выше привёл данные, на которых проверяю... Уже всё

G>перепробовал, что в голову пришло.

Постом выше посмотри.
Re[4]: [SQLite] помогите с выборкой!
От: garant  
Дата: 10.02.12 07:45
Оценка:
10.02.2012 11:15, _ABC_ пишет:
> Ну я же говорил — допили напильником. Я же твоих данных и ограничений не знаю.
> Попробуй что-то вроде этого:

Вау. Кажется, это то, что надо! Сиквель-магия!
Спасибо огромное.
Posted via RSDN NNTP Server 2.1 beta
Re[4]: [SQLite] помогите с выборкой!
От: garant  
Дата: 10.02.12 07:47
Оценка:
10.02.2012 11:15, _ABC_ пишет:
> on 1=1

А вот этот хак какой смысл несёт? Очень хочется разобраться в твоём
запросе...
Posted via RSDN NNTP Server 2.1 beta
Re[5]: [SQLite] помогите с выборкой!
От: _ABC_  
Дата: 10.02.12 08:31
Оценка:
Здравствуйте, 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 нужен для устранения теоретически возможной неоднозначности при группировке.*/
Re[6]: [SQLite] помогите с выборкой!
От: garant  
Дата: 10.02.12 08:59
Оценка:
10.02.2012 12:31, _ABC_ пишет:
> Можно перезаписать вот так (наверное, будет проще для понимания)

Супер. Спасибо большое за разъяснения!
Posted via RSDN NNTP Server 2.1 beta
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.