同一张表在2个条件下内部联接一个表,并且两个条件有时都为假

时间:2019-03-03 04:01:46

标签: mysql sql

enter image description here

详细信息:

  1. VC是表

  2. 我希望C在2个条件下(两个C分别命名为VC0)加入C1。由于我必须在同一查询中分别按VC的子表的列过滤C,因此我认为需要联接。

  3. V有很多(至少一个)C,有时Cx都不存在。

由于3.,对C0C1使用内部联接有时会导致空结果,但我不想得到V的空白区域。

模式:

V (id)
C (id, v_id, name, type)

查询(1):

SELECT V.* 
FROM V
INNER JOIN C AS C0 ON V.id = C0.v_id WHERE C0.type = 0
INNER JOIN C AS C1 ON V.id = C1.v_id WHERE C1.type = 1
WHERE C0.name = 'word' or C1.name = 'word'
WHERE C0.name like '%wo%'

查询(2):

SELECT V.* 
FROM V
INNER JOIN C AS C0 ON V.id = C0.v_id WHERE C0.type = 0
INNER JOIN C AS C1 ON V.id = C1.v_id WHERE C1.type = 1
WHERE C0.name = 'word' or C1.name = 'word'
WHERE C1.name like '%wo%'

WHERE C0.name = 'word' or C1.name = 'word':此子句每次都存在。

WHERE Cx.name like '%wo%':此子句取决于时间。

4 个答案:

答案 0 :(得分:1)

好吧……您似乎正在寻找具有相关子查询的window.document.documentElement条件:

EXISTS

这将返回表SELECT * FROM v WHERE EXISTS (SELECT 1 FROM c WHERE c.c0 = v.c0 OR c.c1 = v.c1) 中的所有记录,其中在表v中至少存在一条满足条件c或条件c.c0 = v.c0的记录。

在这种情况下,相关子查询相对于c.c1 = v.c1方法的优势在于,当表JOIN中存在多个匹配项时,它避免了记录的倍增。

如果要排除满足任一条件的记录而不是包括它们,则只需将c更改为WHERE EXISTS

答案 1 :(得分:1)

不好的问题/问题的详细信息,即使是缩写的字段和实际表也可以在将来更好地帮助您,但知道您想要的更好的上下文。但是,看起来您想要的是基于“ C”别名条件的EITHER的“ IN”条件。不用看它们,您可以像这样看(或在第二秒简化两个条件)。

select
      v.*
   from
      VTable v
         LEFT JOIN CTable C0
            on v.SomeField = C0.SomeField
         LEFT JOIN CTable C1
            on v.SomeOtherField = C1.SomeOtherField
   where
          c0.SomeField IS NOT NULL
      OR c1.SomeField IS NOT NULL

OR ...通过单个左联接简化,结合了两个条件

select
      v.*
   from
      VTable v
         LEFT JOIN CTable C0
            on ( ( v.SomeField = C0.SomeField )
              OR ( v.SomeOtherField = C0.SomeOtherField ) )
   where
      c0.SomeField IS NOT NULL

在上面的查询中,我使用了额外的括号,以防原始的C0和C1条件本身很复杂。

因此,您用简单的英语在“ V”表中描述为白色区域的内容是给了我V表中与C0或C1条件不匹配的所有内容。因此,通过检查任何列(尽管应为键列)显式地为NOT NULL(因此在C表条件中确实存在),左联接然后确保它们确实存在。

答案 2 :(得分:1)

如果您只想要v中的列,那么exists就会浮现在脑海。

我将其表达为:

select v.*
from v
where exists (select 1
              from c
              where v.id = c.v_id and
                    c.type = 0
             ) or
      exists (select 1
              from c
              where v.id = c.v_id and
                    c.type = 1
             ) ;

这可以利用c(v_id, type)上的索引。

也可以这样表达:

select v.*
from v
where exists (select 1
              from c
              where v.id = c.v_id and
                    c.type in (0, 1)
             );

甚至:

select v.*
from v
where v.id in (select c.v_id
               from c
               where c.type in (0, 1)
              );

关键思想是通过在where子句中进行比较,可以保证行不能重复。

答案 3 :(得分:0)

您不需要两次连接表c,您可以像下面这样编写查询。

select V.*
from V as V
inner join C as C on C.v_id=V.id 
where C.name='word' and C.type in(0,1)