好吧,在 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 这样下次就不会使用它(我已经让这部分工作了)。
有什么想法我只能显示一次信用,或者这不能通过“简单”查询(而不是代码)实现吗?
谢谢
最佳答案
您可以使用左连接来做到这一点。这个想法是在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
只匹配第一行,所以只有第一行会得到值。
关于MySQL:从左连接中仅选择一行,结果为多行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24347429/