2010-01-17 4 views
3

J'ai besoin d'écrire des requêtes pour trouver nouveaux utilisateurs et utilisateurs réguliers.Trouver des utilisateurs de la table qui existait il y a plus de 24 heures

nouveaux utilisateurs sont ceux dont UUID apparus dans les dernières 24 heures (à partir de maintenant moins la requête de temps est tiré) dans table2 et n'a pas été là avant.

les utilisateurs réguliers sont ceux dont l'uuid est apparu au dernier jour dans table2 et y était également au moins une fois au cours des 3 derniers jours. En outre, seuls les enregistrements avec id > 10 et ip != 2 doivent être pris en compte.

table1 est une table temporaire contenant des dates. Je ne suis pas capable de comprendre comment y parvenir avec l'aide de jointures. Aidez-moi, s'il vous plaît.


table2

 
    +----+---------------------+------+------+ 
    | id | ts     | uuid | ip | 
    +----+---------------------+------+------+ 
    | 1 | 2010-01-10 00:00:00 | uid1 | 5 | 
    | 2 | 2010-01-10 00:00:00 | uid2 | 14 | 
    | 3 | 2010-01-10 00:00:00 | uid3 | 11 | 
    | 4 | 2010-01-11 00:00:00 | uid4 | 16 | 
    | 5 | 2010-01-11 00:00:00 | uid5 | 4 | 
    | 6 | 2010-01-13 00:00:00 | uid6 | 2 | 
    | 7 | 2010-01-10 00:00:00 | uid1 | 1 | 
    | 8 | 2010-01-11 00:00:00 | uid2 | 10 | 
    | 9 | 2010-01-12 00:00:00 | uid1 | 1 | 
    | 10 | 2010-01-13 00:00:00 | uid4 | 1 | 
    | 11 | 2010-01-09 21:00:00 | uid1 | 1 | 
    | 12 | 2010-01-09 21:30:00 | uid1 | 2 | 
    | 13 | 2010-01-10 05:00:00 | uid2 | 3 | 
    | 14 | 2010-01-10 12:00:00 | uid1 | 1 | 
    | 15 | 2010-01-10 12:00:00 | uid3 | 1 | 
    | 16 | 2010-01-10 21:00:01 | uid1 | 7 | 
    | 17 | 2010-01-11 01:00:00 | uid2 | 14 | 
    | 18 | 2010-01-11 05:00:00 | uid2 | 11 | 
    | 19 | 2010-01-11 17:59:00 | uid4 | 13 | 
    | 20 | 2010-01-11 06:00:00 | uid5 | 12 | 
    | 21 | 2010-01-11 18:01:00 | uid1 | 14 | 
    | 22 | 2010-01-12 23:05:00 | uid4 | 17 | 
    | 23 | 2010-01-13 12:01:23 | uid6 | 13 | 
    +----+---------------------+------+------+ 
    23 rows in set (0.00 sec) 

table1

 
    +------------+ 
    | ts   | 
    +------------+ 
    | 2010-01-10 | 
    | 2010-01-11 | 
    | 2010-01-12 | 
    | 2010-01-13 | 
    +------------+ 
    4 rows in set (0.00 sec) 

sortie en cas de nouveaux utilisateurs prises à 18:00

+------------+-------+ 
| ts   | users | 
+------------+-------+ 
| 2010-01-10 |  3 | 
| 2010-01-11 |  2 | 
| 2010-01-12 |  0 | 
| 2010-01-13 |  1 | 
+------------+-------+ 
4 rows in set (0.00 sec) 

table MySQL décharge

DROP TABLE IF EXISTS `table1`; 
/*!40101 SET @saved_cs_client  = @@character_set_client */; 
/*!40101 SET character_set_client = utf8 */; 
CREATE TABLE `table1` (
    `ts` date NOT NULL 
) ENGINE=MyISAM DEFAULT CHARSET=latin1; 
/*!40101 SET character_set_client = @saved_cs_client */; 

INSERT INTO `table1` VALUES ('2010-01-10'),('2010-01-11'),('2010-01-12'),('2010-01-13'); 

DROP TABLE IF EXISTS `table2`; 
CREATE TABLE `table2` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `ts` datetime DEFAULT NULL, 
    `uuid` varchar(20) DEFAULT NULL, 
    `ip` int(11) DEFAULT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=MyISAM AUTO_INCREMENT=24 DEFAULT CHARSET=latin1; 
/*!40101 SET character_set_client = @saved_cs_client */; 

