简体   繁体   English

GROUP_CONCAT返回1行,共0个结果

[英]GROUP_CONCAT returns 1 row for 0 results

I hope this makes sense. 我希望这是有道理的。

I have a query that I'm running through PHP and as part of my query, I'm using GROUP_CONCAT. 我有一个查询,我正在通过PHP运行,作为查询的一部分,我正在使用GROUP_CONCAT。 It works great and does everything I want but if the results are empty, it still returns 1 results with a series of NULL values. 它的效果很好,可以执行我想要的一切,但是如果结果为空,它仍然会返回1个结果,其中包含一系列NULL值。 I know it is GROUP_CONCAT affecting this because if I remove it from the query, the issue doesn't happen. 我知道这是GROUP_CONCAT的问题,因为如果我从查询中将其删除,则不会发生此问题。

Also, I'm very well aware that I can simply fix this with PHP by reading the first variable in the array, checking for a null value then assuming it's an empty string but I'm more curious as to why this happens and if there is a better way I could be writing my SQL here. 另外,我非常清楚,我可以使用PHP来解决此问题,方法是读取数组中的第一个变量,检查null值,然后假定它为空字符串,但我对此事以及为什么要这样做感到好奇这是我可以在此处编写SQL的更好方法。

I don't know if it will help but here's my query 我不知道是否有帮助,但这是我的查询

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

Few things about your query, you said that you don't have a GROUP BY but you are SELECTing some non-aggregated columns: 关于查询的几件事,您说您没有GROUP BY,但是您正在选择一些未汇总的列:

SELECT
  m.id, m.RNID, m.DisplayLogoPath, m.DisplayName, m.TagLine, ...

and you are using some aggregated functions GROUP_CONCAT: 并且您正在使用一些聚合函数GROUP_CONCAT:

GROUP_CONCAT(DISTINCT(ra.Name)) as AlcoholArray,
GROUP_CONCAT(DISTINCT(rc.Name)) AS CuisineArray,
GROUP_CONCAT(DISTINCT(rd.Name)) AS DiningArray,

so your query will always return 1 row, but the values of m.id, m.RNID, etc. will be undetermined (they might be from the first row, or from any other row). 因此您的查询将始终返回1行,但是m.id,m.RNID等的值将不确定(它们可能来自第一行,或来自其他任何行)。

So you might want to remove all non-aggregated columns, and use an HAVING clause: 因此,您可能希望删除所有未聚合的列,并使用HAVING子句:

SELECT GROUP_CONCAT(...)
FROM ...
HAVING COUNT(*)>0

BUT! 但! you are probably just missing a GROUP BY, I think this should be enough: 您可能只是想念GROUP BY,我认为这应该足够了:

GROUP BY m.id

please note that this is not a SQL-compliant but MySQL will happily execute it, and (if I understand correctly) even if it is not considered good practice it will return the right result. 请注意,这不是SQL兼容的,但是MySQL会很乐意执行它,并且(如果我理解正确的话),即使不是很好的做法,它也会返回正确的结果。

But I would prefer to rewrite your query as this: 但是我更喜欢这样重写您的查询:

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
...

using subqueries. 使用子查询。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM