GROUP_CONCAT returns 1 行 0 个结果
GROUP_CONCAT returns 1 row for 0 results
我希望这是有道理的。
我有一个查询 运行 到 PHP,作为查询的一部分,我正在使用 GROUP_CONCAT。它工作得很好,可以做我想做的一切,但如果结果为空,它仍然 returns 1 结果具有一系列 NULL 值。我知道这是 GROUP_CONCAT 影响的,因为如果我从查询中删除它,问题就不会发生。
另外,我很清楚我可以简单地用 PHP 解决这个问题,方法是读取数组中的第一个变量,检查空值,然后假设它是一个空字符串,但我更很好奇为什么会发生这种情况,如果有更好的方法我可以在这里写下我的 SQL。
我不知道它是否有帮助,但这是我的查询
SELECT
m.id, m.RNID, m.DisplayLogoPath, m.DisplayName, m.TagLine,
(acos(sin(:lat)*sin(radians(m.Lat)) + cos(:lat)*cos(radians(m.Lat))*cos(radians(m.Lng)-:lon)) * :R) As Distance,
a.Add1, a.Add2, a.City as CityOther, a.State as StateOther, a.Zip as ZipOther,
g.primary_city, g.state, g.zip,
p.AreaCode, p.Prefix, p.LineNum,
h.Open, h.Close, h.Open24, h.Closed24,
GROUP_CONCAT(DISTINCT(ra.Name)) as AlcoholArray,
GROUP_CONCAT(DISTINCT(rc.Name)) AS CuisineArray,
GROUP_CONCAT(DISTINCT(rd.Name)) AS DiningArray,
k.id AS KidsMenu
FROM 20_00_locations m
/*Address*/
LEFT JOIN 20_01_addresses a
ON a.RestID = m.id
AND a.active = 1
AND a.Type = 1
/*Geographic ref data*/
LEFT JOIN 80_00_geo_data g
ON g.id = a.CSZID
/*Phone*/
LEFT JOIN 20_01_phones p
ON p.RestID = m.id
AND p.active = 1
AND p.Type = 1
/*Restaurant hours*/
LEFT JOIN 60_20_1_hours h
ON m.HoursTempID = h.TempID
AND h.DayNum = 1 /*Assigned dynamically*/
/*Check the kids menu status - if Null, no kids menu. If id has value, kids menu*/
LEFT JOIN 20_02_config k
ON k.RestID = m.id
AND k.active = 1
AND k.OptID = 8
and k.TypeID = 29
/*Config used to get cuisine, alcohol, dining, etc*/
LEFT JOIN 20_02_config c
ON c.RestID = m.id
AND c.active = 1
/*Cusine types*/
LEFT JOIN 80_00_master rc
ON rc.IntID = c.OptID
AND rc.ParID = 29
AND c.TypeID = 29
AND c.OptID <> 8
/*Alcohol types*/
LEFT JOIN 80_00_master ra
ON ra.IntID = c.OptID
AND ra.ParID = 30
AND c.TypeID = 30
/*Dining types*/
LEFT JOIN 80_00_master rd
ON rd.IntID = c.OptID
AND rd.ParID = 31
AND c.TypeID = 31
/*Menu table*/
WHERE (acos(sin(:lat)*sin(radians(m.Lat)) + cos(:lat)*cos(radians(m.Lat))*cos(radians(m.Lng)-:lon)) * :R) < :rad
AND m.Lat Between :minLat And :maxLat
AND m.Lng Between :minLon And :maxLon
AND m.active = 1
AND m.Published = 1
ORDER BY Distance
关于你的查询的一些事情,你说你没有 GROUP BY 但你正在选择一些非聚合列:
SELECT
m.id, m.RNID, m.DisplayLogoPath, m.DisplayName, m.TagLine, ...
并且您正在使用一些聚合函数 GROUP_CONCAT:
GROUP_CONCAT(DISTINCT(ra.Name)) as AlcoholArray,
GROUP_CONCAT(DISTINCT(rc.Name)) AS CuisineArray,
GROUP_CONCAT(DISTINCT(rd.Name)) AS DiningArray,
因此您的查询将始终 return 1 行,但 m.id、m.RNID 等的值将不确定(它们可能来自第一行,或来自任何其他行)。
因此您可能想要删除所有非聚合列,并使用 HAVING 子句:
SELECT GROUP_CONCAT(...)
FROM ...
HAVING COUNT(*)>0
但是!您可能只是缺少一个 GROUP BY,我认为这应该足够了:
GROUP BY m.id
请注意,这不是 SQL 兼容的,但 MySQL 会很乐意执行它,并且(如果我理解正确的话)即使这不是好的做法,它也会 return 正确的结果。
但我更愿意将您的查询重写为:
SELECT
m.id, ...,
ra.AlcoholArray,
rc.CuisineArray,
...
FROM
20_00_locations m LEFT JOIN 20_01_addresses a ON ...
LEFT JOIN 80_00_geo_data g ON ...
...
LEFT JOIN (
SELECT IntID, GROUP_CONCAT(Name) AS CuisineArray
FROM 80_00_master
WHERE
rc.ParID = 29
GROUP BY IntID
) rc ON rc.IntID = c.OptID
...
使用子查询。
我希望这是有道理的。
我有一个查询 运行 到 PHP,作为查询的一部分,我正在使用 GROUP_CONCAT。它工作得很好,可以做我想做的一切,但如果结果为空,它仍然 returns 1 结果具有一系列 NULL 值。我知道这是 GROUP_CONCAT 影响的,因为如果我从查询中删除它,问题就不会发生。
另外,我很清楚我可以简单地用 PHP 解决这个问题,方法是读取数组中的第一个变量,检查空值,然后假设它是一个空字符串,但我更很好奇为什么会发生这种情况,如果有更好的方法我可以在这里写下我的 SQL。
我不知道它是否有帮助,但这是我的查询
SELECT
m.id, m.RNID, m.DisplayLogoPath, m.DisplayName, m.TagLine,
(acos(sin(:lat)*sin(radians(m.Lat)) + cos(:lat)*cos(radians(m.Lat))*cos(radians(m.Lng)-:lon)) * :R) As Distance,
a.Add1, a.Add2, a.City as CityOther, a.State as StateOther, a.Zip as ZipOther,
g.primary_city, g.state, g.zip,
p.AreaCode, p.Prefix, p.LineNum,
h.Open, h.Close, h.Open24, h.Closed24,
GROUP_CONCAT(DISTINCT(ra.Name)) as AlcoholArray,
GROUP_CONCAT(DISTINCT(rc.Name)) AS CuisineArray,
GROUP_CONCAT(DISTINCT(rd.Name)) AS DiningArray,
k.id AS KidsMenu
FROM 20_00_locations m
/*Address*/
LEFT JOIN 20_01_addresses a
ON a.RestID = m.id
AND a.active = 1
AND a.Type = 1
/*Geographic ref data*/
LEFT JOIN 80_00_geo_data g
ON g.id = a.CSZID
/*Phone*/
LEFT JOIN 20_01_phones p
ON p.RestID = m.id
AND p.active = 1
AND p.Type = 1
/*Restaurant hours*/
LEFT JOIN 60_20_1_hours h
ON m.HoursTempID = h.TempID
AND h.DayNum = 1 /*Assigned dynamically*/
/*Check the kids menu status - if Null, no kids menu. If id has value, kids menu*/
LEFT JOIN 20_02_config k
ON k.RestID = m.id
AND k.active = 1
AND k.OptID = 8
and k.TypeID = 29
/*Config used to get cuisine, alcohol, dining, etc*/
LEFT JOIN 20_02_config c
ON c.RestID = m.id
AND c.active = 1
/*Cusine types*/
LEFT JOIN 80_00_master rc
ON rc.IntID = c.OptID
AND rc.ParID = 29
AND c.TypeID = 29
AND c.OptID <> 8
/*Alcohol types*/
LEFT JOIN 80_00_master ra
ON ra.IntID = c.OptID
AND ra.ParID = 30
AND c.TypeID = 30
/*Dining types*/
LEFT JOIN 80_00_master rd
ON rd.IntID = c.OptID
AND rd.ParID = 31
AND c.TypeID = 31
/*Menu table*/
WHERE (acos(sin(:lat)*sin(radians(m.Lat)) + cos(:lat)*cos(radians(m.Lat))*cos(radians(m.Lng)-:lon)) * :R) < :rad
AND m.Lat Between :minLat And :maxLat
AND m.Lng Between :minLon And :maxLon
AND m.active = 1
AND m.Published = 1
ORDER BY Distance
关于你的查询的一些事情,你说你没有 GROUP BY 但你正在选择一些非聚合列:
SELECT
m.id, m.RNID, m.DisplayLogoPath, m.DisplayName, m.TagLine, ...
并且您正在使用一些聚合函数 GROUP_CONCAT:
GROUP_CONCAT(DISTINCT(ra.Name)) as AlcoholArray,
GROUP_CONCAT(DISTINCT(rc.Name)) AS CuisineArray,
GROUP_CONCAT(DISTINCT(rd.Name)) AS DiningArray,
因此您的查询将始终 return 1 行,但 m.id、m.RNID 等的值将不确定(它们可能来自第一行,或来自任何其他行)。
因此您可能想要删除所有非聚合列,并使用 HAVING 子句:
SELECT GROUP_CONCAT(...)
FROM ...
HAVING COUNT(*)>0
但是!您可能只是缺少一个 GROUP BY,我认为这应该足够了:
GROUP BY m.id
请注意,这不是 SQL 兼容的,但 MySQL 会很乐意执行它,并且(如果我理解正确的话)即使这不是好的做法,它也会 return 正确的结果。
但我更愿意将您的查询重写为:
SELECT
m.id, ...,
ra.AlcoholArray,
rc.CuisineArray,
...
FROM
20_00_locations m LEFT JOIN 20_01_addresses a ON ...
LEFT JOIN 80_00_geo_data g ON ...
...
LEFT JOIN (
SELECT IntID, GROUP_CONCAT(Name) AS CuisineArray
FROM 80_00_master
WHERE
rc.ParID = 29
GROUP BY IntID
) rc ON rc.IntID = c.OptID
...
使用子查询。