根据LIKE向列添加值

时间:2017-07-05 12:12:11

标签: sql sql-server

我有SSMS 2008 R2。这是我的表

PK | DateOf           | Other Columns | Items
01 | 05/30/2017 15:30 | Blah          | truck, elephant, apple, . . .
02 | 04/15/2012 07:07 | Bluh          | foot, orange, horse, . . .
03 | 11/01/2016 10:30 | Wham          | apple, screen, penny, . . .

我正在尝试搜索每个记录的Items列,并计算水果出现的次数。方便的是,每个记录只会有一个水果,但如果解决方案能够处理多个水果(甚至可能重复),那将会很酷。对于上面的

,结果表看起来像这样
Count | Fruit
2     | Apple
1     | Orange

我有一份完整的“水果”清单。我试图弄清楚如何使它与LIKE一起使用。

SELECT
count(PK) AS [Count]
??? AS [Fruit]
WHERE DateOf >= '2011-01-01 00:00' AND DateOf < '2012-01-01 00:00'
AND Items LIKE '%Apple%' --??(some kind of code that looks for the fruit values??)

3 个答案:

答案 0 :(得分:2)

这是存储列表的错误方法。但是,有时我们会遇到其他人非常糟糕的设计决策。

在这种情况下,您需要split()功能。 SQL Server 2016提供了一个。您还可以在网络上找到一个代码(Google“SQL Server拆分字符串”):

SELECT ss.fruit, count(*) AS [Count]
FROM t CROSS APPLY
     string_split(t.items) ss(fruit)
WHERE DateOf >= '2011-01-01' AND DateOf < '2012-01-01'
GROUP BY ss.fruit;

答案 1 :(得分:0)

如果您有水果桌,您可以使用简单的外部申请来识别水果。像这样:

drop table if exists dbo.Details;
drop table if exists dbo.Fruits;

create table dbo.Details (
    PK int not null primary key
    , DateOf datetime2(3)
    , Items varchar(100)
);

create table dbo.Fruits (
    Fruit varchar(100) not null primary key
);

insert into dbo.Details (PK, DateOf, Items)
values (1, '20170530 15:30', 'truck, elephant, apple, . . .')
    , (2, '20120415 07:07', 'foot, orange, horse, . . .')
    , (3, '20161101 10:30', 'apple, screen, penny, orange, . . .')

insert into dbo.Fruits (Fruit)
values ('apple'), ('orange');

select
    d.PK, d.DateOf, d.Items, count(*) as CountOfFruit
from dbo.Details d
    outer apply (
            select
            *
            from dbo.Fruits f
            where d.Items like '%' + f.Fruit + '%'
    ) tf
group by d.PK, d.DateOf, d.Items

答案 2 :(得分:0)

试试这可能会对你有所帮助

IF OBJECT_ID('Tempdb..#Temp') IS NOT NULL
DROP TABLE #Temp

DECLARE @SearchWords nvarchar(max)='Apple,Orange'

DECLARE @Table TABLE (SearchWords nvarchar(max))
INSERT INTO @Table
SELECT @SearchWords

;With cte_Search
AS
(
SELECT  ROW_NUMBER()OVER(ORDER BY (SELECT 1) )AS Seq, 
        Split.a.value('.', 'VARCHAR(1000)') AS SearchWords
            FROM (
                SELECT
                     CAST('<S>' + REPLACE(SearchWords, ',', '</S><S>') + '</S>' AS XML) AS SearchWords
                FROM @Table
                ) AS A
            CROSS APPLY SearchWords.nodes('/S') AS Split(a)

)
SELECT * INTO #Temp  FROM cte_Search


;With CTE (PK , DateOf , OtherColumns , Items)
AS
(
SELECT 01 , '05/30/2017 15:30' ,'Blah', 'truck, elephant, apple'UNION ALL
SELECT 02 , '04/15/2012 07:07' ,'Bluh', 'foot, orange, horse'   UNION ALL
SELECT 03 , '11/01/2016 10:30' ,'Wham', 'apple, screen, penny'
)
SELECT SearchWords AS Fruit,
        MAX(Seq) AS CountOFFruits FROM
(
SELECT C.OtherColumns,
        t.SearchWords,
        C.Items,
        COUNT(C.Items) CntItems,
        ROW_NUMBER()OVER(Partition by t.SearchWords order by  C.OtherColumns ) AS Seq
         FROM CTE c ,#Temp t
WHERE CHARINDEX(t.SearchWords,c.Items) >0
Group by C.OtherColumns,t.SearchWords,C.Items
)dt
Group by SearchWords

结果

Fruit   CountOFFruits
----------------------
Apple   2
Orange  1