代码之家  ›  专栏  ›  技术社区  ›  ruohola

SQL为join子句中的所有表测试相同的列值

  •  0
  • ruohola  · 技术社区  · 6 年前

    我有以下示例查询;

    SELECT S.Column1, S.Column2
    FROM TableS as S
    LEFT JOIN TableP as P ON S.PID = P.ID
    LEFT JOIN TableI as I ON P.IID = I.ID
    WHERE I.Identifier = 'StringIdentifier'
          AND I.Relevant = 1
          AND P.Relevant = 1
          AND S.Relevant = 1 
    

    有没有办法把最后三行简化成一行,检查一下 Relevant 一次完成所有表的列?

    显然,用一行替换最后三行 AND Relevant = 1 不会工作,因为它给出了错误:

    不明确的列名“relevant”。

    编辑:的数据类型 相关的 列是位。

    5 回复  |  直到 6 年前
        1
  •  3
  •   Dumitrescu Bogdan    6 年前

    如果您在该列上有一个索引,那么这就是方法。

    如果你不想,只想让它看起来漂亮或漂亮,你可以做如下的事情:

    AND I.Relevant * P.Relevant * S.Relevant = 1 -- assuming they are numeric
    AND I.Relevant & P.Relevant & S.Relevant = 1 -- assuming bit
    

    如果不是数字或位(文本),那么您需要转换为数字,它将再次看起来不那么好。

    另外,我建议丢失左边的部分(从join),因为在许多情况下,它会更快,在这个代码上,它是没有意义的。

        2
  •  1
  •   sticky bit    6 年前

    如果你的问题是你必须重复 1 而不是您可以使用的表达式的长度 ALL .

    SELECT S.Column1, S.Column2
    FROM TableS as S
    LEFT JOIN TableP as P ON S.PID = P.ID
    LEFT JOIN TableI as I ON P.IID = I.ID
    WHERE I.Identifier = 'StringIdentifier'
          AND 1 = ALL(SELECT I.Relevant
                      UNION
                      SELECT P.Relevant
                      UNION
                      SELECT S.Relevant)
    
        3
  •  1
  •   Gordon Linoff    6 年前

    你的 WHERE 情况正在改变 JOIN s转换为内部联接,因此应正确表示联接:

    SELECT S.Column1, S.Column2
    FROM TableS S JOIN
         TableP P
         ON S.PID = P.ID JOIN
         TableI I
         ON P.IID = I.ID AND I.Identifier = 'StringIdentifier'
    WHERE I.Relevant = 1 AND
          P.Relevant = 1 AND
          S.Relevant = 1;
    

    假设 Relevant 只接受0/1的值,您 能够 使用横向联接:

    SELECT S.Column1, S.Column2
    FROM TableS S JOIN
         TableP P
         ON S.PID = P.ID JOIN
         TableI I
         ON P.IID = I.ID AND
            I.Identifier = 'StringIdentifier' CROSS APPLY
         (SELECT MIN(v.Relevant) as min_relevant
          FROM (VALUES (I.Relevant), (P.Relevant), (S.Relevant)
               ) v(Relevant)
         ) v
    WHERE v.min_relevant = 1;
    

    这对3个比较没有真正的帮助。但如果你有一打,它会有用的。

        4
  •  0
  •   Miguel Angel Alonso    6 年前

    该查询是错误的,因为有2个左联接,但在这些表上有条件的位置 我提议:

    SELECT S.Column1, S.Column2
    FROM TableS as S
        LEFT JOIN TableP as P ON S.PID = P.ID AND P.Relevant = 1
        LEFT JOIN TableI as I ON P.IID = I.ID AND I.Identifier = 'StringIdentifier' AND I.Relevant = 1
    WHERE S.Relevant = 1 
    

    正确的查询比简化的查询更好

        5
  •  -2
  •   Radacina    6 年前

    假设你能做到这一点

    ... and I.Relevant and P.Relevant and S.Relevant