2014-03-04 23 views
2

我有两个表,其中包含客户的年龄和高度。如何制作处理缺失记录的SQL查询?

Table: Ages 
+-----------+------------+ 
|customerId |  age | 
+-----------+------------+ 
|  1  |  15  | 
|  2  |  24  | 
|  3  |  21  | 
|  4  |  62  | 
|  6  |  57  | 
|  7  |  32  | 
+-----------+------------+ 

Table: Heights 
+-----------+------------+ 
|customerId | height | 
+-----------+------------+ 
|  1  |  175 | 
|  2  |  182 | 
|  4  |  180 | 
|  5  |  171 | 
|  6  |  165 | 
|  7  |  182 | 
+-----------+------------+ 

我需要编写一个可读取所有年龄和高度的SELECT查询。因此,像这样......

SELECT Ages.age, Heights.height 
FROM Ages INNER JOIN Heights ON Ages.customerId=Heights.customerId; 

然而(和这里的扭曲)由于马虎记录保存,有两个表丢失记录。 (例如,年龄中的顾客ID 5和高度上的顾客ID 3)。

有没有办法编写查询,以便它仍然可以工作,但每当数据丢失时返回零?

+-----------+------------+------------+ 
|customerId |  age | height | 
+-----------+------------+------------+ 
|  1  |  15  |  175 | 
|  2  |  24  |  182 | 
|  3  |  21  |  0  | 
|  4  |  62  |  180 | 
|  5  |  0  |  171 | 
|  6  |  57  |  165 | 
|  7  |  32  |  182 | 
+-----------+------------+------------+ 

回答

4

一条路可走(他们是别人,总是)

select customerId, max(age), max(height) 
from 
(
    select customerId, age, 0 as height from Ages 
    UNION 
    select customerId, 0 as age, height from heights 
) s 
group by customerId; 

看到SqlFiddle

0

使用LEFT JOIN与IF条件为NULL

SELECT Ages.age, IF (Heights.height IS NULL, 0, Heights.height) AS height 
FROM Ages 
LEFT JOIN Heights ON Ages.customerId=Heights.customerId; 

OK OK,于是赶紧回答... ...以上才会给你0作为高度。问题是得到同样的年龄,但对于这一点,最好把所有客户的ID,左连接的年龄和高度

最好的答案是公认的答案,我离开这里,是因为我学到了MySQL的COALESCE()函数,XD

+1

这将处理空高度,但什么是零年龄? –

+3

请注意,COALESCE符合SQL标准。它也很整洁。 – Strawberry

2

MySQL没有全外连接,但你可以simulate oneLEFT JOIN,随后RIGHT JOIN,具有UNION相结合,将结合+消除重复:

SELECT Ages.age, COALESCE(Heights.height, 0) 
FROM Ages 
LEFT OUTER JOIN Heights ON Ages.customerId=Heights.customerId 
UNION 
SELECT COALESCE(Ages.age, 0), Heights.height 
FROM Ages 
RIGHT OUTER JOIN Heights ON Ages.customerId=Heights.customerId; 

SqlFiddle Here

1

你真正需要的是一个full outer join,但MySQL不支持这一点。相反,让所有的客户在子查询和使用left outer join

select c.customerid, coalesce(a.age, 0) as age, coalesce(h.height, 0) as height 
from (select customerid from ages union 
     select customerid from heights 
    ) c left outer join 
    ages a 
    on a.customerid = c.customerid left outer join 
    heights h 
    on h.customerid = c.customerid;