2013-03-05 4 views
2

У меня есть таблица A как | name1 | name2 | value |Попытка избежать дублирования запроса

таблица B как | имя | значение |.

Здесь «name1» и атрибут «name2» в таблице А внешние ключи, ссылающиеся на «имя» в таблице В.

Теперь я хочу иметь функции запроса, как это:

SELECT value FROM A WHERE name1 IN 
    (SELECT name FROM B WHERE value = '1') AND 
    name2 IN (SELECT name FROM B WHERE value = '1') 

Здесь проблема в том, если я делаю это как код выше, будет два запроса из таблицы B. Но на самом деле мне нужно только один запрос, есть все, что в SQL, который пишет

SELECT value FROM A WHERE name1,name2 IN (SELECT name FROM B WHERE value = '1') 

а что, еслиЯ хочу что-то вроде этого:

SELECT value FROM A WHERE name1,name2 IN 
    (SELECT name FROM B ORDER BY value DESC FETCH FIRST 200 ROWS ONLY) 

?

+0

какая система баз данных вы используете? –

ответ

0

Может ли это сделать с присоединением?

select value from A inner join table b b1 on a.name1 = b1.name inner join table b b2 on a.name2 = b2.name where b1.name = '1' and b2.name = '1'

+0

Моя проблема здесь в том, что A и B оба очень большие, если я могу выбрать из B во-первых, будет намного меньше кортежей, присоединятся ли они все еще к производительности? – faz

+0

Нужно ли быть чистым запросом? Не могли бы вы обернуть его функцией или процедурой? В этом случае вы можете объявить временную таблицу и присоединиться к ней? 'declare @tbl table (имя nvarchar); вставить в @tbl выбрать топ 200 имя из B; выберите имя из A, где name1 in (выберите имя из @tbl) и name2 in (выберите имя из @tbl) ' – AndrewP

0

вы можете использовать присоединяется как этот SELECT A.value FROM A inner join B on A.name1 = B.name inner join B on A.name2 = B.name where B.name in ('1')?

+0

. Моя проблема в том, что A и B очень большие, если я могу выбрать из B сначала, будет гораздо меньше кортежей, присоединились бы к этому все еще влияют на производительность? – faz

+0

Я думаю, что соединения быстрее, чем многоуровневый запрос, который вы используете. –

0
select name, value from b 
left outer join (select name1 from a where value = '1') as a1 on 
a1.name1 = b.name 
left outer join (select name2 from a where value = '1') as a2 on 
a2.name2 = b.name 
where value is not null 
/*omit null from left outer join for names not in table b*/ 
0

В SQLServer2005 + вы можете использовать опцию NOT EXISTS + EXCEPT операторов

SELECT A.value 
FROM A 
WHERE NOT EXISTS (     
        SELECT A.name1 
        UNION 
        SELECT A.name2     
        EXCEPT 
        SELECT B.name 
        FROM B 
        WHERE B.value = '1'     
        ) 

Демо на SQLFiddle

0

Создать вид на таблицу В и использовать его?

Create view B_LIMITED AS SELECT name FROM B WHERE value = '1' 

select value from A inner join table b_limited b1 on a.name1 = b1.name inner join table b_limited b2 on a.name2 = b2.name where b1.name = '1' and b2.name = '1' 
Смежные вопросы