1

SQLクエリをまとめて、過去1週間に注目されたニュースのトップ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

私を助けてください :)

4

3 に答える 3

1

このようなものはどうですか?

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を返します。
于 2011-12-14T00:46:38.130 に答える
0

以下のステートメントにはあまり満足していません。一時テーブルを使用せずにネストが多すぎます。データを追加の一時テーブルに取り込むと、クロスアプライはそれほど重くなりません。

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
于 2011-12-14T01:36:54.860 に答える
0

「...重複するIPアドレスをフィルタリングする...」と言うときは、同じIPアドレスから要求された同じニュース記事だけを1回(1日あたり?)カウントしたいと思います。

その場合、記事を取得する前に重複をフィルタリングする必要がある場合は、次のようにしてみてください。

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
于 2011-12-14T00:44:25.480 に答える