2016-05-12 162 views
1

我有2个表: -仅当返回结果不包含特定值时才返回结果?

T

ID | val 
    1 | abcd 
    2 | 1234 
    3 | asd 
    4 | lkj 

而另一台M

ID | T_ID | Type 
1 | 1 | I 
2 | 1 | S 
3 | 2 | I 
4 | 2 | I 
5 | 3 | I 
6 | 4 | S 

我想写一个连接上m.T_ID = T.IDTM查询,但它不应该返回T.ID if anyM映射到它具有键入S即上述一组数据的应返回值T.ID = 2,3和不1,4因为M映射到它具有键入S

一种方式做到这一点是写一个内部查询。例如: -

SELECT T.id 
FROM table1 T 
     JOIN table2 M 
     ON M.t_id = T.id 
WHERE T.id NOT IN (SELECT m2.t_id 
        FROM table2 m2 
        WHERE m2.type = 'S') 

但内部查询可能非常昂贵,因为我的表M有数百万行。有一个更好的方法吗 ?

+1

'where M.Type!='S''? – Stewart

+0

如何改善您的连接条件,例如M.T_ID = T.ID和Type ='s''? – ceadreak

+0

如果您已经有工作查询并希望获得帮助以提高性能,请向我们展示解释计划。性能问题应该包括'EXPLAIN ANALYZE'和一些关于表格大小,索引,当前时间表现,期望时间等的信息。'Slow'是一个相对术语,我们需要一个真实值来比较。 [** MySQL **](http://dba.stackexchange.com/questions/15371/how-do-i-get-the-execution-plan-for-a-view) –

回答

2

使用条件COUNT

SELECT T.id 
FROM table1 T 
JOIN table2 M 
    ON M.t_id = T.id 
GROUP BY T.id 
HAVING COUNT(CASE WHEN M.Type = 'S' THEN 1 END) = 0 

意味着你不要有该组中'S'

+0

是的,我的坏... – ceadreak

-2

你应该看看LEFT JOIN而不是INNER JOIN。

1

不是最漂亮的,但它似乎工作

select T.ID 
from Table1 T 
left join Table2 M on M.T_ID = T.ID 
group by T.Id 
having sum(case when M.Type = 'S' then 1 else 0 end) = 0 

你应该检查,如果它实际上是在执行计划更便宜。

+2

只是个人喜好,因为你的SUM和我的COUNT应该产生相同的结果。但是对于使用'count'的未来读者来说更明显,因为你在计算对象。 'SUM'在'SUM'(月份='二月'那么销售结束)''的情况下更好 –