8722 sujets

Développement web côté serveur, CMS

Bonjour,


j'aimerais faire une requête sql qui me récupère les enregistrements qu'il y a eu le même jours

J'ai une table passage qui enregistre les passages d'une déchetterie.
Pour chaque utilisateur, je souhait rechercher tous les passages mais j'aimerais récupérer les passages uniquement si pour le même jour j'ai un enregistrement qui a un intervalle <= à 15min
et ça sur une année entière.

Est ce que je dois le faire en plusieurs étapes?
Bonjour,

cid5420 a écrit :
uniquement si pour le même jour j'ai un enregistrement qui a un intervalle &lt;= à 15min

Peux-tu clarifier ce point ? Qu'appelles-tu un intervalle ? Temps entre deux passages pour le même utilisateur ?
Dans ma table passage j'ai plusieurs enregistrements où la dateNow() est enregistré lors du passage.
Lorsqu'un utilisateur fait un passage, celui-ci est enregistrer, le même utilisateur peut passer plusieurs foi le même jour.

moi je voudrais récupérer les enregistrement où j'ai plusieurs passages pour le même jour et où les date de passage ont un intervalle entre les passages inférieur à 15 min

Je ne connais pas le jou. donc pour toute l'année en cours,
sélectionne moi tous les passages de l'utilisateur pour lequel il y a un passage le même jour avec un intervalle inférieur à 15 min entre 2 passages.
Je ne suis pas sûr d'être correct sur un grand nombre de données, à tester donc, mais une première approche pourrait être :
SELECT DISTINCT
	P1.id_utilisateur,
	DATE_FORMAT ( P1.date_passage , '%d %m %y' ) AS date_passage
FROM
	passages P1
		INNER JOIN passages P2
			-- Pour un même utilisateur
			ON P1.id_utilisateur = P2.id_utilisateur
			-- Pour des passages différents
			AND P1.id_passage != P2.id_passage
			-- Pour la même date
			AND DATE_FORMAT ( P1.date_passage , '%y%m%d' ) = DATE_FORMAT ( P2.date_passage , '%y%m%d' )
			-- Pour des passages espacés de moins de 15 minutes
			AND P1.date_passage < P2.date_passage + INTERVAL 15 MINUTE

Et la requête en test sur SQLFiddle.
Merci pour ton aide,

pour ta requête, il y a juste un problème c'est que voudrais exclure tous les passages où il n'y en as 1

exemple:
Habitant : 12 Passage : 2014-02-07 15:37:44

Habitant : 12 Passage : 2014-02-07 15:37:41

Habitant : 18 Passage : 2014-05-16 11:02:30

Habitant : 18 Passage : 2014-05-16 11:02:26

Habitant : 20 Passage : 2014-03-17 16:17:59

Habitant : 20 Passage : 2014-03-17 16:17:56

Habitant : 23 Passage : 2014-03-27 09:59:22

Habitant : 23 Passage : 2014-03-27 09:59:19

Habitant : 25 Passage : 2014-04-18 14:36:23

Habitant : 30 Passage : 2013-12-20 16:59:13

Habitant : 30 Passage : 2013-12-20 16:50:23

Habitant : 30 Passage : 2013-12-20 16:50:11

Si tu regarde l'habitant 25, je n'ai qu'un passage.

Sinon ça fonctionne pour le reste

Voici le code adapté à ma situation.
<?php
try
{
	$cnx = new PDO('mysql:host=localhost;dbname=smtom', 'root', '');
}catch(Exception $e)
{
	die('Erreur : '.$e->getMessage());
}
$h = $cnx->query("SELECT DISTINCT
	P1.habitant,
	P1.datetime
FROM
	`dechetterie_passages` P1
		INNER JOIN `dechetterie_passages` P2
			-- Pour un même utilisateur
			ON P1.habitant = P2.habitant
			-- Pour des passages différents
			AND P1.id != P2.id
			-- Pour la même date
			AND DATE_FORMAT ( P1.datetime , '%y%m%d' ) = DATE_FORMAT ( P2.datetime , '%y%m%d' )
			-- Pour des passages espacés de moins de 15 minutes
			AND P1.datetime < P2.datetime + INTERVAL 15 MINUTE ORDER BY habitant, datetime DESC");
while($row = $h->fetch(PDO::FETCH_ASSOC))
{
	echo "Habitant : ".$row["habitant"]." Passage : ".$row["datetime"]."<br><br>";
}

?>
Bon en scrutant les résultats (plusieurs centaines)

Je me demande si je n'affiche pas tous les passages.

car les passages sont bien ordonné par habitant mais j'affiche les passages pour un jour différent
Tu as raison, cela ne fonctionne pas ... Smiley confused
Dans la jointure on précise date2 < date1 + 15 minutes, mais il faut aussi que date2 > date1 ...

Par contre, il faut bien préciser le DATE_FORMAT dans le SELECT sinon tu regroupes par datetime et non par date ...

Du coup, corrigé cela devient :
SELECT
  P1.habitant,
  DATE_FORMAT ( P1.datetime, '%d/%m/%Y' ) AS jour_passage,
  COUNT(P1.id) AS nombre
FROM
  passages P1
    INNER JOIN passages P2
      -- Pour le même habitant
      ON P1.habitant = P2.habitant
      -- Pour un passage différent
      AND P1.id != P2.id
      -- Pour deux passages espacés de moins de 15 minutes
      AND P2.datetime > P1.datetime
      AND P2.datetime < P1.datetime + INTERVAL 15 MINUTE
GROUP BY
  P1.habitant,
  jour_passage
ORDER BY
  P1.habitant


Et le SQLFiddle actualisé Smiley cligne
Modifié par Benzouye (23 May 2014 - 15:45)
Je suis en train de tester mais pour vérifier le resultat j'ai besoins d'afficher le jour et l'heure
Ok, mais si plusieurs cas se présentent le même jour pour le même habitant, la requête va te remonter plusieurs lignes pour le même jour, une par datetime ...

Regarde le résultat sur le SQLFiddle.

Dans cet exemple, l'habitant 1 a trois passages le 1er janvier 2014 en moins d'une demi heure ... sans GROUP BY ou DISTINCT la requête sort deux lignes pour cette date ...
Modifié par Benzouye (23 May 2014 - 15:59)
Bon j'ai scruté quelques résultats, j'espère que je ne vais pas en oublier mais ça me parait bon. Donc merci à toi pour ton aide !!!