2013-02-27 3 views
4

Considérons ce tableau en spécifiant combien de fois une personne a acheté une propriété.Comptez le nombre de lignes distinctes pour plusieurs valeurs

+--------+----------+ 
| user | property | 
+--------+----------+ 
| john | car  | 
| john | car  | 
| john | house | 
| peter | car  | 
| peter | car  | 
| amanda | house | 
| amanda | house | 
+--------+----------+ 

J'ai besoin de savoir combien de fois une voiture a été acheté une fois, combien de fois une maison a été achetée une fois, etc. Quelque chose comme ceci:

+----------+---+---+ 
| property | 1 | 2 | 
+----------+---+---+ 
| cars  | 4 | 2 | 
| house | 3 | 1 | 
+----------+---+---+ 
  • Combien de fois une voiture était acheté? Quatre, deux pour peter et deux pour john.
  • Combien de fois une voiture a été achetée deux fois? Deux, pour les mêmes gars.
  • Combien de fois une maison a-t-elle été achetée? Trois, deux pour amanda et une fois pour john.
  • Combien de fois une maison a été achetée deux fois? Seulement une fois , pour amanda

Est-ce possible de le faire en utilisant uniquement des requêtes SQL?

  • Je ne me soucie pas des performances ou des moyens hackish.
  • Il y a plus de deux fréquences.
  • Il existe un ensemble fixe de temps qu'une personne peut acheter une propriété (5). Il n'est donc pas difficile de spécifier les colonnes manuellement dans la requête. Je veux dire qu'il n'y a pas de problème à faire quelque chose comme:

    SELECT /* ... */ AS 1, /* ... */ AS 2, /* ... */, AS 3 /* ... */ 
    

Répondre

1
SELECT DISTINCT @pr := prop, 
    (SELECT COUNT(1) FROM tbl WHERE prop = @pr LIMIT 1), 
    (SELECT COUNT(1) FROM 
     (SELECT *, COUNT(*) cnt 
     FROM tbl 
     GROUP BY usr, prop 
     HAVING cnt = 2) as tmp 
     WHERE `tmp`.prop = @pr LIMIT 1) 
FROM tbl; 

Oui, ce ne sont pas la meilleure méthode; mais bon, vous obtenez les réponses souhaitées.

De plus, il générera les résultats pour tout type de propriété dans votre table.

Le lien de violon lies here.

P.S .: 60 essais o_O

+0

C'est génial! Une petite note cependant, c'est qu'il me dit le nombre de fois qu'un certain utilisateur a acheté une propriété. Par exemple, si ** amanda ** achète une autre maison, le nombre de fois qu'une maison a été achetée ** deux fois ** serait 0 (même si Amanda a acheté une maison deux fois auparavant). Encore, assez proche, et c'est encore très utile. Si rien d'autre n'apparaît, c'est la bonne réponse. – Veehmot

+1

Vous pouvez remplacer 'HAVING cnt = 2' par' HAVING cnt> = 2'. ou ajouter une autre clause; où mettre 'HAVING cnt = 3' donnerait tous ceux qui ont été achetés trois fois. : P – hjpotter92

+0

Fonctionne plutôt bien, merci beaucoup! – Veehmot

0

essayer cette

SELECT property , count(property) as bought_total , count(distinct(user)) bought_per_user 
    FROM Table1 
    GROUP BY property 

la sortie sera comme celle

PROPERTY | BOUGHT_TOTAL  | BOUGHT_PER_USER 
    ________________________________________________________ 
    car  |   4  |  2 
    house |   3  |  2 

DEMO SQL FIDDLE HERE

+0

Merci pour votre temps. Cela me donne combien de fois un utilisateur différent a acheté une propriété, mais ce n'est pas ce que je cherche. Notez que la table de résultats est différente de l'exemple de table de sortie. – Veehmot

0

Vous devriez pouvoir pour faire ça avec sous-sélection.

SELECT property, user, COUNT(*) FROM purchases GROUP BY property, user; 

vous renverra l'ensemble complet de données groupées que vous souhaitez. Vous devez alors regarder les différentes fréquences:

SELECT property, freq, COUNT(*) FROM (SELECT property, user, COUNT(*) freq FROM purchases GROUP BY property, user) AS foo GROUP BY property, freq; 

Il est pas tout à fait dans le format que vous illustré, mais il renvoie les données

1

