使用 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 该术语了解更多信息)。所以,最好的方法就是正确存储数据。

如果你必须使用这个数据结构(比如,你在一个荒岛上,除非你在这样的数据库上写查询,否则他们不会给你送食物),那么你可以使用 likefind_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;