web-dev-qa-db-fra.com

requête mysql: SELECT DISTINCT colonne1, GROUP BY colonne2

En ce moment, j'ai la requête suivante:

SELECT name, COUNT(name), time, price, ip, SUM(price) 
  FROM tablename 
 WHERE time >= $yesterday 
   AND time <$today GROUP BY name

Et ce que je voudrais faire, c'est ajouter un DISTINCT par colonne 'ip', c'est-à-dire.

SELECT DISTINCT ip FROM tablename 

Donc, ma sortie finale serait toutes les colonnes, de toutes les lignes où l'heure est aujourd'hui, regroupées par nom (avec le nombre de noms pour chaque nom répétitif) et aucune adresse IP en double.

À quoi devrait ressembler ma requête? (ou alternativement, comment puis-je ajouter le filtre manquant à la sortie avec php)?

Merci d'avance.


[MISE À JOUR]

Pour minimiser la confusion, considérez ce tableau db (simplifié):

|   name   |   ip   |
---------------------
|  mark    |  123   |
|  mark    |  123   |
|  mark    |  456   |
|  dave    |  789   |
|  dave    |  087   |

Le résultat que je recherche serait un tableau HTML ressemblant à ceci:

|  name    |  name count   |
----------------------------
|  mark    |      2        |
|  dave    |      2        |

Ce que je reçois actuellement, c'est:

|  name    |  name count   |
----------------------------
|  mark    |      3        |
|  dave    |      2        |

(il compte la marque 3 fois, même si deux fois avec la même ip).

19
Adam Tal

vous pouvez utiliser COUNT(DISTINCT ip), cela ne comptera que des valeurs distinctes

53
knittl

Le remplacement de FROM tablename Par FROM (SELECT DISTINCT * FROM tablename) devrait vous donner le résultat souhaité (en ignorant les lignes dupliquées), par exemple:

SELECT name, COUNT(*)
FROM (SELECT DISTINCT * FROM Table1) AS T1
GROUP BY name

Résultat pour vos données de test:

dave 2
mark 2
13
Mark Byers

Vous pouvez simplement ajouter la DISTINCT(ip), mais elle doit venir au début de la requête. Assurez-vous d'échapper PHP variables qui vont dans la chaîne SQL.

SELECT DISTINCT(ip), name, COUNT(name) nameCnt, 
time, price, SUM(price) priceSum
FROM tablename 
WHERE time >= $yesterday AND time <$today 
GROUP BY ip, name
3
Andy

Essayez ce qui suit:

SELECT DISTINCT(ip), name, COUNT(name) nameCnt, 
time, price, SUM(price) priceSum
FROM tablename 
WHERE time >= $yesterday AND time <$today 
GROUP BY ip, name
2
user2463590

D'une certaine manière, votre exigence semble un peu contradictoire.

regrouper par nom (qui est fondamentalement distinct sur le nom et prêt à agréger), puis distinct sur IP

Selon vous, que devrait-il se passer si deux personnes (noms) travaillaient à partir de la même adresse IP dans le délai spécifié?


Avez-vous essayé cela?

SELECT name, COUNT(name), time, price, ip, SUM(price) 
  FROM tablename 
 WHERE time >= $yesterday AND time <$today 
GROUP BY name,ip
2
lexu