Je suis ici depuis que vous avez posté la question. Bon ...
Voici une façon de le faire exactement comme vous l'avez demandé, avec seulement des groupes et des comptes.
L'astuce consiste à concaténer les colonnes user et property pour produire un "id" unique pour chacune, si nous pouvons l'appeler ainsi. Il devrait fonctionner indépendamment du nombre d'achats.

SELECT C.`property`, COUNT(C.`property`), D.`pcount` from `purchases` C 
LEFT JOIN(
    SELECT A.`property`, B.`pcount` FROM `purchases` A 
    LEFT JOIN (
    SELECT `property`, 
      CONCAT(`user`, `property`) as conc, 
      COUNT(CONCAT(`user`, `property`)) as pcount 
    FROM `purchases` GROUP BY CONCAT(`user`, `property`) 
) B 
    ON A.`property` = B.`property` 
    GROUP BY B.pcount 
) D 
ON C.`property` = D.`property` 
GROUP BY C.`property` 
1

SQL Fiddle

MySQL 5.5.30 Configuration Schéma:

CREATE TABLE Table1 
    (`user` varchar(6), `property` varchar(5)) 
; 

INSERT INTO Table1 
    (`user`, `property`) 
VALUES 
    ('john', 'car'), 
    ('john', 'car'), 
    ('john', 'house'), 
    ('peter', 'car'), 
    ('peter', 'car'), 
    ('amanda', 'house'), 
    ('amanda', 'house') 
; 

Query 1:

select t.property, t.total, c1.cnt as c1, c2.cnt as c2, c3.cnt as c3 
from 
    (select 
    t.property , 
    count(t.property) as total 
    from Table1 t 
    group by t.property 
) as t 
    left join (
     select property, count(*) as cnt 
     from (
      select 
      property, user, count(*) as cnt 
      from table1 
      group by property, user 
      having count(*) = 1 
     ) as i1 
     group by property 
) as c1 on t.property = c1.property 
    left join (
     select property, count(*) as cnt 
     from (
      select 
      property, user, count(*) as cnt 
      from table1 
      group by property, user 
      having count(*) = 2 
     ) as i2 
     group by property 
) as c2 on t.property = c2.property 
    left join (
     select property, count(*) as cnt 
     from (
      select 
      property, user, count(*) as cnt 
      from table1 
      group by property, user 
      having count(*) = 3 
     ) as i3 
     group by property 
) as c3 on t.property = c3.property 

Results:

| PROPERTY | TOTAL |  C1 | C2 |  C3 | 
------------------------------------------- 
|  car |  4 | (null) | 2 | (null) | 
| house |  3 |  1 | 1 | (null) | 
1

Vous pouvez essayer.

SELECT COUNT(TABLE1.PROPERTY) AS COUNT, PROPERTY.USER FROM TABLE1 
INNER JOIN (SELECT DISTINCT PROPERTY, USER FROM TABLE1) AS PROPERTY 
ON PROPERTY.PROPERTY = TABLE1.PROPERTY 
AND PROPERTY.USER = TABLE1.USER 
GROUP BY TABLE1.USER, PROPERTY.PROPERTRY 

testé similaire dans MySQL

0

J'espère que cela peut aider u ..... Créons une table d'abord:

créer prop table (varchar utilisateur (max), propriété varchar (max))

insert en valeurs de béquille ('john', 'car'), insérer dans les valeurs d'appui vertical ('john', 'car'), insert en valeurs prop ('john', 'maison'), insérer dans les valeurs de prop ('peter', 'voiture'),

insert en valeurs prop ('peter', 'voiture'), insérer dans les valeurs prop ('amanda', 'maison'), insert en valeurs prop ('amanda', 'maison')

1) comment plusieurs fois la voiture a été achetée?

ANS: select count (propriété) de prop où la propriété = 'voiture' (4)

2) Combien de fois une voiture a été acheté deux fois?

ANS: sélectionnez l'utilisateur, COUNT (propriété) de prop où property = groupe 'voiture' par l'utilisateur ayant COUNT (propriété) = 2

2-john 2-Peter

3) Comment plusieurs fois une maison a été achetée? ANS: sélectionnez COUNT (propriété) à partir de la propriété où 'property' (3) ANS: Sélectionner les utilisateurs, COUNT (propriété) de prop où property = groupe 'maison' par l'utilisateur ayant COUNT (propriété) < = 2 2-amanda 1-john

Questions connexes