我有这两个表:
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值的情况,反之亦然。
感谢。
答案 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中的保留字,可能会导致令人困惑的结果。