如何在获取记录数和最小值/最大值的 MySQL 查询中使用 GROUP_CONCAT DISTINCT 值?

fre*_*ent 6 mysql query subquery select

我正在运行 MySQL 5.0.88 (Coldfusion8)

我有一个产品搜索,我正在查询number-of-results以及min/max prices/rebates整个产品表。我还想包含一个 的字符串distinct sizes/colors,这样我就可以在显示结果的同时更新我的​​搜索条件。

但是我的 GROUP_CONCAT 没有返回所有预期值。我不知道我错过了什么,但它似乎只返回不同的min/max尺寸/颜色,而不是返回all整个记录集的不同尺寸/颜色。

我的产品表:

 CREATE TABLE dummy (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`iln` VARCHAR(13) NULL DEFAULT NULL,
`ean` VARCHAR(35) NULL DEFAULT NULL,
`artikelnummer` VARCHAR(35) NULL DEFAULT NULL,
`groesse` VARCHAR(10) NULL DEFAULT NULL,
`farbe` VARCHAR(35) NULL DEFAULT NULL,
`farbnummer` VARCHAR(10) NULL DEFAULT NULL,
`preis_ek` DECIMAL(12,2) NULL DEFAULT NULL,
`preis_vk` DECIMAL(12,2) NULL DEFAULT NULL,
`preis_aktuell` DECIMAL(12,2) NULL DEFAULT NULL,
`firma` VARCHAR(35) NULL DEFAULT NULL,
`marke` VARCHAR(35) NULL DEFAULT NULL,
`nos` VARCHAR(4) NULL DEFAULT NULL,
`nos_anzeige` VARCHAR(4) NULL DEFAULT NULL,
`aktiv` VARCHAR(4) NULL DEFAULT NULL,
`modus` VARCHAR(4) NULL DEFAULT NULL,
`bestand` DECIMAL(10,0) NULL DEFAULT '0'
    )
Run Code Online (Sandbox Code Playgroud)

产品由 EAN 列出,因此例如 S、M、L、XL 号衬衫将有 4 个条目,如下所示:

  style      ean           size       price      qty
  123      111111111111    S          9.99       12
  123      111111111112    M          9.99        1
  123      111111111113    L          9.99       23
  123      111111111114    XL         9.99        0
Run Code Online (Sandbox Code Playgroud)

这是我的查询:

 SELECT   COUNT(recordcount) AS total_records
        , MIN(min_price_ek) AS ek_min
        , MAX(max_price_ek) AS ek_max
        , MIN(min_price_vk) AS vk_min
        , MAX(max_price_vk) AS vk_max
        , MAX(max_reb) AS rb_max
        , SUBSTRING_INDEX( GROUP_CONCAT( DISTINCT sizeRange ), ',', 10  ) AS sz_rng
        , SUBSTRING_INDEX( GROUP_CONCAT( DISTINCT colorRange ), ',', 16  ) AS cl_rng 

    FROM (SELECT  a.id AS recordcount
                , a.nos
                , a.nos_anzeige
                , MAX(IFNULL(p.ek, a.preis_ek)) AS max_price_ek
                , MIN(IFNULL(p.ek, a.preis_ek)) AS min_price_ek
                , MAX(IFNULL(p.vk, a.preis_vk)) AS max_price_vk
                , MIN(IFNULL(p.vk, a.preis_vk)) AS min_price_vk
                , ROUND( MAX(  ( IFNULL(p.ek, a.preis_ek) - IFNULL(p.vk ,a.preis_aktuell) ) /  IFNULL(p.ek, a.preis_ek)  ),2) AS max_reb
                , a.groesse AS sizeRange
                , zu.systemfarbe AS colorRange 

                FROM artikelstammdaten a

                # currency join
                LEFT JOIN preislisten p ON 
                    p.iln = a.iln 
                AND p.ean = a.ean 
                AND ( (  p.preisliste = "Test" AND p.iln = "2222222222222" ) OR (1=0) )

                # base color join
                LEFT JOIN farbenzuordnung zu ON 
                    a.farbe = zu.farbe 

                WHERE a.aktiv = "ja"
                # include currency if applicable
                AND ( IF( a.iln IN ( 2222222222222), p.onlinepreis IS NOT NULL,1 ) )

                AND a.artikelnummer LIKE "%style_number%"


            GROUP BY a.iln, a.artikelnummer
            HAVING (( sum(a.bestand) != 0 ) OR (a.nos = "ja" AND a.nos_anzeige = "ja" ))
            ) AS temp 
