根据连接表SQL中的其他值选择值

时间:2015-08-27 11:42:16

标签: mysql select join key-value

我想请求一个SQL请求的帮助,它给我两个表的值。

作为一个例子,我有一个表订单和一个表处理。

我想报告订单和处理状态。

table orders

id | status   | div
-------------------
1  | wating_r | div1
2  | closed   | div2
3  | closed   | div3

-

table processing:

id | order_id | type           | date
----------------------------------------
1  |   2      | send_request   | 15.01.15
2  |   2      | send_invoice   | 30.01.15
3  |   1      | send_request   | 01.02.15
4  |   3      | send_request2  | 10.02.15
5  |   3      | send_invoice   | 15.02.15

我想得到什么:

order_id | status    | date_request  | date_request2 | date_invoice
--------------------------------------------------------------------------------
1        | waiting_r |  01.02.15     | NULL          | NULL
2        | closed    |  15.01.15     | NULL          | 30.01.15
3        | closed    | NULL          | 10.02.15      | 15.02.15

我的解决方案:

select orders.id as order_id, orders.status, IF(processing.type='send_invoice',date_format(processing.date, '%Y-%m-%d'), NULL) as date_invoice, IF(processing.type='send_request',date_format(processing.date, '%Y-%m-%d'), NULL) as date_request, IF(processing.type='send_request2',date_format(processing.date, '%Y-%m-%d'), NULL) as date_request2

from orders inner join processing on orders.id = processing.order_id

where case when orders.status='closed' then processing.type='send_invoice' when orders.status='waiting_r' then processing.type='send_request' when orders.status='waiting_2'then processing.type='send_request2' end

这样可以正常运行但是使用这个IF语句我发送发票时不会成为请求的日期 - 我只能得到发票的日期。

我尝试了以下方法,而不是案例请求,但在这种情况下,每个订单都有多行。当我试图" group by"我有混合数据。

where processing.type in ('send_invoice', 'send_request', 'completion_request_send')

1 个答案:

答案 0 :(得分:0)

你需要将第二个表连接到前三个,就像这样。

SELECT o.id AS order_id, o.status, 
       p1.date AS date_request,
       p2.date AS date_request2,
       p3.date AS date_invoice
  FROM orders o
  LEFT JOIN processing p1 ON o.id = p1.order_id  AND p1.type='send_request'         
  LEFT JOIN processing p2 ON o.id = p2.order_id  AND p2.type='send_request2'
  LEFT JOIN processing p3 ON o.id = p3.order_id  AND p3.type='send_invoice'
 ORDER BY 1,2

此左连接具有id匹配条件,并且特定类型选择会拉出每列所需的行。 Left,而不是inner,join,允许将缺失值显示为null。

这是工作。 http://sqlfiddle.com/#!9/b8c74/5/0

这是加入键/值表的典型模式,其中(id / key)对是唯一的。

修改不幸的是,在特定值的重复键存在的情况下,它会生成重复的结果集行。为了解决这个问题,在这种情况下,必须对密钥/值表(processing)进行重复数据删除。

此子查询将执行该操作,并采用最新的日期值。

               SELECT type, order_id, MAX(date) AS date
                 FROM processing
                GROUP BY type, order_id

然后,您必须在主查询中使用该子查询。如果MySQL有公共表表达式,那么这就好了。但它并没有让事情变得冗长。

SELECT o.id AS order_id, o.status, 
       p1.date AS date_request,
       p2.date AS date_request2,
       p3.date AS date_invoice
  FROM orders o
  LEFT JOIN (
               SELECT type, order_id, MAX(date) AS date
                 FROM processing
                GROUP BY type, order_id
            ) p1 ON o.id = p1.order_id  AND p1.type='send_request'         
  LEFT JOIN (
               SELECT type, order_id, MAX(date) AS date
                 FROM processing
                GROUP BY type, order_id
            ) p2 ON o.id = p2.order_id  AND p2.type='send_request2'
  LEFT JOIN (
               SELECT type, order_id, MAX(date) AS date
                 FROM processing
                GROUP BY type, order_id
            ) p3 ON o.id = p3.order_id  AND p3.type='send_invoice'
 ORDER BY 1,2