INSERT INTO `table2` VALUES (1,'2010-01-10 00:00:00','uid1',5),(2,'2010-01-10 00:00:00','uid2',14),(3,'2010-01-10 00:00:00','uid3',11),(4,'2010-01-11 00:00:00','uid4',16),(5,'2010-01-11 00:00:00','uid5',4),(6,'2010-01-13 00:00:00','uid6',2),(7,'2010-01-10 00:00:00','uid1',1),(8,'2010-01-11 00:00:00','uid2',10),(9,'2010-01-12 00:00:00','uid1',1),(10,'2010-01-13 00:00:00','uid4',1),(11,'2010-01-09 21:00:00','uid1',1),(12,'2010-01-09 21:30:00','uid1',2),(13,'2010-01-10 05:00:00','uid2',3),(14,'2010-01-10 12:00:00','uid1',1),(15,'2010-01-10 12:00:00','uid3',1),(16,'2010-01-10 21:00:01','uid1',7),(17,'2010-01-11 01:00:00','uid2',14),(18,'2010-01-11 05:00:00','uid2',11),(19,'2010-01-11 17:59:00','uid4',13),(20,'2010-01-11 06:00:00','uid5',12),(21,'2010-01-11 18:01:00','uid1',14),(22,'2010-01-12 23:05:00','uid4',17),(23,'2010-01-13 12:01:23','uid6',13); 
+0

Maintenant * c'est * comment poser une question DB. Effacer, avec des exemples de données prêts à copier-coller. –

+0

Excepté: À quoi sert 'table2'? Est-ce pour limiter la plage de dates pour laquelle vous obtenez cette info? –

+0

En fait, vous avez mal étiqueté vos tables. Quel est le tableau des dates (table2 dans votre texte, table1 dans l'échantillon) pour? –

Répondre

2

Vous pouvez vous joindre à la table sur elle-même pour rechercher des entrées pour le même utilisateur qui sont plus d'un jour vieux. Lorsqu'il n'y a pas de correspondance d'un jour, les champs de la table jointe gauche seront NULL.

Par exemple:

select  
    YEAR(cur.ts) as year 
, MONTH(cur.ts) as month 
, DAY(cur.ts) as day 
, case when old.uuid is null then 1 else 0 end as IsNewUser 
, count(distinct cur.uuid) as Users 
from  table2 cur 
left join table2 old 
on   cur.uuid = old.uuid 
      and old.ip <> 2 
      and old.id > 10 
      and cur.ts - old.ts > 1 
where  cur.ip <> 2 
      and cur.id > 10 
group by year, month, day, IsNewUser 
order by year, month, day, IsNewUser 
+0

Est-ce que cela fonctionne sur votre configuration? Sur la mienne, même si je change 'timestamp' en' ts' (pour correspondre à l'original), je reçois toujours "ERROR 1054 (42S22): Colonne inconnue 'old.uuid' dans 'liste des champs'". –

+0

@ T.J. Crowder: Je l'ai tapé dans ma tête, j'ai changé table1 et table2. Édité avec une meilleure version, bien que le résultat soit encore différent de l'exemple de réponse dans la question. – Andomar

+0

oui cela fonctionne sur ma machine. Mais pas capable de comprendre comment je le change à mes exigences :( – Amit

1

Je ne suis pas tout familier avec MySQL, mais voici comment je le ferais dans Oracle:

SELECT uuid, 'NEW' as user_type FROM 
    (SELECT uuid, MAX(ts) as MAX_TS, MIN(ts) as MIN_TS 
    FROM TABLE2 
    WHERE ID > 10 AND 
      IP <> 2 
    GROUP BY uuid 
    HAVING MAX_TS > SYSTIMESTAMP - INTERVAL '1' DAY AND 
      MAX_TS = MIN_TS) nu 
UNION ALL 
    SELECT DISTINCT uuid, 'REGULAR' as user_type FROM 
    (SELECT uuid, MAX(ts) as MAX_TS 
     FROM TABLE2 
     WHERE ID > 10 AND 
      IP <> 2 
     GROUP BY uuid) n 
    INNER JOIN (SELECT * 
        FROM TABLE2 
        WHERE ID > 10 AND 
          IP <> 2) t 
     ON (t.uuid = n.uuid) 
    WHERE n.MAX_TS > SYSTIMESTAMP - INTERVAL '1' DAY AND 
      t.ts < SYSTIMESTAMP - INTERVAL '1' DAY AND 
      t.ts > SYSTIMESTAMP - INTERVAL '3' DAY; 

Je ne peux pas vraiment voir une utilisation pour TABLE1 ici. Est-il nécessaire que vous l'utilisiez? Je ne sais pas si MySQL supporte SYSTIMESTAMP ou la construction INTERVAL. J'espère que cela vous donnera quelques idées.

+0

dans la table1, il peut y avoir des jours où il n'y a pas d'entrée du tout.Selon table1 est utilisé comme une graine pour les dates, et le nombre d'utilisateurs est calculé sur toutes ces dates sont dans la table2. – Amit

Questions connexes