2016-07-23 18 views
2

私は統計的な追跡をしようとしています。私のデータベースでは、私は参照URLを格納しています。よく私は、次のようにURL年代を持っている:MYSQL:グループ正規表現パターン

http://www2.trafficadbar.com/__a4w4 
http://trafficadbar.com/__a4w4 
http://www.trafficadbar.com/__a4w4 
http://4acesmailer.com/credit_click.php?userid=2472&openkey=gbyp2vcm 
http://4acesmailer.com/credit_click.php?userid=2714&openkey=gbyp2vcm 
http://4acesmailer.com/credit_click.php?userid=2723&openkey=gbyp2vcm 
http://4acesmailer.com/credit_click.php?userid=3245&openkey=gbyp2vcm 
http://4acesmailer.com/credit_click.php?userid=3259&openkey=gbyp2vcm 

私はGROUP BYを行うと、正規表現パターンを頼りにする方法を知りたいです。基本的に私が欲しいのは返さ次のとおりです。私はそれ、GROUP BYを実行しようとする際のURLのは、全く同じでどこ

trafficadbar 3 
4acesmailer 5 

は現在のみ動作します。したがって、www.blah.comとblah.comは2つの異なる結果であり、それぞれのurl変数はさらに変わりますか?blah = 1 & blahblah = 2はまだユニークなグループとして機能します。尋ねられた問題に非常に特化していて、ほとんどすべては "正規表現ではない"回避策を示しているようです - 適用可能な方法が見つかったらうまくいくでしょう。

+0

私はこれを頻繁には言いませんが、おそらくすべてを選択してからPHPで解析する方がよいでしょう。 – AbraCadaver

+0

私は@AbraCadaverに同意します。私はPHPで解析を行います。 – BeetleJuice

答えて

1

トップレベルドメインのすぐ前の部分をホスト名から取得するには、次のように作業します。

SELECT 
    REVERSE(SUBSTRING(SUBSTRING_INDEX(rev_hostname, '.', 2), 
      LOCATE('.', rev_hostname) + 1) 
     ) domain 
    , COUNT(id) hits 
FROM (
    SELECT 
    id 
    , CONCAT(REVERSE(SUBSTRING_INDEX(SUBSTRING(referring_site, 8), 
            '/', 1)), '.') rev_hostname 
    FROM TestData 
) T 
GROUP BY domain 
; 

それを: - それはスタンドとして - 4acesmailer、例えば、のために//、および

  • が失敗します。

    • httpでオフを開始するために、すべてのreferring_site Sに依存しています。 co.uk

    必要に応じていずれかが(ある程度)対処することができます。

    は、(多少、いくつかのより多くのケースをカバーするように拡張/調整し、あなたのデータとの)アクションSQL Fiddleでそれを参照してください。

    調整が必要な場合は、コメントしてください。

  • 0

    あなただけのこれらの2つの値を気にしている場合、このような何かが働くだろう:

    select case when yourcolumn like '%trafficadbar%' then 'trafficadbar' 
          when yourcolumn like '%4acesmailer%' then '4acesmailer' 
         end, 
        count(*) 
    from yourtable 
    group by 1 
    

    編集、あなたのコメントを考えると、これはもう少しかもしれませんダイナミックで比較的容易に拡張できます:

    select 
        replace(replace(replace(
        left(yourcolumn, locate('.com', yourcolumn) - 1), 
        'http://', ''), 
        'www.', ''), 
        'www2.', ''), 
        count(*) 
    from yourtable 
    group by 1 
    
    +1

    私はそれらが例であると確信していて、彼らはすべてのドメイン名を前もって知っているわけではありません。 – AbraCadaver

    +0

    @AbraCadaver - OPが特定のドメインを検索している場合や、類似したドメインを何らかの形で集約したい場合は、明確な点ではありません。後でだけでは、SQLで可能だと思います...私のポストに「似ている」 – sgeddes

    +0

    その言葉は、確かに私は特にそれらを探しておりませんと言うことを意図していたしないでください - 簡単だろうという:) – Bruce

    0

    私は確実にすべてのSQLでこれを行うのに十分習熟していませんよ。あまりにも多くの可動部品があります:サブドメインの多く、可能なTLDのロット(だけではなく.com)、などの可能な不正なドメイン...

    私のアプローチは:すべてを選択して、PHPで解析します。

    以下の例では、URLがurls列にあり、各URLがDBに追加された日時を持つdate_added列があると仮定しています。それに応じてクエリを調整します。

    過去30日以内に追加されたすべてのURLを選択:あなたが与えた入力を使用すると、

    $rows = [...];//Associative array of all rows returned by the query above 
    $results = []; //will hold aggregate counts 
    
    foreach($rows as $row){ 
        $host = parse_url($row['urls'],PHP_URL_HOST); //eg: www2.trafficadbar.com 
        $matches = []; 
    
        //find top level domain or skip to next row 
        if(!preg_match('/[^\.]*\.[^\.]+$/',$host,$matches)) continue;   
    
        $domain = $matches[0]; //eg: trafficadbar.com 
    
        //increment the count for this domain in results 
        if(!isset($results[$domain])) $results[$domain]=0; 
        $results[$domain]++; 
    } 
    

    をしたいレポートを生成する工程、その後、$rowsアレイ内のすべての結果

    SELECT `urls` FROM `myTable` 
    WHERE `date_added` >= DATE_SUB(CURDATE(), INTERVAL 30 DAY) 
    

    場所をOPでは、$resultsは次のようになります。

    [ 
        'trafficadbar.com' => 3, 
        '4acesmailer.com' => 5, 
    ] 
    

    あなたは、 ebay.comebay.phは完全に異なるドメインなので、あなたと違ってTLD(例:.com.net ...)を保管しています。私は1つの結果にそれらをマッシュすることをお勧めします。

    Live demo

    +0

    いいです。しかし、単にループ内の配列に追加してから 'array_count values()'を使用してください。 – AbraCadaver

    +0

    配列を2回トラバースする(ドメインを追加するすべてのURL、次にすべての結果をカウントする)ので、一度だけ行う。 – BeetleJuice

    0

    @BeetleJuiceからの溶液を働いているだろう、と可能性をより確実に私が選んだ解決策よりも、私はそれが主演していない場合

    SELECT 
        CASE WHEN SUBSTRING(referring_site, 1, 8) = 'http://w' 
         THEN SUBSTRING_INDEX((SUBSTRING_INDEX(referring_site, '.', 2)), '.', -1) 
         ELSE SUBSTRING_INDEX((SUBSTRING_INDEX(referring_site, '.', 1)), '://', -1) 
        END 
    AS domain 
    FROM 
    .... 
    

    欠点があるSQLソリューションを選択しましたが、 http://wではなく、一部http://random.sub.domain

    +0

    誰かが純粋な純粋なmysqlソリューションを持っているなら、それは私が本当に好きなものです。最終的に私がしたいのは、 "。"の数を数えることです。 between://と/ then 2が最初のsubstring_indexを実行する場合は2番目にsubstring_indexを実行します。私はちょうど "。"の適切なカウントを取得して適用する方法を知らない – Bruce

    +0

    (i)再熟読するのは正しいですか?トップレベルドメイン(** com **、** org **など)より前の部分が必要ですか? (点数による判断は誤解を招く可能性があります:** abc.def.ghi.com **から何を得たいですか?)(ii)常にhttp ** **を開始していますか? – Abecee