2012-07-15 6 views
1

Je cherche un moyen de faire correspondre un ensemble de résultats à partir d'une plus grande liste d'autres résultats, et compte le nombre de correspondances. Par exemple:Groupe de variables SQL dans un autre groupe

J'ai un ensemble de résultats

Result 1 
sub1 
sub2 
sub3 

Result 2 
sub1 
sub2 
sub3 

Je dois trouver combien de fois soit un ensemble de résultats ci-dessus apparaît dans un ensemble de données beaucoup plus de résultats ci-dessous.

Result 1 
sub1 
sub2 
sub3 

Result 2 
sub1 
sub3 
sub4 

Result 2 
sub1 
sub2 
sub3 

Result 2 
sub1 
sub2 
sub3 
sub4 

Dans l'exemple ci-dessus, Résultat 1 du premier ensemble correspondrait le premier résultat dans le deuxième set, et Résultat 2 sélectionnne les 2 derniers résultats du deuxième ensemble, parce qu'ils contenaient tous les sous résultats de le premier ensemble. Donc le résultat 1 montrerait un nombre de fréquence de 1, alors que le résultat 2 montrerait un nombre de fréquence de 2.

Je suis plutôt nouveau avec SQL, mais je voudrais trouver une solution au problème ci-dessus.

données d'échantillon d'hier:

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 

je dois savoir combien de fois le groupe A Annonces 1-3 couru la semaine dernière, mais dire le lundi Groupe A couru annonces 1 et 3. Je Je ne veux pas que ce résultat soit renvoyé. Mardi Groupe A a couru les annonces 1, 2, 3, 4. Je Voudrais savoir ce résultat, mercredi Groupe A avait des annonces 1, 2, 3 courent, ceci encore je voudrais savoir.

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 

Ainsi, étant donné l'exemple, je pense voir ceci:

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 
+0

Quels sont les "sous"? Pouvez-vous poster des exemples de données et peut-être des résultats souhaités? –

+1

Pouvez-vous au moins publier un schéma pour que nous puissions travailler avec? Nous devons savoir comment les données sont représentées. Chaque groupe a-t-il son propre identifiant? Les ensembles sont-ils dans leurs propres tables ou sont-ils représentés par un identifiant? –

+0

@ZaneBien Les données d'échantillon seraient propriétaires, donc je ne peux pas les poster. Nous avons des séries d'annonces qui sont diffusées tous les jours. Ces annonces sont diffusées dans des groupes.Les «Résultats» dans l'exemple sont les groupes et les «sous-marins» sont les publicités dans les groupes. Toutes les annonces d'un groupe ne sont pas diffusées tous les jours. Parfois, les annonces sont ajoutées au groupe, parfois les annonces sont supprimées d'un groupe. J'ai besoin de savoir combien de fois dans une plage de dates spécifique, un ensemble donné d'annonces a couru dans un groupe particulier. –

Répondre

3

Il est un peu désordonné, mais voici ce que je pouvais venir avec:

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 

Je suis un peu trop fatigué pour écrire une explication, mais peut-être quand je me réveillerai demain, je continuerai ma réponse. Pour l'instant, vous pouvez voir un SQLFiddle Example. Notez que j'ai inséré quatre valeurs de plus que dans vos données d'exemple pour montrer comment la requête fonctionne lorsqu'un ensemble apparaît plus d'une fois par jour.

^Vous pouvez voir dans la deuxième requête exécutée que vous pouvez également filtrer la fréquence de l'ensemble apparaît chaque jour via HAVING COUNT(1) >= 2.

+0

'COUNT (CAS LORSQUE c.grp EST NULL ALORS 1 FIN) = 0' peut être simplifié à:' COUNT (*) = COUNT (c.grp) 'Ou peut-être le retirer complètement amke que' LEFT' rejoint un 'INNER 'un. –

+0

@ypercube, bon point, merci. Il a besoin de toute la simplification qu'il peut utiliser. –

+0

C'est génial! Existe-t-il un moyen d'ajouter un peu plus d'automatisation à cela? Je pensais quelque chose comme Select * à partir de la table où date = hier GROUP BY date, groupe, annonce ... puis avoir le résultat de cette requête nourrir la recherche pour le reste de la semaine. Les ensembles de données que je regarde auront plusieurs dizaines de milliers d'annonces diffusées quotidiennement. En outre, il n'y aura pas toujours exactement 3 annonces dans un groupe, parfois il y en aura une, parfois 2, 3, 4, 5 ou plus. Merci encore! –

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 
0

Peut-être que vous pourriez trier et transposer:

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; 

Vous aurez une ligne par jour. Si nécessaire, vous pouvez fusionner ceci sur vos données d'origine:

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