我有一个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
答案 0 :(得分: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))
答案 1 :(得分:0)
我认为你应该改变你的表结构并使它像这样。
tblName
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
通过这种方式,您可以轻松查询和管理表格中的数据。
答案 2 :(得分:0)
您应该修复数据结构,这样就不会在列中存储以逗号分隔的列表。这是在关系数据库中存储数据的错误方法。 。 。你可以从回答这个简单问题的问题中看出来。你想要的是一个交接表。
有时,我们会遇到其他人不好的设计。你说只有两个或值,那么你可以这样做:
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;
答案 3 :(得分:0)
首先......我会创建一个语句,将所有行转换为一个大的逗号分隔列表。
DECLARE @tmp VarChar(max)
SET @tmp = ''
SELECT @tmp = @tmp + ColumnA + ',' FROM TableA
然后使用本SO文章描述的表值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