我有一个包含三列的表格。第一列是PK。第二列包含5个不同的URL(URL是进程中的步骤,一个URL表示步骤#1等)。第三列包含User-Agent字符串。
SELECT * FROM UserAgent WHERE URL LIKE '%Step2%' ORDER BY UserAgentString;
我想根据特定步骤中出现的次数返回前三个User-Agent字符串。我该怎么做?
如果有更好的方法来查询所需的结果集,我可以提出任何建议。
答案 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