Run Code Online (Sandbox Code Playgroud)

我需要按卖家 ( a.iln) 和风格 ( a.artikelnummer)分组。该having子句仅选择有库存 ( sum(a.bestand) != 0) 或永远不会缺货的a.nos产品(设置在产品和a.nos_anzeige功能上)。

我的问题是选择在这些行中完成的不同尺寸/颜色:

  , SUBSTRING_INDEX( GROUP_CONCAT( DISTINCT sizeRange ), ',', 10  ) AS sz_rng
  , SUBSTRING_INDEX( GROUP_CONCAT( DISTINCT colorRange ), ',', 10  ) AS cl_rng
   ....
  , a.groesse AS sizeRange
  , zu.systemfarbe AS colorRange  
Run Code Online (Sandbox Code Playgroud)

这不能正常工作。上面的文章只会返回s,xlvs s,m,l,xl,我不确定为什么。我使用SUBSTRING_INDEX仅选择前 10 种尺寸/颜色(前 10 种会更好),但我不确定这是问题所在。

问题:
语法中是否有错误导致并非所有不同的大小/颜色都被返回?有没有办法只返回

fre*_*ent 2

好的。经过一段时间的研究并记住@Shlomi Noach 的评论后,我得出了以下结论:

  • a.groesse还可以按和进行分组zu.systemfarbe
  • 这摆脱了recordcount(似乎我现在不再按样式编号分组(a.artikelnummer
  • 删除COUNT(recordcount) AS total_records并在子查询中使用COUNT(DISTINCT styles) AS total_recordswith 代替 a.artikelnummer AS styles

所以我的查询现在看起来像这样:

 SELECT 
        COUNT(DISTINCT styles) AS total_records
      , MIN(min_price_ek) AS ek_min
      , MAX(max_price_ek) AS ek_max
      , MIN(min_price_vk) AS vk_min
      , MAX(max_price_vk) AS vk_max
      , MAX(max_reb) AS rb_max
      , SUBSTRING_INDEX( GROUP_CONCAT( DISTINCT sizeRange ), ',', 10  ) AS sz_rng
      , SUBSTRING_INDEX( GROUP_CONCAT( DISTINCT colorRange ), ',', 16  ) AS cl_rng

      FROM (SELECT  
             a.artikelnummer AS styles
           , a.nos
           , a.nos_anzeige
           , MAX(IFNULL(p.ek, a.preis_ek)) AS max_price_ek
           , MIN(IFNULL(p.ek, a.preis_ek)) AS min_price_ek
           , MAX(IFNULL(p.vk, a.preis_vk)) AS max_price_vk
           , MIN(IFNULL(p.vk, a.preis_vk)) AS min_price_vk
           , ROUND( MAX(  ( IFNULL(p.ek, a.preis_ek) - IFNULL(p.vk ,a.preis_aktuell) ) /  IFNULL(p.ek, a.preis_ek)  ),2) AS max_reb
           , a.groesse AS sizeRange
           , zu.systemfarbe AS colorRange

           ...
            GROUP BY  a.iln, a.artikelnummera.groesse, zu.systemfarbe
            HAVING (( sum(a.bestand) != 0 ) OR (a.nos = "ja" AND a.nos_anzeige = "ja" ))
            ) AS temp
Run Code Online (Sandbox Code Playgroud)

似乎工作和查询处理时间也差不多。如果这可以通过任何其他/更简单的方式完成,我愿意接受改进建议。

谢谢!