Пересечение SQL и объединение - PullRequest
1 голос
/ 30 ноября 2011

У меня есть таблица с именем words, состоящая из трех столбцов word(VARCHAR(16)), doc_id(INT), weight(DOUBLE).

Вот что мне нужно сделать, у меня два запроса:

SELECT doc_id, weight FROM words WHERE word = 'bla';

doc_id    weight
------    ------
1         0.14
2         0.61
3         0.32

и

SELECT doc_id, weight FROM words WHERE word = 'blabla';

doc_id    weight
------    ------
2         0.19
3         0.45
4         0.14

Мне нужно получить пересечение двух на doc_id и выбрать нижнее значение weight в качестве веса, т.е. я хочу, чтобы результаты были:

doc_id    weight
------    ------
2         0.19
3         0.32

Есть ли способ сделать это в одном запросе? Выполнение этого в программе делает это чертовски медленным!

Мне также нужно получить их UNION и выбрать более высокое значение weight, т.е. я хочу, чтобы результаты были:

doc_id    weight
------    ------
1         0.14
2         0.61
3         0.45
4         0.14

Имейте в виду, что столбцы word и doc_id не являются уникальными, поэтому одному слову можно присвоить множество документов.

Ответы [ 5 ]

1 голос
/ 30 ноября 2011
select w1.doc_id
     , least(w1.weight, w2.weight) weight
  from words w1
 inner 
  join words w2
    on w1.doc_id = w2.doc_id
 where w1.word = 'bla1'
   and w2.word = 'bla2'



select doc_id
     , max(weight) weight
  from words
 where word in ('blah1', 'blah2')
 group
    by doc_id
1 голос
/ 30 ноября 2011

Для пересекающейся части это звучит так, как будто вы хотите «наименьший вес для всех doc_id, где doc_id имеет одну строку для слова« bla »и одну строку для слова« blabla »».Это может быть найдено с помощью

(untested)
select w1.doc_id, least(min(w1.weight), min(w2.weight)) as minweight 
  from words w1, words w2
 where w1.doc_id = w2.doc_id
   and w1.word = 'bla'
   and w2.word = 'blabla'
 group by w1.doc_id;

Для объединяемой части вы хотите получить «максимальный вес для всех doc_id, где doc_id имеет одну строку для слова« bla »ИЛИ одну строку для слова« blabla »».Это можно найти по

(untested)
select doc_id, max(weight) as maxWeight
  from words
 where word in ('bla', 'blabla')
 group by doc_id;
0 голосов
/ 30 ноября 2011

Насколько я понимаю, следующий запрос должен работать для вашего запроса.

- запрос меньшего веса ВЫБЕРИТЕ Z.doc_id, MIN (вес) как LOWER_WEIGHT ОТ ( ВЫБЕРИТЕ doc_id, вес ОТ слов ГДЕ слово = 'бла' ПЕРЕСЕЧЕНИЕ ВЫБЕРИТЕ doc_id, вес ОТ слов, ГДЕ слово = 'блабла' ) Z GROUP BY Z.DOC_ID;

- запрос с более высоким весом

ВЫБЕРИТЕ Z.doc_id, МАКС. (Вес) как HIGHER_WEIGHT ОТ ( ВЫБЕРИТЕ doc_id, вес ОТ слов ГДЕ слово = 'бла' UNION ВЫБЕРИТЕ doc_id, вес ОТ слов, ГДЕ слово = 'блабла' ) Z GROUP BY Z.DOC_ID;

С уважением, Venk

0 голосов
/ 30 ноября 2011

Пересечения:

SELECT doc_id, MIN(weight) as MinWeight FROM words
WHERE doc_id IN
    (SELECT doc_id FROM words WHERE word = 'bla')
AND doc_id IN
    (SELECT doc_id FROM words WHERE word = 'blabla')
GROUP BY doc_id

Союз:

SELECT doc_id, MAX(weight) as MaxWeight FROM words
WHERE word IN ('bla', 'blabla')
GROUP BY doc_id
0 голосов
/ 30 ноября 2011

Я думаю, что вы хотите это:

SELECT doc_id, MIN(weight) MinWeight, MAX(weight) MaxWeight
FROM words
WHERE word IN ('bla','blabla')
GROUP BY doc_id
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...