1

我有一个如下表族

Family_Name | Family_Members_Age
Johnson     | 45,60,56
Ken         | 78,67,40
David       | 40

这是我有的一个过程

CREATE PROCEDURE getFamilyRowsByAge @Age nvarchar(30)
AS
SELECT * 
FROM Family
WHERE Family_members_age LIKE FILL_IN -- need to get this fill_in dynamically

@Age 参数以逗号分隔的字符串形式提供,例如45,67. 对于 "45,67" 的输入字符串,FILL_IN 将是这样的LIKE '%45%' OR LIKE '%67%'。我希望通过将输入字符串拆分为逗号并加入 LIKE OR 来动态创建它。MSSQL 中有没有办法做到这一点?

Output:
Johnson     | 45,60,56
Ken         | 78,67,40

这是另一个输入和输出:

input : 40, 67, 69
Output:
Johnson     | 45,60,56
Ken         | 78,67,40
David       | 40
4

4 回答 4

1

你可以通过这种简单的方式来实现它,现场演示在这里

strSplit

CREATE FUNCTION  [dbo].[strSplit] ( @string nvarchar( MAX), @splitter CHAR( 1) )  
RETURNS @res TABLE (id INT PRIMARY KEY, rank INT, val nvarchar( MAX) )  
AS  
BEGIN  
     IF SUBSTRING ( @string, len ( @string), 1)<>@splitter  
          SET @string= @string+@splitter  
     DECLARE @start INT, @word nvarchar(MAX), @charindex INT, @i INT  
     SET @i=1  
     SET @start=1  
     SET @charindex= CHARINDEX( @splitter, @string, @start)  
     WHILE (@charindex <> 0)BEGIN  
          SET @word= SUBSTRING( @string, @start, @charindex - @start)  
          SET @start= @charindex +1  
          SET @charindex= CHARINDEX( @splitter, @string, @start)  
          INSERT INTO @res  VALUES ( @start, @i, @word)  
          SET @i=@i+1  
     END  
     RETURN
END  

包含字符串

CREATE FUNCTION  [dbo].[ContainString] (@string1 nvarchar( MAX), @string2 nvarchar( MAX))  
RETURNS BIT
AS  
BEGIN  
     IF(EXISTS(SELECT TOP 1 a.val From strSplit(@string1, ',') a
               INNER JOIN strSplit(@string2, ',') b on a.val = b.val ))
     BEGIN
       RETURN 1
     END

     RETURN 0
END  

选择结果

SELECT * FROM Family WHERE [dbo].ContainString(Family_Members_Age, '45,67') = 1
SELECT * FROM Family WHERE [dbo].ContainString(Family_Members_Age, '40,67,69') = 1
于 2020-01-08T07:17:36.710 回答
1

根据这些评论,试试这个:

USE tempdb;
GO

DROP TABLE IF EXISTS dbo.Family;
GO

CREATE TABLE dbo.Family
(
    FamilyID int IDENTITY(1,1) 
        CONSTRAINT PK_dbo_Family PRIMARY KEY,
    Family_Name varchar(100),
    Family_Members_Age varchar(max)
);
GO

INSERT dbo.Family (Family_Name, Family_Members_Age)
VALUES ('Johnson', '45,60,56'),
       ('Ken', '78,67,40'),
       ('David', '40');
GO

CREATE PROCEDURE dbo.GetFamilyRowsByAge 
@RequiredAges varchar(100)
AS
BEGIN
    SET NOCOUNT ON;
    SET XACT_ABORT ON;

    WITH FamilyAges
    AS
    (
        SELECT f.Family_Name, fma.Age
        FROM dbo.Family AS f
        CROSS APPLY (SELECT value AS Age FROM STRING_SPLIT(f.Family_Members_Age,',')) AS fma
    )
    SELECT fa.Family_Name, fa.Age 
    FROM FamilyAges AS fa
    WHERE fa.Age IN (SELECT value FROM STRING_SPLIT(@RequiredAges, ','));
END;
GO

EXEC dbo.GetFamilyRowsByAge '45,67,40';
GO

于 2020-01-08T07:13:04.360 回答
0

可能你需要这样的东西。

SELECT 'Johnson'Family_Name,'45,60,56' Family_Members_Age 
into #YourTable
union all select 'Ken','78,67,40'
union all select 'David','40'

DECLARE  @WhereQuery varchar(250)='40, 67, 69', @Query nvarchar(250)

select @Query = 'select * from #YourTable' 

SET @WhereQuery = ' WHERE Family_Members_Age LIKE ''%'+ REPLACE (@WhereQuery,',','%'' OR Family_Members_Age LIKE ''%') + '%'''

SET @Query = @Query + @WhereQuery

EXEC SP_EXECUTESQL @Query
于 2020-01-08T07:24:45.047 回答
0

proc 中的整个查询需要是动态的。然后,您可以使用 STRING_SPLIT(2016 或更高版本)之类的东西来分离逗号分隔的值并构建字符串。但是,我不相信这就是您所需要的。如果你使用 LIKE,你将如何避免 %9% 匹配像 91 这样的值?

您可能需要考虑正确地规范化表。为什么单列中有 3 个年龄?为什么不将其存储为 3 行?

于 2020-01-08T06:56:01.707 回答