[英]MySQL Join two tables and combine multiple rows into one
I have 2 tables: 我有2张桌子:
sms_recipients sms_recipients
campaign_id | message | user_id | contact_number | status
.........................................................
1 something 12334 078237812719 1
1 something 12123 071231231232 1
2 other 12124 078123123126 0
2 other 12334 078234234212 0
2 other 42124 078124124415 1
sms_campaign sms_campaign
campaign_id | shop_id| campaign_type
.....................................
1 1123 marketing
2 2123 awareness
3 3231 something else
4 4432 bla bla
5 5244 last
campaign_id
's are unique for the sms_campaign
table, there are multiple user_id
's related to the same campaign_id
the message
is the same for all unique champagne_id
对于
sms_campaign
表, campaign_id
是唯一的,与同一个campaign_id
相关的有多个user_id
,对于所有唯一的champagne_id
, message
都是相同的
I want to combine them so that every contact_number
of the same campaign_id
with a status = 0
appears in a single row and column like this: 我想将它们组合在一起,以使
status = 0
的同一campaign_id
每个contact_number
都显示在单个行和列中,如下所示:
campaign_id | shop_id| campaign_type | users_mobile_numbers | message
..........................................................................
1 1123 marketing something
2 2123 awareness 078123123126,078234234212 other
3 3231 something else
4 4432 078234234212
5 5244 078124124415
Here is my query so far: 到目前为止,这是我的查询:
SELECT c.campaign_id,
shop_id,
campaign_type,
contact_number AS users_mobile_numbers,
message FROM sms_campaign c
LEFT JOIN sms_recipients r
ON u.campaign_id = c.campaign_id
WHERE status = 0
In the LEFT JOIN
, you will need to either move the filter status = 0
into a join condition, OR if you leave the filter in the WHERE clause, then status = 0 OR status IS NULL
to avoid filtering out campaigns with no messages at all - I've done the first option. 在
LEFT JOIN
,您将需要将过滤器status = 0
移到LEFT JOIN
条件中,或者如果将过滤器留在WHERE子句中,则status = 0 OR status IS NULL
可以避免过滤掉没有消息的广告活动-我已经做了第一个选择。
As per the comment, you will need to GROUP
the data by the campaign columns, and apply aggregate functions to all non-grouped columns, in order to guarantee just one row per group - GROUP_CONCAT
will concatenate all text values in each GROUP. 按照该意见,则需要
GROUP
由竞选列中的数据,并且将集合函数应用于所有非分组的列,以保证每组只有一行- GROUP_CONCAT
将串联在各组中的所有文本值。 I've arbitrarily used MIN
to resolve a value for shop
and message
, but you may need to adjust otherwise. 我已任意使用
MIN
来解析shop
和message
的值,但您可能需要进行其他调整。 (You can also do a DISTINCT in a GROUP CONCAT, if required). (如果需要,您也可以在GROUP CONCAT中执行DISTINCT)。
SELECT
c.campaign_id,
MIN(shop_id) AS shop_id,
campaign_type,
GROUP_CONCAT(contact_number) AS users_mobile_numbers,
MIN(message) AS message
FROM sms_campaign c
LEFT JOIN sms_recipients r
ON u.campaign_id = c.campaign_id AND status = 0
GROUP BY c.campaign_id, campaign_type;
Move the condition on r.status
to the ON
clause of the outer join. 将
r.status
上的条件r.status
外部r.status
的ON
子句中。 (With the condition in the WHERE clause requiring r.status
to be non-NULL, that will negate the outerness of the LEFT JOIN, making it equivalent to an INNER JOIN.) (由于WHERE子句中的条件要求
r.status
为非NULL,这将否定LEFT JOIN的外部性,使其等效于INNER JOIN。)
Add a GROUP BY
clause to collapse the rows. 添加
GROUP BY
子句以折叠行。
Use a GROUP_CONCAT
function to combine the values of contact_number
. 使用
GROUP_CONCAT
函数合并contact_number
的值。 Column references which appear in the SELECT list but are not included in the GROUP BY clause should also be enclosed in aggregate expressions.) 出现在SELECT列表中但未包含在GROUP BY子句中的列引用也应包含在聚合表达式中。)
SELECT c.campaign_id
, ...
, GROUP_CONCAT(DISTINCT r.contact_number ORDER BY r.contact_number) AS `c_numbers`
, MIN(r.message) AS `message`
FROM campaign c
LEFT
JOIN sms_recipients r
ON r.campaign_id = c.campaign_id
AND r.status = 0
GROUP BY c.campaign_id
The value returned by GROUP_CONCAT
aggregate function is limited by max_group_concat_len
variable. GROUP_CONCAT
聚合函数返回的值受max_group_concat_len
变量限制。 Longer values will be silently truncated to the maximum length. 较长的值将被无提示地截断为最大长度。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.