简体   繁体   English

如何在JOIN子句中为所有表测试相同的列值?

[英]How to test the same column value for all tables in a JOIN clause?

I have the following example query; 我有以下示例查询;

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 

Is there any way to simplify the last 3 lines to only one, to check the Relevant column from all the tables in one go? 有什么方法可以将最后三行简化为仅一行,一次检查所有表中的“ Relevant列?

Obviously replacing the last 3 lines with just a line AND Relevant = 1 will not work because it gives the error: 显然仅用AND Relevant = 1替换最后3行将不起作用,因为它会产生错误:

Ambiguous column name 'Relevant'. 列名称不明确“相关”。

Edit: The datatype of Relevant column is bit. 编辑: Relevant列的数据类型是位。

If you have an index on that column, then this is the way to go. 如果您在该列上有索引,那么这就是方法。

If you do not, and just want it to look fancy or nice you can do something like: 如果您不这样做,只是希望它看起来不错或不错,则可以执行以下操作:

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

If not numeric or bit (text) then you need to cast to numeric and it will again not look that nice. 如果不是数字或位(文本),那么您需要转换为数字,并且看起来也不会那么好。

Also, I would suggest losing the left (from join) as in many cases it will be faster and on this code it does not make sense. 另外,我建议丢失左(从连接中),因为在许多情况下这样做会更快,并且在此代码上这没有意义。

Your WHERE condition are turning the JOIN s into inner joins, so you should express the joins correctly: 您的WHERE条件正在将JOIN变成内部联接,因此您应该正确表达联接:

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;

Assuming Relevant takes on only the values of 0/1, you could use a lateral join: 假设“ 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;

This isn't really helpful for 3 comparisons. 这对于3个比较并没有真正的帮助。 But if you had a dozen, it would be useful. 但是,如果您有一打,它将很有用。

If your problem is that you have to repeat the 1 and not the length of the expression you could use ALL . 如果您的问题是必须重复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)

That query is wrong because there are 2 left join but in the where there are conditions over those tables I propose: 该查询是错误的,因为有两个左连接,但是在我建议的那些表上有条件的地方:

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 

It is better a correct query than a simplified query 正确的查询比简化的查询更好

假设相关是个笨蛋,您可以做

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM