1

他の結果のより大きなリストからの結果のセットを一致させ、一致の数を数える方法を探しています。例えば:

一連の結果があります

Result 1
sub1
sub2
sub3

Result 2
sub1
sub2
sub3

上記の結果のいずれかのセットが、以下の結果のはるかに大きなデータセットに何回表示されるかを見つける必要があります。

Result 1
sub1
sub2
sub3

Result 2
sub1
sub3
sub4

Result 2
sub1
sub2
sub3

Result 2
sub1
sub2
sub3
sub4

上記の例では、最初のセットの結果1は2番目のセットの最初の結果と一致し、結果2は2番目のセットの最後の2つの結果と一致します。これは、最初のセットのすべてのサブ結果が含まれているためです。したがって、結果1は頻度カウント1を示し、結果2は頻度カウント2を示します。

私はSQLにかなり慣れていませんが、上記の問題の解決策を見つけたいと思います。

昨日のサンプルデータ:

Group    Ad   Date
A        1    7/14
A        2    7/14
A        3    7/14
B        1    7/14
B        2    7/14
B        3    7/14
B        4    7/14
C        1    7/14
D        1    7/14
D        3    7/14
D        4    7/14

過去1週間にグループAの広告1〜3が何回実行されたかを調べる必要がありますが、月曜日にグループAは広告1と3のみを実行したと言います。この結果を返したくありません。火曜日のグループAは広告1、2、3、4を実行しました。私はこの結果を知りたいと思います。水曜日のグループAは広告1、2、3を実行しました、これもまた知りたいと思います。

Group    Ad   Date
A        1    7/09
A        3    7/09
A        1    7/10
A        2    7/10
A        3    7/10
A        4    7/10
A        1    7/14
A        2    7/14
A        3    7/14

したがって、例を考えると、私はこれを見ることを期待します:

Group    Ad   Date
A        1    7/10
A        2    7/10
A        3    7/10
A        1    7/14
A        2    7/14
A        3    7/14
4

3 に答える 3

3

少し面倒ですが、これが私が思いついたものです:

SELECT a.*, b.*
FROM 
(
    SELECT 'A' AS grp, 1 AS ad UNION ALL
    SELECT 'A', 2 UNION ALL
    SELECT 'A', 3
) a 
CROSS JOIN
(
    SELECT DISTINCT date
    FROM tbl
    WHERE date >= CURDATE() - INTERVAL 1 WEEK
) b
LEFT JOIN tbl c ON a.grp = c.grp
               AND a.ad = c.ad
               AND b.date = c.date
INNER JOIN
(
    SELECT a.date
    FROM 
    (
        SELECT 'A' AS grp, 1 AS ad UNION ALL
        SELECT 'A', 2 UNION ALL
        SELECT 'A', 3
    ) a 
    CROSS JOIN
    (
        SELECT DISTINCT date
        FROM tbl
        WHERE date >= CURDATE() - INTERVAL 1 WEEK
    ) b
    LEFT JOIN tbl c ON a.grp = c.grp
                   AND a.ad = c.ad
                   AND b.date = c.date
    GROUP BY a.date
    HAVING COUNT(1) = COUNT(c.grp)
) d ON b.date = d.date

少し疲れて説明が書けませんが、明日目が覚めたら答えを続けます。

今のところ、 SQLFiddleの例を表示できます。セットが1日に複数回表示される場合にクエリがどのように機能するかを示すために、サンプルデータよりも4つ多くの値を挿入したことに注意してください。

^ 2番目に実行されたクエリで、セットが毎日表示される頻度を。を介してフィルタリングできることがわかりますHAVING COUNT(1) >= 2

于 2012-07-15T10:40:33.427 に答える
0

SAS SQLの場合:

    proc sql;
    CREATE TABLE tbl (
      grp CHAR(1),
      ad INT,
      date DATE
    );

    INSERT INTO tbl 
    values('A', 1, '09jul2012'd) 
    values('A', 3, '09jul2012'd) 
    values('A', 1, '10jul2012'd) 
    values('A', 2, '10jul2012'd)
    values('A', 3, '10jul2012'd) 
    values('A', 4, '10jul2012'd) 
    values('A', 1, '14jul2012'd) 
    values('A', 2, '14jul2012'd) 
    values('A', 3, '14jul2012'd) 
    values('A', 1, '14jul2012'd) 
    values('A', 2, '14jul2012'd) 
    values('A', 3, '14jul2012'd) 
    ;
    quit;

    proc sql noprint; /* the set and upper date I'm interested in */
    CREATE TABLE my_set (
      grp CHAR(1),
      ad INT,
      date DATE
    );

    INSERT INTO my_set (grp, ad)
    VALUES ('A', 1)
    VALUES ('A', 2)
    VALUES ('A', 3)
    ;
    update my_set set date=today()-1;
    select count(*) into :my_set_size from my_set
    ;
    quit;

    proc sql;
    create table potential_dates as
     select t.date, s.grp, s.ad, count(*) as ad_occurrence
    from my_set s
     inner join tbl t 
        on s.grp = t.grp and s.ad = t.ad and s.date >= t.date
     group by t.date, s.grp, s.ad
    ;
    quit;

    proc sql;
        create table result as
            select a.* from potential_dates a
             inner join (select date from potential_dates
                        group by date
                        having count(*) = &my_set_size ) d
            on a.date = d.date
    ;
    quit;


 date     grp        ad  ad_occurrence
 10JUL12  A           1              1
 10JUL12  A           2              1
 10JUL12  A           3              1
 14JUL12  A           1              2
 14JUL12  A           2              2
 14JUL12  A           3              2
于 2012-07-15T17:53:16.240 に答える
0

多分あなたはソートして転置することができます:

proc sort data=mydata1;
  by group date;
run;

proc transpose data=mydata1 out=mydata2;
  by group date;
  var ad;
run;

data mydata3;
  set mydata2;
  if not missing(col1,col2,col3);
run;

日付ごとに1つの行があります。必要に応じて、これを元のデータにマージして戻すことができます。

data mydata4;
  merge mydata1 mydata3;
  by group date;
run;
于 2012-07-15T22:30:22.980 に答える