【问题标题】:Concatenate SQL Results by Year (Year, Make, Model)按年份连接 SQL 结果(年份、品牌、型号)
【发布时间】:2015-11-17 20:20:10
【问题描述】:

我有一个相当简单的查询,用于获取车辆属性,例如年份、品牌和型号。目前的数据看起来与此类似...:

+------+------+-----------+-------+----------+------------------------------------------+
| SKU  | Year |   Make    | Model | Submodel |                  Notes                   |
+------+------+-----------+-------+----------+------------------------------------------+
| 0001 | 1995 | Chevrolet | Astro | Base     | Clear Lens; Chrome Housing; Pair; 1 pc.; |
| 0001 | 1995 | Chevrolet | Astro | CL       | Clear Lens; Chrome Housing; Pair; 1 pc.; |
| 0001 | 1995 | Chevrolet | Astro | LS       | Clear Lens; Chrome Housing; Pair; 1 pc.; |
| 0001 | 1996 | Chevrolet | Astro | Base     | Clear Lens; Chrome Housing; Pair; 1 pc.; |
| 0001 | 1996 | Chevrolet | Astro | CL       | Clear Lens; Chrome Housing; Pair; 1 pc.; |
| 0001 | 1996 | Chevrolet | Astro | LS       | Clear Lens; Chrome Housing; Pair; 1 pc.; |
| 0001 | 1997 | Chevrolet | Astro | Base     | Clear Lens; Chrome Housing; Pair; 1 pc.; |
| 0001 | 1997 | Chevrolet | Astro | LT       | Clear Lens; Chrome Housing; Pair; 1 pc.; |
| 0001 | 2001 | Chevrolet | Astro | Base     | Clear Lens; Chrome Housing; Pair; 1 pc.; |
+------+------+-----------+-------+----------+------------------------------------------+

当其他数据在行中匹配时(SKU、品牌、型号、子型号、备注),我想连接年份。最终结果的一个例子是这样的......:

+------+-------------+-----------+-------+----------+------------------------------------------+
| SKU  |    Year     |   Make    | Model | Submodel |                  Notes                   |
+------+-------------+-----------+-------+----------+------------------------------------------+
| 0001 | 1995 - 1997 | Chevrolet | Astro | Base     | Clear Lens; Chrome Housing; Pair; 1 pc.; |
| 0001 | 1995 - 1996 | Chevrolet | Astro | CL       | Clear Lens; Chrome Housing; Pair; 1 pc.; |
| 0001 | 1995 - 1996 | Chevrolet | Astro | LS       | Clear Lens; Chrome Housing; Pair; 1 pc.; |
| 0001 | 1997        | Chevrolet | Astro | LT       | Clear Lens; Chrome Housing; Pair; 1 pc.; |
| 0001 | 2001        | Chevrolet | Astro | Base     | Clear Lens; Chrome Housing; Pair; 1 pc.; |
+------+-------------+-----------+-------+----------+------------------------------------------+

查询当前看起来像...:

SELECT DISTINCT
sku,
YearID,
MakeName,
modelname,
SubmodelName,
notes
FROM
TableName
WHERE 1

在与我类似的示例中,向用户提供了一个指向查询中“CASE”用法的答案。提供的示例如下,但它在整个表格中获取了最小和最大年份。最终结果是这样的,只有一个结果...

+------+-------------+-----------+-------+----------+------------------------------------------+
| SKU  |    Year     |   Make    | Model | Submodel |                  Notes                   |
+------+-------------+-----------+-------+----------+------------------------------------------+
| 0001 | 1950 - 2015 | Chevrolet | Astro | Base     | Clear Lens; Chrome Housing; Pair; 1 pc.; |
+------+-------------+-----------+-------+----------+------------------------------------------+

示例查询(包括 CASE)...:

SELECT DISTINCT
sku,
CASE
WHEN MIN(YearID) = MAX(YearID) 
    THEN MIN(YearID)
ELSE CONCAT(MIN(YearID), '-', MAX(YearID))
END As Year,
MakeName,
modelname,
SubmodelName,
notes
FROM
TableName
WHERE 1

非常感谢您在获得我想要的结果方面的帮助。我一直不知道如何通过 SQL 做到这一点。

