我有一张包含以下数据的表格:
reservno || icode || location
00004 || 00021 || Bohol - Cebu
00004 || 00022 || Cebu - Manila
00004 || 00014 || Manila - Bohol
我使用此查询来检索位置的连接值。
SELECT GROUP_CONCAT(location) from location_list where reservno='00004';
查询结果如下所示:
GROUP_CONCAT(location)
Bohol - Cebu,Cebu - Manila,Manila - Bohol
但我想要做的是查询看起来像这样:Bohol - Cebu - Manila - Bohol
。我想合并这样的结果。我怎样才能做到这一点?我对MySQL字符串函数并不熟悉,所以我需要一些关于如何使其工作的想法。任何帮助将不胜感激。非常感谢!
答案 0 :(得分:6)
您需要在SEPARATOR
函数中使用GROUP_CONCAT
:
SELECT GROUP_CONCAT(IF((@var_ctr := @var_ctr + 1) = @cnt,
location,
SUBSTRING_INDEX(location,' - ', 1)
)
ORDER BY loc_id ASC
SEPARATOR ' - ') AS locations
FROM location_list,
(SELECT @cnt := COUNT(1), @var_ctr := 0
FROM location_list
WHERE reservno='00004'
) dummy
WHERE reservno='00004';
将多个值存储在同一列中并不是一个好习惯,更好的方法可能是:
reservno || icode || location_from || location_to
00004 || 00021 || Bohol || Cebu
00004 || 00022 || Cebu || Manila
00004 || 00014 || Manila || Bohol
答案 1 :(得分:3)
这是一种方式。它将您的单个location
列中的两个位置分开,区分它,然后将它重新组合在一起SQL Fiddle:
SELECT GROUP_CONCAT(DISTINCT loc SEPARATOR ' - ')
FROM
(
SELECT SUBSTRING_INDEX(location, ' - ', 1) AS loc
FROM location_list
WHERE reservno='00004'
UNION ALL
SELECT SUBSTRING_INDEX(location, ' - ', -1) AS loc
FROM location_list
WHERE reservno='00004'
) separatedLocs
你可能正在寻找更聪明的东西?我觉得“位置”更像是一种“从头到尾”的东西?我还质疑在location
列中存储多个值的决定。将location1
和location2
存储为单独的列会更好。
答案 2 :(得分:0)
以后the currently accepted answer似乎cause problems,这是另一种选择。它主要基于the solution by lc.,但负责订购。
首先:SQL表没有明确定义的行顺序。当您查询表的所有行时,这些行将按特定顺序返回,但该顺序未定义,可能与添加行的顺序相关,也可能不相关,并且可能会意外更改。因此,当您要按给定顺序处理行时,应添加一列以包含某种序列号或smilar。这就是lc的原因。 kept bugging you关于地点的顺序。
如果您有一个名为seq
的列,则可以使用以下查询:
SELECT GROUP_CONCAT(loc SEPARATOR ' - ')
FROM (
(SELECT 1 half, seq, SUBSTRING_INDEX(location, ' - ', 1) loc
FROM location_list
WHERE reservno='00004'
ORDER BY seq
LIMIT 1)
UNION ALL
(SELECT 2 half, seq, SUBSTRING_INDEX(location, ' - ', -1) loc
FROM location_list
WHERE reservno='00004')
ORDER BY half, seq
) locs
联合将生成各种位置的列表,使用最外面的选择将其组合成单个字符串。联合的第一部分产生路线第一部分的前半部分,而联合的第二部分将给出所有部分的后半部分。到目前为止,联合结果的顺序是未定义的,因此我们需要一个整体排序规则。我们还需要一个上半年的排序规则,以便我们真正选择带限制条款的路线的第一部分。
Here是一个基于Omesh设置的sqlfiddle。由于缺少seq
列,它会使用icode
列来排序。因此,结果与您预期的结果不同,而是生成Manila - Bohol - Cebu - Manila
。
如果添加seq
列,则必须更改数据库架构,因此您也可以更改它,使每个部分的两个端点转换为两个不同的列。使用CONCAT
组合列很简单,但拆分它们会增加开发人员和数据库引擎的查询复杂性。
如果您无法添加序列列,因为您无法控制数据库架构,那么您就遇到了麻烦。 Your comment here表示您一直在寻找一个循环,但是从无序数据中找到这样一个循环最好使用map来完成,{{3}}在SQL级别不可用。你可以通过存储过程实现这一点,如果必须,为jurney的每个部分执行一个选择,但如果我是你,我宁愿在应用程序级别解决这个问题。