使用HAVING搜索字符串的一部分

时间:2015-03-01 12:15:32

标签: sql database having database-table

我想知道是否可以使用sql HAVING来查找表中的某些行。

示例:

我有一个有三列的表 - > ID(int,主键),类型和大小(varchar)

一行看起来像这样:

ID     type          size 
1      15; 16; 17    4; 8

要选择类型为15的行,请使用以下查询

SELECT * FROM tableName WHERE type HAVING "15"

这样做是否可以,或者有更好的方法吗?

提前谢谢!

2 个答案:

答案 0 :(得分:2)

您的语法在大多数数据库中都不起作用。它将发生在MySQL中工作,因为MySQL允许为非聚合查询设置子句。

即使在MySQL中,该条款也不会做任何事情,因为“15”只是一个数字。在布尔上下文中,非零数字被解释为“true”,零被解释为“false”。您要使用的是where

select *
from table
where type = 15;

唉,这对你不起作用,因为你有一个混乱的数据结构。您不应该将列表存储在字符串中。您应该将它们存储在联结表中(您可以使用Google术语来了解有关它的更多信息)。因此,最好的方法是正确存储数据。

如果你必须使用这个数据结构(比如,你在一个荒岛上除非你在这样的数据库上写查询,他们就不会给你发送食物),那么你可以使用like或{{ 1}}。在这种情况下,第一个更容易:

find_in_set()

答案 1 :(得分:0)

不,你必须做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%'

<强>返回

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
    )

<强>返回

ID   type       Size
1   15; 16; 17; 4; 8;