T-SQL左连接与Like运算符

时间:2014-03-19 20:15:38

标签: tsql sql-server-2008-r2 left-join

我正在创建一个包含3列的报告:

搜索字词,搜索字词数,搜索字词是否为标记?

以下是示例输出:

Search Phrase   Count   Is Tag
V7000           507     Yes
SPSS            370     No
unica           282     Yes

我可以毫不费力地完成前2个请求。这是标记的比较搜索术语,这让我感到悲痛。如果标记名称中存在整个短语,则搜索项是标记。我在下面举几个例子。

确定搜索词是否为标记的示例:

Search Phrase       Tag             Is Tag?
CLM Dashboard       CLM             No
Dashboards          Dashboard       Yes
Dashboard           CLM Dashboard`  Yes
unica               Communication   Yes
XX                  XX Cool Name    Yes
ABC Tech Company    ABC             No 

我的攻击计划是在search_term如tag_name

的情况下进行左连接

但是有一些问题:

问题1:我的代码中有超过100行返回(即使我有TOP(100))列表 目前它为搜索词日语显示两行,因为有两个标签,日本和日语。我不关心搜索词与哪个标记匹配,只要匹配。我认为这与我的Left Join like子句直接相关。

问题2:“ABC Tech Company”应该失败 目前ABC Tech Company在失败时显示“是”。这是因为“ABC Tech Company”中的“ABC”出现在标签名称“ABC”中。我希望这返回null,因为整个短语“ABC Tech Company”不在任何标记中

问题3:“unica”应该匹配,因为该短语位于“Communication”标签内。 “XX”应匹配“XX Cool Name”标签。
目前unica不匹配(也不是XX)。我不知道为什么这不起作用

总的来说,我的问题似乎源于没有正确实现我的LEFT JOIN LIKE情况。

这就是我现在所拥有的:

DECLARE @startDate DATETIME2 = '2013-01-01'
DECLARE @endDate DATETIME2 = '2013-08-22'

;WITH Top100Searches AS
(
    Select TOP (100)
        SearchDim.criteria_keywords as SearchTerm, COUNT(SearchDim.created_date) as SearchPhraseCount
    From
        search_dimension SearchDim
    Where
        SearchDim.created_date > @startDate
        and SearchDim.created_date < @endDate
    Group by
        SearchDim.criteria_keywords
    Order by
        SearchPhraseCount DESC
)

Select
    Top100Searches.SearchTerm, Top100Searches.SearchPhraseCount,CASE WHEN TagDim.name IS NOT NULL THEN 'Yes' ELSE 'No' END AS 'Is Tag?'
From
    Top100Searches
LEFT JOIN
    (
        Select TagDim.name
        From tag_dimension TagDim
    ) as TagDim on 
    --This is where I'm having trouble
    Top100Searches.SearchTerm like '%' + TagDim.name + '%'
Order by
    Top100Searches.SearchPhraseCount DESC

如果我能澄清任何事情,请告诉我,我已尽力清楚地解释一切。

2 个答案:

答案 0 :(得分:1)

以下是问题3的答案,尽管搜索术语是一种可怕的方式。您应该考虑(如果可能)在C#中使用RegEx进行此操作。

DECLARE @JUNKYWORDS TABLE
( 
 junkWord VARCHAR(400)
)

DECLARE @TAGS TABLE
(
TAGNAME VARCHAR(30),
YESORNO VARCHAR(1)
)
INSERT INTO @JUNKYWORDS VALUES ('I love buttons')
INSERT INTO @JUNKYWORDS VALUES ('I lost a button')
INSERT INTO @JUNKYWORDS VALUES ('pizza')

INSERT INTO @TAGS VALUES ('to','Y')
INSERT INTO @TAGS VALUES ('zz','N')

SELECT TAGNAME, YESORNO, COUNT(*)
FROM @JUNKYWORDS,@TAGS
WHERE JunkWord LIKE '%' + TAGNAME + '%'
GROUP BY TAGNAME, YESORNO

答案 1 :(得分:1)

我实际上找到了自己的解决方案。

有两件事:1。)首先,我在LEFT JOIN上错误地使用LIKE。在外行人看来,我说'#34;沟通&#39;在&#39; unica&#39;?&#34;相反,我想要相反,所以交换我的连接标准解决了问题2和3。


2.)一旦我做了这个改变,现在根据应用于许多标签的搜索项的数量有重复。虽然我尽力从不使用DISTINCT,因为它通常意味着您已经错误地写了您的查询,这次没有办法解决它。所以添加DISTINCT让我回到了预期的100行,解决了问题1。

总结一下,我的LEFT JOIN条件被颠倒了,我需要添加DISTINCT以使我的查询起作用。

我希望这可以帮助其他人!

Select DISTINCT --#adding Distinct is change #2
    Top100Searches.SearchTerm, Top100Searches.SearchPhraseCount,CASE WHEN TagDim.name IS NOT NULL THEN 'Yes' ELSE 'No' END AS 'Is Tag?'
From
    Top100Searches
LEFT JOIN
    (
        Select TagDim.name
        From tag_dimension TagDim
    ) as TagDim on
    --This is change #1
    TagDim.name LIKE '%' + Top100Searches.SearchTerm + '%'
Order by
    Top100Searches.SearchPhraseCount DESC