从Select语句的结果中返回前三个发生的字符串

时间:2016-11-10 14:44:10

标签: tsql sql-server-2008-r2

我有一个包含三列的表格。第一列是PK。第二列包含5个不同的URL(URL是进程中的步骤,一个URL表示步骤#1等)。第三列包含User-Agent字符串。

SELECT * FROM UserAgent WHERE URL LIKE '%Step2%' ORDER BY UserAgentString;

我想根据特定步骤中出现的次数返回前三个User-Agent字符串。我该怎么做?

如果有更好的方法来查询所需的结果集,我可以提出任何建议。

2 个答案:

答案 0 :(得分:1)

试试这个

WITH CTE AS(
       SELECT Col1,Col2,Col3,LEN(Col2)-LEN(REPLACE(Col2,Col3,'')) Occurance 
       FROM UserAgent  
)
SELECT TOP (3) Col1,Col2,Col3
FROM CTE
ORDER BY Occurance   

答案 1 :(得分:0)

JayDipJ发布的内容效率很高,但只有在col3的长度为1时才有效。看看这个示例代码:

-- Sample data:
DECLARE @userAgent TABLE (col2 varchar(100), url varchar(100));
INSERT @userAgent VALUES 
('dog','this dog, that dog... Dogs?'),
('cat','cats, cats, cats and more cats'),
('bird', 'bird, bird!'),
('xxx', 'xxx yyy zzz');

-- solution:
SELECT TOP (3) *, Occurances = (LEN(url) - LEN(REPLACE(url,col2,''))) / LEN(col2)
FROM @userAgent
ORDER BY (LEN(url) - LEN(REPLACE(url,col2,''))) / LEN(col2) DESC;

但要注意的是,如果存在任何重叠值,此方法将失败。例如字符串" .."在这里出现了四次:" ...... ...&#34 ;;上述方法会返回错误的答案。如果可能存在重叠,我会使用Ngrams8K(http://www.sqlservercentral.com/articles/Tally+Table/142316/)。 NGrams8K解决方案看起来像这样:

-- sample data with overlapping values:
DECLARE @userAgent TABLE (col2 varchar(100), url varchar(100));
INSERT @userAgent VALUES ('..', 'blah... blah...'), ('!!', 'Fantastic!!!'),('xx','abc');

-- solution:
SELECT url, Occurances = COUNT(*)
FROM @userAgent
CROSS APPLY dbo.NGrams8k(url, LEN(col2))
WHERE token = col2
GROUP BY ALL url;

结果:

url               Occurances
----------------- -----------
abc               0
blah... blah...   4
Fantastic!!!      2