使用 HAVING 搜索字符串的一部分
Using HAVING to search for part of a string
我想知道是否可以使用 sql HAVING 在 table 中查找某些行。
示例:
我有一个 table 三列 -> ID(int,主键),类型和大小(varchar)
一行看起来像这样:
ID type size
1 15; 16; 17 4; 8
对于 select 类型为 15 的行,我使用以下查询
SELECT * FROM tableName WHERE type HAVING "15"
这样可以吗,还是有更好的方法?
提前致谢!
您的语法不适用于大多数数据库。它会 发生 在 MySQL 中工作,因为 MySQL 允许有非聚合查询的子句。
即使在 MySQL 中,该子句也不会执行任何操作,因为“15”只是一个数字。在布尔上下文中,非零数字被解释为 "true",零被解释为 "false"。您要使用的是 where
:
select *
from table
where type = 15;
唉,这对你不起作用,因为你的数据结构一团糟。您不应该将列表存储在字符串中。您应该将它们存储在联结表中(您可以 Google 该术语了解更多信息)。所以,最好的方法就是正确存储数据。
如果你必须使用这个数据结构(比如,你在一个荒岛上,除非你在这样的数据库上写查询,否则他们不会给你送食物),那么你可以使用 like
或find_in_set()
。在这种情况下,第一个更容易:
where concat('; ', type, '; ') like '%; 15; %'
不,你必须做一个LIKE
CREATE TABLE #test(
ID int,
[type] varchar(255),
[size] varchar(255)
);
insert into #test VALUES(1, '15; 16; 17;', '4; 8;')
select * from #test where [type] like '%15%'
Returns
ID type Size
1 15; 16; 17; 4; 8;
或者您可以将 IN 语句与 Split 函数结合使用:
用法
declare @val varchar(255);
set @val = 15
select * from #test t where @val in (select Value from [dbo].udf_Split(t.[type], ';') as i)
函数
CREATE Function [dbo].[udf_Split]
(
@DelimitedList nvarchar(max)
, @Delimiter nvarchar(2)
)
RETURNS TABLE
AS
RETURN
(
With CorrectedList As
(
Select Case When Left(@DelimitedList, Len(@Delimiter)) <> @Delimiter Then @Delimiter Else '' End
+ @DelimitedList
+ Case When Right(@DelimitedList, Len(@Delimiter)) <> @Delimiter Then @Delimiter Else '' End
As List
, Len(@Delimiter) As DelimiterLen
)
, Numbers As
(
Select TOP( Coalesce(DataLength(@DelimitedList)/2,0) ) Row_Number() Over ( Order By c1.object_id ) As Value
From sys.columns As c1
Cross Join sys.columns As c2
)
Select CharIndex(@Delimiter, CL.list, N.Value) + CL.DelimiterLen As Position
, Substring (
CL.List
, CharIndex(@Delimiter, CL.list, N.Value) + CL.DelimiterLen
, CharIndex(@Delimiter, CL.list, N.Value + 1)
- ( CharIndex(@Delimiter, CL.list, N.Value) + CL.DelimiterLen )
) As Value
From CorrectedList As CL
Cross Join Numbers As N
Where N.Value <= DataLength(CL.List) / 2
And Substring(CL.List, N.Value, CL.DelimiterLen) = @Delimiter
)
Returns
ID type Size
1 15; 16; 17; 4; 8;
我想知道是否可以使用 sql HAVING 在 table 中查找某些行。
示例:
我有一个 table 三列 -> ID(int,主键),类型和大小(varchar)
一行看起来像这样:
ID type size
1 15; 16; 17 4; 8
对于 select 类型为 15 的行,我使用以下查询
SELECT * FROM tableName WHERE type HAVING "15"
这样可以吗,还是有更好的方法?
提前致谢!
您的语法不适用于大多数数据库。它会 发生 在 MySQL 中工作,因为 MySQL 允许有非聚合查询的子句。
即使在 MySQL 中,该子句也不会执行任何操作,因为“15”只是一个数字。在布尔上下文中,非零数字被解释为 "true",零被解释为 "false"。您要使用的是 where
:
select *
from table
where type = 15;
唉,这对你不起作用,因为你的数据结构一团糟。您不应该将列表存储在字符串中。您应该将它们存储在联结表中(您可以 Google 该术语了解更多信息)。所以,最好的方法就是正确存储数据。
如果你必须使用这个数据结构(比如,你在一个荒岛上,除非你在这样的数据库上写查询,否则他们不会给你送食物),那么你可以使用 like
或find_in_set()
。在这种情况下,第一个更容易:
where concat('; ', type, '; ') like '%; 15; %'
不,你必须做一个LIKE
CREATE TABLE #test(
ID int,
[type] varchar(255),
[size] varchar(255)
);
insert into #test VALUES(1, '15; 16; 17;', '4; 8;')
select * from #test where [type] like '%15%'
Returns
ID type Size
1 15; 16; 17; 4; 8;
或者您可以将 IN 语句与 Split 函数结合使用:
用法
declare @val varchar(255);
set @val = 15
select * from #test t where @val in (select Value from [dbo].udf_Split(t.[type], ';') as i)
函数
CREATE Function [dbo].[udf_Split]
(
@DelimitedList nvarchar(max)
, @Delimiter nvarchar(2)
)
RETURNS TABLE
AS
RETURN
(
With CorrectedList As
(
Select Case When Left(@DelimitedList, Len(@Delimiter)) <> @Delimiter Then @Delimiter Else '' End
+ @DelimitedList
+ Case When Right(@DelimitedList, Len(@Delimiter)) <> @Delimiter Then @Delimiter Else '' End
As List
, Len(@Delimiter) As DelimiterLen
)
, Numbers As
(
Select TOP( Coalesce(DataLength(@DelimitedList)/2,0) ) Row_Number() Over ( Order By c1.object_id ) As Value
From sys.columns As c1
Cross Join sys.columns As c2
)
Select CharIndex(@Delimiter, CL.list, N.Value) + CL.DelimiterLen As Position
, Substring (
CL.List
, CharIndex(@Delimiter, CL.list, N.Value) + CL.DelimiterLen
, CharIndex(@Delimiter, CL.list, N.Value + 1)
- ( CharIndex(@Delimiter, CL.list, N.Value) + CL.DelimiterLen )
) As Value
From CorrectedList As CL
Cross Join Numbers As N
Where N.Value <= DataLength(CL.List) / 2
And Substring(CL.List, N.Value, CL.DelimiterLen) = @Delimiter
)
Returns
ID type Size
1 15; 16; 17; 4; 8;