在同一个表中由列设置的条件下,来自同一个表的两个值的SQL查询

时间:2018-04-17 14:10:56

标签: mysql sql database

我有这两个表:

TableA:
aid ! name
--- ! -----
1   ! Paper
2   ! Rock
3   ! Sciz

Table B (aid is TableA FKEY)
id ! aid ! area  ! mode
-- ! --- ! ----- ! ----
1  ! 1   ! 200   ! 1
2  ! 1   ! 240   ! 2
3  ! 2   ! 300   ! 1
4  ! 2   ! 290   ! 2
5  ! 3   ! 100   ! 1
6  ! 3   ! 110   ! 2

我想编写一个返回以下结果的查询:

aid ! area(mode=1) ! area(mode=2) 
--- ! ------------ ! ------------
1   ! 200          ! 240
2   ! 300          ! 290
3   ! 100          ! 110

如何在mySQL中完成此操作?我还需要排除表B仅包含mode1值而不包含mode2值的情况,反之亦然。

感谢。

5 个答案:

答案 0 :(得分:2)

http://sqlfiddle.com/#!9/2db6c5/1

试试这个;

SELECT b1 .aid, b1.area, b2.area  
FROM tablea a1
LEFT JOIN tableb b1 ON a1.aid = b1 .aid
LEFT JOIN tableb b2 ON a1.aid = b2 .aid
where 
b1.mode = 1
and b2.mode = 2

答案 1 :(得分:2)

如果您需要两种模式,那么我建议您使用inner join

SELECT a.aid, b1.area, b2.area  
FROM tablea a1 JOIN
     tableb b1
     ON a1.aid = b1.aid AND b1.mode = 1 JOIN
     tableb b2
     ON a1.aid = b2.aid AND b2.mode = 2;

内连接将确保b中都存在这两个值。

因为两种模式都需要存在,所以实际上并不需要tablea

SELECT b1.aid, b1.area, b2.area  
FROM tableb b1
     ON a1.aid = b1.aid JOIN
     tableb b2
     ON a1.aid = b2.aid AND b1.mode = 1  AND b2.mode = 2;

实际上,如果您只需要两者都存在的aid,您也可以这样做:

select b.aid, max(case when mode = 1 then area end) as area1,
       max(case when mode = 2 then area end) as area2
from tableb b
group by b.aid
having area1 is not null and area2 is not null;

这根本不需要加入表格。

答案 2 :(得分:2)

这是一个名为pivot的过程。
并且可以使用GROUP BY结合MAX(CASE END)子句来完成。
HAVING子句确保B.aid具有包含1和2模式的记录。

SELECT 
   B.aid 
 , MAX(CASE WHEN B.mode = 1 WHEN B.area ELSE 0 END) AS 'area(mode=1)'
 , MAX(CASE WHEN B.mode = 2 WHEN B.area ELSE 0 END) AS 'area(mode=2)'
FROM 
 B
GROUP BY
 B.aid 
HAVING
   SUM(B.mode = 1) = 1
 AND
   SUM(B.mode = 2) = 1
ORDER BY 
 B.aid ASC

答案 3 :(得分:1)

这应该有效:

select * from(
    select aid, max(case when mode = 1 then area end) as mode1, 
                max(case when mode = 2 then area end) as mode2
    from tableB  
    group by aid order by aid
)where mode1 is not null and mode2 is not null

答案 4 :(得分:1)

我不知道为什么TableA表A的目的是什么。但我认为它将是起点。

SELECT DISTINCT a.aid
    ,b1.area as area_mode1
    ,b2.area as area_mode2

FROM TableA a
    JOIN TableB b1 ON (a.aid = b1.aid AND b1.mode = '1')
    JOIN TableB b2 ON (a.aid = b2.aid AND b2.mode = '2')
;

也许SUBSELECT也会这样做,但我认为表B的双JOIN会为较大的表花费更少的内存。

提示:您应该避免使用“名称”和“模式”等字段名称。它们是SQL中的保留字,可能会导致令人困惑的结果。