【问题标题】:How can I make an SQL query that handles missing records?如何进行处理丢失记录的 SQL 查询?
【发布时间】:2014-03-04 15:50:28
【问题描述】:

我有两张表,其中包含客户的年龄和身高。

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;

然而(这里是转折点)由于草率的记录保存,两个表中都缺少记录。 (例如,Ages 中的 customerId 为 5,Heights 中的 customerId 为 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    |
+-----------+------------+------------+

【问题讨论】:

    标签: mysql sql select records


    【解决方案1】:

    一条路(他们是其他人,一如既往)

    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

    【讨论】:

      【解决方案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

      【讨论】:

        【解决方案3】:

        您真正需要的是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;
        

        【讨论】:

          【解决方案4】:

          在 IF 条件为 NULL 的情况下使用 LEFT JOIN

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

          好的好的,那么快回答......上面只会给你0作为高度。问题也是年龄,但为此,最好获取所有客户 ID,加入年龄和身高

          最佳答案是公认的答案,我把这个留在这里是因为我学习了 MySQL COALESCE() 函数,XD

          【讨论】:

          • 这样可以处理空高度,但是空年龄呢?
          • 请注意,COALESCE 符合 SQL 标准。它也更整洁。
          猜你喜欢
          • 1970-01-01
          • 2019-01-28
          • 1970-01-01
          • 2017-04-12
          • 2018-05-11
          • 1970-01-01
          • 2014-09-21
          • 2012-02-08
          • 1970-01-01
          相关资源
          最近更新 更多