【问题讨论】:

  • 我的第一个想法是把当年的 MINMAX 串联起来,但这会像 1967 年制造的 Camaro 这样的东西咬你一口- 2002 年,然后一直中断到 2010 年。查询将返回 '1967 - 2016',您实际上应该有两个单独的行,'1967 - 2002''2010-2016'。为了处理这个问题,我认为您需要一个游标来滚动记录集并检查年份间隔。然后我看到这是一个 mysql,不知道它是否支持游标等,并决定留下这个评论进一步解释问题。
  • 感谢@LDMJoe 的帮助。您指出了我的一个担忧,我不确定如何让它发挥作用,或者是否可能以这种方式工作。感谢您花时间提供您的见解。 :-)
  • @LDMJoe 我在数据中没有看到这种情况
  • @JuanCarlosOropeza 没错,但这显然只是几行样本数据。我认为 OP 的完整数据是基于已知存在这种情况的现实世界数据。我刚刚看到了一个潜在的绊脚石并记下了它。 OP 可以决定是否需要对此进行解释,并相应地接受(或不接受)他自己的答案。
  • 我已更改我的答案。请再试一次

标签: mysql sql concatenation


【解决方案1】:

我又换了一次。请测试它并让我知道它是否有效。抱歉之前的 SQL 不好。第一次忘记初始化变量了。

  SELECT
    sku,
    CASE
      WHEN MIN(YEAR) = MAX(YEAR) THEN MIN(YEAR)
      ELSE CONCAT(MIN(YEAR), '-', MAX(YEAR))
     END AS YEAR,
     make, model, submodel, notes
  FROM
    (SELECT @ldfnr:= IF((@old_make = tab.make
      AND @old_model = tab.model
      AND @old_submodel = tab.submodel
      AND @old_notes = tab.notes
      AND (@old_year = tab.`year`
      OR @old_year = tab.`year`-1)) , @ldfnr, @ldfnr+1) AS nr, tab.* ,
      @old_make := tab.make , @old_model := tab.model ,
      @old_submodel := tab.submodel , @old_notes := tab.notes ,
      @old_year := tab.`year`
    FROM TableName AS tab,
      (SELECT @ldfnr:=0, @old_model:='', @old_submodel:='', @old_notes:='', @old_year:='', @old_make:=''  ) AS tmp
    ORDER BY make, model, submodel, notes, `YEAR` ASC) AS mytab
  GROUP BY nr
  ORDER BY nr;

+------+-----------+-----------+-------+----------+------------------------------------------+
| sku  | YEAR      | make      | model | submodel | notes                                    |
+------+-----------+-----------+-------+----------+------------------------------------------+
|    1 | 1995-1997 | Chevrolet | Astro | Base     | Clear Lens; Chrome Housing; Pair; 1 pc.; |
|    1 | 2001      | Chevrolet | Astro | Base     | Clear Lens; Chrome Housing; Pair; 1 pc.; |
|    1 | 1995-1996 | Chevrolet | Astro | CL       | Clear Lens; Chrome Housing; Pair; 1 pc.; |
|    1 | 1995-1996 | Chevrolet | Astro | LS       | Clear Lens; Chrome Housing; Pair; 1 pc.; |
|    1 | 1997      | Chevrolet | Astro | LT       | Clear Lens; Chrome Housing; Pair; 1 pc.; |
+------+-----------+-----------+-------+----------+------------------------------------------+
5 rows in set (0.44 sec)

【讨论】:

  • Camaro 打破了这一点(见我对 OP 的评论)。
  • 谢谢你的回答,伯恩德。不幸的是,我在运行此查询时收到的结果不包括顺序连接。结果与原始数据一样返回,带有一个额外的列(“nr”),从 1 开始,并以 1 递增。
  • 抱歉,复制粘贴错误。在查询结束时将 GROUP BY nr; 更改为 GROUP BY nr ORDER BY nr;
  • 嗨,伯恩德!谢谢你的及时回复。我也刚试过,没用。我在查询中没有收到任何错误,但也没有发生串联。非常感谢您在这方面的帮助。
  • 嗨@Brian Schroeter,如果再次更改我的答案。请再次测试
【解决方案2】:

您可能希望将 STUFF 函数与 xml 子查询一起使用。这将允许您选择同一行上的信息并将其连接起来。我将其用于类似的查询。

https://sqlwhisper.wordpress.com/2013/03/24/stuff-and-for-xml-path-for-string-concatenation/

【讨论】:

    猜你喜欢
    • 2012-05-16
    • 1970-01-01
    • 2015-08-27
    • 2022-12-07
    • 1970-01-01
    • 1970-01-01
    • 2020-07-07
    • 1970-01-01
    • 2023-03-29
    相关资源
    最近更新 更多