如何在同一表的不同列上使用不同的where子句连接SQL语句

时间:2018-07-02 07:40:39

标签: sql sql-server ssms

我在sql中有3个查询:

第一个查询:

select t1ID ,AVG(t2score) AS AVG1
from T1
WHERE t1m1 NOT IN (t2m1,t2m2,t2m3) and t1m2 IN (t2m1,t2m2,t2m3)
group by t1ID

结果

+------+------+
| t1ID | AVG1 |
+------+------+
|    1 |   55 |
|    2 |   45 |
|    3 |   73 |
|    4 |   69 |
+------+------+

第二个查询:

select t1ID ,AVG(t2score) AS AVG2
from T1
WHERE t1m2 NOT IN (t2m1,t2m2,t2m3) and t1m1 IN (t2m1,t2m2,t2m3)
group by t1ID

结果

+------+------+
| t1ID | AVG2 |
+------+------+
|    1 | 68   |
|    2 | 56   |
|    3 | NULL |
|    4 | NULL |
+------+------+

第三个查询

select t1ID ,AVG(t2score) AS AVGt3
from T1
WHERE t1m3 NOT IN (t2m1,t2m2,t2m3) and t1m1 IN (t2m1,t2m2,t2m3)
group by t1ID

结果

+------+------+
| t1ID | AVG3 |
+------+------+
|    1 | NULL |
|    2 | 70   |
|    3 | NULL |
|    4 | NULL |
+------+------+

如何将这三个语句结合起来,这样我才能将这些结果加在一起(每个AVG分数在不同的列中)

所需结果:

+------+------+------+------+
| t1ID | AVG1 | AVG2 | AVG3 |
+------+------+------+------+
|    1 |   55 | 68   | NULL |
|    2 |   45 | 56   | 70   |
|    3 |   73 | NULL | NULL |
|    4 |   69 | NULL | NULL |
+------+------+------+------+

5 个答案:

答案 0 :(得分:2)

注释中提到的条件聚合通过将CASE表达式放在AVG()函数调用中而起作用,因此仅对满足特定条件的值求平均值...

SELECT
   t1ID,
   AVG(CASE WHEN t1m1 NOT IN (t2m1,t2m2,t2m3) and t1m1 IN (t2m1,t2m2,t2m3) THEN t2Score END)   AVG1,
   AVG(CASE WHEN t1m2 NOT IN (t2m1,t2m2,t2m3) and t1m1 IN (t2m1,t2m2,t2m3) THEN t2Score END)   AVG2,
   AVG(CASE WHEN t1m3 NOT IN (t2m1,t2m2,t2m3) and t1m1 IN (t2m1,t2m2,t2m3) THEN t2Score END)   AVG3
FROM
    T1
GROUP BY
    t1ID

之所以可行,是因为在CASE表达式中不满足条件的所有内容都返回NULL,并且所有聚合函数(例如AVG())都会忽略NULL

答案 1 :(得分:0)

您可以使用CTE实现输出。像这样-

WITH cte1 AS
(
    select t1ID ,AVG(t2score) AS AVG1
    from T1
    WHERE t1m1 NOT IN (t2m1,t2m2,t2m3) and t1m2 IN (t2m1,t2m2,t2m3)
    group by t1ID

 ),
 cte2 AS
 (
    select t1ID ,AVG(t2score) AS AVG2
    from T1
    WHERE t1m2 NOT IN (t2m1,t2m2,t2m3) and t1m1 IN (t2m1,t2m2,t2m3)
    group by t1ID
 ),
 cte3 as
 (
     select t1ID ,AVG(t2score) AS AVGt3
     from T1
     WHERE t1m3 NOT IN (t2m1,t2m2,t2m3) and t1m1 IN (t2m1,t2m2,t2m3)
     group by t1ID
)
SELECT cte1.t1ID, cte1.AVG1, cte2.AVG2, cte3.AVG3
FROM cte1
JOIN cte2 ON cte1.t1ID = cte2.t1ID
JOIN cte3 ON cte2.t1ID = cte3.t1ID
  

如果t1ID列始终返回每个查询中的所有ID,则是适当的。

换句话说(自MatBailie起)

  

仅当子查询中的WHERE子句从不   过滤掉任何必需的t1ID值。

答案 2 :(得分:0)

您可以只对ID进行SELECT,然后对ID进行(LEFTJOIN子查询,如下所示:

select t1ID, AVG1, AVG2, AVG3 FROM 
(SELECT t1ID FROM T1 GROUP BY t1ID) AS IDs
JOIN (select t1ID ,AVG(t2score) AS AVG1
from T1
WHERE t1m1 NOT IN (t2m1,t2m2,t2m3) and t1m2 IN (t2m1,t2m2,t2m3)
group by t1ID) AS group1 USING (t1ID)
JOIN (select t1ID ,AVG(t2score) AS AVG2
from T1
WHERE t1m2 NOT IN (t2m1,t2m2,t2m3) and t1m1 IN (t2m1,t2m2,t2m3)
group by t1ID) AS group2 USING (t1ID)
JOIN (select t1ID ,AVG(t2score) AS AVG3
from T1
WHERE t1m3 NOT IN (t2m1,t2m2,t2m3) and t1m1 IN (t2m1,t2m2,t2m3)
group by t1ID) AS group3 USING (t1ID)

您必须为每个子查询赋予表别名。

答案 3 :(得分:0)

{SELECT t1ID, AVG(FirstT.t2score) AS AVG1, AVG(SecondT.t2score) AS AVG1, AVG(ThirdT.t2score) AS AVG1
FROM T1 t
JOIN T1 FirstT ON FirstT.t1ID = t.t1ID AND FirstT.t1m1 NOT IN (t2m1,t2m2,t2m3) AND FirstT.t1m2 IN (t2m1,t2m2,t2m3)
JOIN T1 SecondT ON SecondT.t1ID = t.t1ID AND SecondT.t1m2 NOT IN (t2m1,t2m2,t2m3) AND SecondT.t1m1 IN (t2m1,t2m2,t2m3)
JOIN T1 ThirdT ON ThirdT.t1ID = t.t1ID AND FirstT.t1m3 NOT IN (t2m1,t2m2,t2m3) and t1m1 IN (t2m1,t2m2,t2m3)enter code here
GROUP BY t1ID}

答案 4 :(得分:-1)

创建临时表并将数据插入其中可能对您有帮助