【问题标题】:Retrieve Distinct concat values from MySQL table从 MySQL 表中检索不同的连续值
【发布时间】:2016-12-02 11:20:57
【问题描述】:

我有一个 SQL 表广告

id       name       cat
11       abc        ab
12       acb        ab, bc
13       abb        bcd
14       abcd       ad
15       acbd       de
16       abbd       ad

在使用 DISTINCT 函数时,我得到这样的输出

查询:

SELECT DISTINCT cat FROM advert;

输出:

ab
ab, bc
bcd
ad
de

对于这样的输出,我需要在查询中进行哪些更改

ab
bc
bcd
ad
de

【问题讨论】:

  • 我想最好的解决方案是每行分配一个类别。我假设你的 cat 是一个 varchar
  • 我会说错误的表结构。切勿将多个值放入一个字段中。
  • 单列最多可以包含多少个值?
  • @mabe02 是的,它的 varchar...问题是我已经发布了 3 列它有大约 25 列...如果我在每个字段中输入一个值,那么我必须复制这 25 列两次或三个 cat 值可能是三次...
  • @DuduMarkovitz 二三...

标签: mysql sql database distinct concat


【解决方案1】:
select distinct trim(substring_index(substring_index(cat,',',n),',',-1)) as cat

from   t join (select 1 as n union all select 2 union all select 3) r
       on cat like concat('%',repeat(',%',n-1))

【讨论】:

【解决方案2】:

我认为你应该改变你的表结构,让它变成这样。

tbl名称

id    | name
11       abc        
12       acb       
13       abb       
14       abcd      
15       acbd       
16       abbd

tblCat

id          | name_id |  cat
some ids*       11        ab
                12        ab
                12        bc
                13        bcd
                14        ad
                15        de
                16        ad

通过这种方式,您可以轻松查询和管理表中的数据。

【讨论】:

  • 我已经按照你的建议创建了表格......你能告诉我加入这两个的查询......谢谢......
  • 从 tblCat 中选择不同的猫
  • 该查询将显示您想要的结果。但是如果你想加入这两个 select distinct b.cat from tblCat as b inner join tblName as a
【解决方案3】:

您应该修复您的数据结构,这样您就不会将逗号分隔的列表存储在列中。这是在关系数据库中存储数据的错误方式。 . .从回答这个简单问题的问题中可以看出。你想要的是一个联结表。

有时,我们会被其他人的糟糕设计所困。你说只有两个 or 值,那么你可以这样做:

select cat
from ((select substring_index(cat, ', ', 1) as cat
       from advert
      ) union all
      (select substring_index(substring_index(cat, ', ', 2), ', ', -1) as cat
       from advert
       where cat like '%, %'
      ) union all
      (select substring_index(substring_index(cat, ', ', 3), ', ', -1) as cat
       from advert
       where cat like '%, %, %'
      )
     ) c
group by cat;

【讨论】:

    【解决方案4】:

    首先...我将创建一个语句,将所有行变成一个巨大的逗号分隔列表。

    DECLARE @tmp VarChar(max)
    SET @tmp = ''
    SELECT @tmp = @tmp + ColumnA + ',' FROM TableA
    

    然后使用这篇 SO 文章中描述的 table valued udf split 将那个庞大的字符串转回一个带有 distinct 子句的表,以确保它是唯一的。

    https://stackoverflow.com/a/2837662/261997

    SELECT DISTINCT * FROM dbo.Split(',', @tmp)
    

    完整代码示例:

    if object_id('dbo.Split') is not null
        drop function dbo.Split
    go
    CREATE FUNCTION dbo.Split (@sep char(1), @s varchar(512))
    RETURNS table
    AS
    RETURN (
        WITH Pieces(pn, start, stop) AS (
          SELECT 1, 1, CHARINDEX(@sep, @s)
          UNION ALL
          SELECT pn + 1, stop + 1, CHARINDEX(@sep, @s, stop + 1)
          FROM Pieces
          WHERE stop > 0
        )
        SELECT pn,
          SUBSTRING(@s, start, CASE WHEN stop > 0 THEN stop-start ELSE 512 END) AS s
        FROM Pieces
      )
    go
    declare @t table (colA varchar(max))
    insert @t select '111, 223'
    union all select '333'
    union all select '444'
    union all select '777,999';
    
    select  ltrim(rtrim(s.s)) as colC
    from    @t t
    cross apply
            dbo.split(',', t.colA) s
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-16
      • 2019-03-30
      • 2021-02-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多