Топ 10 встречающихся значений в таблице - PullRequest
1 голос
/ 14 декабря 2011

Я пытаюсь собрать SQL-запрос, чтобы собрать 10 самых популярных новостей за последнюю неделю.Мне также нужно, чтобы он фильтровал дублирующиеся IP-адреса, которые просматривали один и тот же элемент новостей.

Каждый раз, когда пользователь заходит на страницу, берется строка запроса браузера пользователя.
Вот пример настройки db:

datetime   | ipaddress     | querystring
-----------------------------------------
9/12/2011  | 65.65.65.651  | newsid=3512
9/12/2011  | 65.65.65.658  | newsid=3512
10/12/2011 | 65.65.65.653  | newsid=3514
11/12/2011 | 65.65.65.656  | newsid=3515
11/12/2011 | 65.65.65.651  | newsid=3515
13/12/2011 | 65.65.65.651  | newsid=3516
14/12/2011 | 65.65.65.650  | newsid=3516
14/12/2011 | 65.65.65.650  | newsid=3516

Моя неудачная попытка:

 SELECT DISTINCT TOP 10 ipaddress, querystring, Count(*) AS thecount
      FROM [thedb].[dbo].[tblwebstats] 
      WHERE querystring LIKE '%newsid=%' AND datetime > (1 week ago)
      GROUP BY querystring, ipaddress
      ORDER BY Count(*) DESC

Пожалуйста, помогите мне:)

Ответы [ 3 ]

1 голос
/ 14 декабря 2011

Как насчет этого?

select top 10 querystring, count(querystring) as popularity
from 
(
    select distinct ipaddress, querystring
    from 
    (
        select [datetime], ipaddress, querystring
        from tblwebstats
        where querystring LIKE '%newsid=%' AND [datetime] > dateadd(day, -7, getdate())
    ) as datefilter
) as distinctfilter
group by querystring
order by popularity desc

Этот запрос выполняет следующие действия (от самого внутреннего до самого внешнего):

  1. Фильтрация исходной таблицы по диапазону дат и строке запроса по необходимости
  2. Сокращает результаты с (1) до отдельных пар (IP-адрес, строка запроса), игнорируя дату
  3. Подсчитывает уникальные вхождения строки запроса из (2) и возвращает первые 10 из них в порядке убывания по количеству.
0 голосов
/ 14 декабря 2011

Не очень доволен утверждением ниже. Слишком много вложений без учета временных таблиц. Если вы перенесете данные в дополнительные временные таблицы, перекрестное применение будет менее тяжелым.

DECLARE @t as table(Created datetime,IPAddress varchar(15),QueryString VARCHAR(20))

INSERT INTO @t(Created,IPAddress,QueryString) VALUES
('2012-11-9' ,'65.65.65.651' ,'newsid=3512' ),
('2012-11-9','65.65.65.658','newsid=3512'),
('2012-11-10','65.65.65.653','newsid=3514'),
('2011-12-11','65.65.65.656','newsid=3515'),
('2011-12-11','65.65.65.651','newsid=3515'),
('2011-12-13','65.65.65.651','newsid=3516'),
('2011-12-14','65.65.65.650','newsid=3516'),
('2011-12-14','65.65.65.650','newsid=3516')

SELECT TOP 10 QueryString,DistinctIp,COUNT(1) Counter FROM (
SELECT DISTINCT Created,IPAddress,DistinctIp,QueryString
FROM @t t
CROSS APPLY (SELECT DISTINCT COUNT(1) DistinctIp FROM @t WHERE Created = t.Created ANd QueryString = t.QueryString) g
WHERE Created >= CAST((GETDATE()-7) AS DATE) AND
    QueryString LIKE '%newsid=%'
) x
GROUP BY QueryString,DistinctIp 
ORDER BY Counter DESC

Результат оператора будет содержать дополнительное количество различных IP-адресов.

QueryString|DistinctIp|Counter
newsid=3515|2|2
newsid=3512|2|2
newsid=3516|2|1
newsid=3516|1|1
newsid=3514|1|1
0 голосов
/ 14 декабря 2011

Я предполагаю, что когда вы говорите "... отфильтровать дублирующиеся IP-адреса ...", вы хотите, чтобы одна и та же новостная статья, запрошенная с того же IP-адреса, учитывалась один раз (в день?)

Если это так, вам нужно отфильтровать дубликаты, прежде чем получать статьи, попробуйте что-то вроде:

WITH Unique_Requests AS ( 
    SELECT DISTINCT datetime, ipaddress, querystring
    FROM [thedb].[dbo].[tblwebstats]
    WHERE datetime >= DATEADD(week, -1, CURRENT_TIMESTAMP) AND
        querystring LIKE '%newsid=%'
)

SELECT TOP 10 querystring, Count(*) AS thecount
FROM Unique_Requests
GROUP BY querystring
ORDER BY Count(*) DESC
...