MySQL:从左连接中选择一行,结果只有多行

时间:2014-06-22 01:42:16

标签: mysql sql join left-join

好吧,在SO的帮助和我自己公认的有限脑功能的帮助下,我的查询大部分都在起作用。我从LEFT JOIN得到了我想要的结果,它出现在外部查询中。但是,对于具有相同ID的每一行,它会显示多次,这是预期的,但这不是我需要的......

我想知道是否有可能只显示一次加入的结果。我在网上找到了很多答案,只是从已加入的表中拉出第一行。但是,我正在寻找的只是在结果中显示连接结果(不一定是第一次)。

这是我的查询的简化版本:

select
    `order`.order_id,
    `order`.total,
    `order`.comment,
    `order`.shipping_cost,
    `ct`.amount as credit
from `order`
left join (
    select
        customer_id,
        sum(amount) as amount
    from `customer_transaction`
    where
        amount > 0
        and integrated = 0
    group by
        customer_id
) as ct
    on `ct`.`customer_id` = `order`.`customer_id`
where
    `order`.integrated = 0;

这应该做的是在包含客户信用的同时获取尚未整合的订单信息。不幸的是,信用被存储为ct表中的行,与特定订单无关,这有点合理,但正在集成它的软件需要订购此号码。

上述查询“有效”,直到一个客户有多个订单。在这种情况下,如果我使用上述查询,它将有效地认为所有订单都已应用信用。例如,上面的查询返回如下结果:

+-------------+----------+-----------+---------+---------------+--------+
| customer_id | order_id | total     | comment | shipping_cost | credit |
+-------------+----------+-----------+---------+---------------+--------+
|       52227 |   184589 |   28.6910 |         |       12.7410 | 8.0000 |
|       52227 |   184590 |   28.6910 |         |       12.7410 | 8.0000 |
+-------------+----------+-----------+---------+---------------+--------+

该客户的“账户”信用额度为8美元,而不是16美元。即,客户的未使用信用交易总和加起来为8.我试图获得该信用仅出现一次。换句话说,这就是我想要的结果:

+-------------+----------+-----------+---------+---------------+--------+
| customer_id | order_id | total     | comment | shipping_cost | credit |
+-------------+----------+-----------+---------+---------------+--------+
|       52227 |   184589 |   28.6910 |         |       12.7410 | 8.0000 |
|       52227 |   184590 |   28.6910 |         |       12.7410 | NULL   |
+-------------+----------+-----------+---------+---------------+--------+

(注意右下角的NULL。它也可能是0,甚至可能是8 / $ NUM_ROWS。我必须检查软件是否可以使用。可能不会。)

这种疯狂的原因是因为一个软件将信用存储为与客户相关联的一行或多行,而另一个软件将其视为一个订单的一部分,并且它应该“一次性”集成。它运行一个查询以获取所有订单信息,包括信用,第二个用于订单项(无信用)。所以......我需要将订单信用,然后将其设置为integrated = 1,以便下次不会使用它(我已经有了这部分工作)。

任何想法如何只显示一次信用,或者这是不是可以用“简单”查询(而不是代码)?

由于

1 个答案:

答案 0 :(得分:2)

您可以使用左连接执行此操作。我们的想法是在left join

的第一个表格中有一个序列号
select o.order_id, o.total, o.comment, o.shipping_cost, ct.amount as credit
from (select o.*,
             @rn :=  if(@cid = customer_id, @rn + 1, 1) as rn,
             @cid := customer_id
      from `order` o cross join
           (select @rn := 0, @cid := 0) vars
     ) o left join
     (select customer_id, sum(amount) as amount
      from `customer_transaction`
      where amount > 0 and integrated = 0
      group by customer_id
     ) ct
     on `ct`.`customer_id` = o.`customer_id` and o.rn = 1
where o.integrated = 0;

如果需要,left join会保留第一个表中的所有行以及第二个表中的匹配行。因为条件o.rn = 1仅匹配第一行,所以只有第一行才能获得值。