另一组中的SQL变量组

时间:2012-07-15 03:38:13

标签: mysql sql dataset sas

我正在寻找一种方法来匹配来自更大的其他结果列表的一组结果,并计算匹配的数量。例如:

我有一组结果

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个结果,因为它们包含第一组中的所有子结果。因此,结果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

我需要了解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

3 个答案:

答案 0 :(得分: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 Example 。请注意,我已经插入了比示例数据中多四个值的值,以展示当一个集合每天出现多次时查询的工作方式。

^您可以在第二个执行的查询中看到,您还可以通过HAVING COUNT(1) >= 2过滤每天出现的频率。

答案 1 :(得分: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

答案 2 :(得分: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;

每个日期您将有一行。如果需要,您可以将其重新合并到原始数据中:

data mydata4;
  merge mydata1 mydata3;
  by group date;
run;