按相同或相似的字符串分组 sql

Group By same or similar string sql

1) 假设我有一个这样的 table:-

| id    |  color_code  |      fruit      |
|:------|--------------|----------------:|
| 1     |  000001      |      apple      |     
| 2     |  000001      |      apple      |    
| 3     |  000001      |      apple      |      
| 4     |  000002      |      lemon      |         
| 5     |  000002      |      lemon      |       
| 6     |  000003      |      grapes     |
| 7     |  000003      |      grapes     | 

如何根据 sql 服务器中的 color_code 列 水果列分组?

我想是这样的:-

| id    |  color_code  |      fruit      |   group_concat(id)  |
|:------|--------------|-----------------|---------------------|
| 1     |  000001      |      apple      |        1,2,3        |
| 4     |  000002      |      lemon      |        2,5          |
| 6     |  000003      |      grapes     |        6,7          |

2) 如果我有 3 个 table(如下所示)需要加入怎么办?

series_no table:

|   id  |  desc_seriesno  |
|:------|----------------:|
| 7040  |     AU1011      |
| 7041  |     AU1022      |
| 7042  |     AU1033      |
| 7043  |     AU1044      |
| 7044  |     AU1055      |
| 7045  |     AU1066      |

品牌 table:

|   id  |  desc_brand     |
|:------|----------------:|
| 1020  |     Audi        |
| 1021  |     Bentley     |
| 1022  |     Ford        |
| 1023  |     BMW         |
| 1024  |     Mazda       |
| 1025  |     Toyota      |

car_info table:

|   seriesno_id  |  brand_id  |  color  |
|:---------------|------------|--------:|
|     7040       |    1020    | white   |
|     7040       |    1020    | black   |
|     7040       |    1020    | pink    |
|     7041       |    1021    | yellow  |
|     7041       |    1021    | brown   |
|     7042       |    1022    | purple  |
|     7042       |    1022    | black   |
|     7042       |    1022    | green   |
|     7043       |    1023    | blue    |
|     7044       |    1024    | red     |
|     7045       |    1025    | maroon  |
|     7045       |    1025    | white   |    

这是我当前对 sql 服务器 2014 的查询:-

SELECT SN.id AS seriesid, B.id AS brandid, B.desc_brand
FROM [db1].[dbo].[series_no] SN
  LEFT JOIN [db1].[dbo].[car_info] CI
  ON CI.seriesno_id = SN.id
  RIGHT JOIN [db1].[dbo].[brand] B
  ON B.id = CI.brand_id
GROUP BY SN.id, B.id
ORDER BY SN.id ASC

但不幸的是它给了我一个错误,因为我不能用这种方式按相似的字符串分组。

我希望它是这样的:-

|  seriesid  |   brandid  |   desc_brand  | count |
|:-----------|------------|---------------|-------|
|    7040    |    1020    |     Audi      |   3   |
|    7041    |    1021    |     Bentley   |   2   |
|    7042    |    1022    |     Ford      |   3   |
|    7043    |    1023    |     BMW       |   1   |
|    7044    |    1024    |     Mazda     |   1   |
|    7045    |    1025    |     Toyota    |   2   |

使用下面的代码..

SELECT distinct
       m.color_code
     , m.fruit      
     , group_concat = STUFF((
          SELECT ',' + CONVERT(varchar(10),md.id) 
          FROM dbo.tablename md
          WHERE m.fruit = md.fruit and m.color_code = md.color_code 
          FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '')
FROM dbo.tablename  m

第二个:

SELECT SN.id AS seriesid, B.id AS brandid, B.desc_brand ,count(*)
FROM [db1].[dbo].[series_no] SN
  LEFT JOIN [db1].[dbo].[car_info] CI
  ON CI.seriesno_id = SN.id
  RIGHT JOIN [db1].[dbo].[brand] B
  ON B.id = CI.brand_id
GROUP BY SN.id, B.id ,B.desc_brand
ORDER BY 4 ASC

1种水果颜色

假设table名字是FruitColor,你可以通过下面的查询得到想要的输出-

SELECT MIN(id) AS id
    , color_code
    , fruit
    , group_concat_id = STUFF((SELECT ',' + CAST(id AS VARCHAR)
                               FROM FruitColor AS fci
                               WHERE fci.fruit = fc.fruit AND fci.color_code = fc.color_code
                               FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '')
FROM FruitColor AS fc
GROUP BY color_code, fruit
ORDER BY id;

2。你可以有几个选项 -

选项 (a):显示品牌系列的数量

SELECT seriesno_id AS seriesid, ci.brand_id AS bandid, desc_brand, COUNT(*)    AS [count]
FROM db1.dbo.car_info AS ci
LEFT JOIN db1.dbo.brand AS b ON (b.id = ci.brand_id)
GROUP BY seriesno_id, ci.brand_id, desc_brand;
  • 如果您想显示具有品牌的汽车的数量,则无需使用系列 table。
  • 您可能不需要对品牌 table 使用 RIGHT JOIN,因为如果品牌 table 包含一条记录 不在 car_info table 中,那么 seriesno_id 将为空。

选项 (b):显示有或没有品牌的所有系列的计数

SELECT sn.id AS seriesid, ci.brand_id AS bandid, desc_brand, COUNT(*) AS [count]
FROM db1.dbo.series_no AS sn
LEFT JOIN db1.dbo.car_info AS ci ON (ci.seriesno_id = sn.id)
LEFT JOIN db1.dbo.brand AS b ON (b.id = ci.brand_id)
GROUP BY sn.id, ci.brand_id, desc_brand;

选项 (c):解决选择不在 GROUP BY

中的列的方法
SELECT seriesno_id AS seriesid, ci.brand_id AS bandid, MAX(desc_brand) AS desc_brand, COUNT(*) AS [count]
FROM db1.dbo.car_info AS ci
LEFT JOIN db1.dbo.brand AS b ON (b.id = ci.brand_id)
GROUP BY seriesno_id, ci.brand_id;
  • 这里,如果我们确定每个品牌只包含一个desc_brand,我们可以对其使用聚合。 这是因为仅应用聚合一个值 returns 该值。我这里用的是MAX。

就我个人而言,我会选择选项 (a),因为它更有意义。

关于 desc_brand 为 NTEXT 的 GROUP BY 异常更新...

将 desc_brand 转换为 NVARCHAR 以避免异常。

 CAST(desc_brand AS NVARCHAR(200))

此外,我强烈建议使用 VARCHAR / NVARCHAR 而不是任何 TEXT、CHAR 等,因为它们通常占用更多内存。

SELECT 
id = SUBSTRING(group_concat,1,1),
color_code,
fruit,
group_concat
FROM(
SELECT distinct
   m.color_code, 
   m.fruit,       
   group_concat = STUFF((SELECT ',' + CONVERT(varchar(10),md.id) 
                         FROM [Test_1].[dbo].[Stuff] md
                         WHERE m.fruit = md.fruit 
                            AND m.color_code = md.color_code 
                         FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '')
FROM [Test_1].[dbo].[Stuff] m)x