2016-11-30 4 views
1

J'ai une requête:mysql: compter le nombre de valeurs dans chaque groupe

SELECT 
    count(session_id_open) as opens, 
    count(session_id_visit) as visits, 
    date_intervals_open, 
    group_concat(date_intervals_visit) 
FROM 
    bla 
GROUP BY date_intervals_open 

Je me le tableau suivant. Ce dont j'ai besoin, c'est de trouver le pourcentage des occurrences de chaque valeur apparaissant dans group_concat. Donc, en gros, je dois compter le nombre de valeurs (date_intervals_visit) dans chaque groupe (data_intervals_open)

opens visits date_intervals_open group_concat   
213 5  day (12-16)    evening (17-21),evening (17-21),day (12-16),day (12-16),day (12-16) 
113 0  evening (17-21)   NULL 
11  0  late evening (22-00) NULL 
396 12  morning (5-11)   morning (5-11),morning (5-11),morning (5-11),morning (5-11),morning (5-11),morning (5-11),morning (5-11),morning (5-11),morning (5-11),morning (5-11),morning (5-11),morning (5-11) 
9  0  night (1-4)    NULL 

C'est à peu près le tableau que je dois obtenir. en soirée First record a 40 parce que "le soir (17-21)" apparaît deux fois et le nombre de toutes les occurrences est 5. 2/5 * 100 = 40

opens visits date_intervals_open evening(17-21) day(12-16) morning (5-11) 
213 5  day (12-16)    40   60  0 
113 0  evening (17-21)   NULL  NULL  NULL 
11  0  late evening (22-00) NULL  NULL  NULL 
396 12  morning (5-11)   0  0  100 
9  0  night (1-4)    NULL 

PS: je group_concat juste pour visualiser la valeur que j'ai là. Je n'ai pas besoin de l'utiliser car ce sera un effort supplémentaire pour l'analyser ensuite.

+0

S'il vous plaît fournir SHOW CREATE TABLE bla' et quelques rangées de données d'échantillon. C'est comme si vous dépendiez des valeurs NULL en faisant 'count (session_id_visit)'. Cela semble étrange. –

Répondre

1

Vous devez essentiellement un pivot, avec quelques autres calculs. La base de ma réponse provient de l'excellent sujet SO suivant sur pivoting records in MySQL. Je suppose que vous avez un nombre fixe de valeurs date_intervals_visit, car ces valeurs semblent couvrir toute la journée, donc j'utilise l'approche du nombre conditionnel avec un nombre fixe de comptes. Je vais ajouter 2 catégories dans l'exemple de code, vous pouvez l'étendre pour couvrir toutes les valeurs date_intervals_visit.

SELECT 
    count(session_id_open) as opens, 
    count(session_id_visit) as visits, 
    date_intervals_open, 
    round(sum(if(date_intervals_visit='morning (5-11)',1,0))/count(session_id_visit) * 100,2) as `morning (5-11)`, 
    round(sum(if(date_intervals_visit='day (12-16)',1,0))/count(session_id_visit) * 100,2) as `day (12-16)` 
FROM 
    bla 
GROUP BY date_intervals_open 

S'il est possible d'avoir 0 visites par date_intervals_open valeur, vous devez vérifier 0 dans l'expression:

if(count(session_id_visit)=0, 0, <above formula>) 
+0

ah, bon nombre même rep. 15000. Bonne réponse et support. – Drew

+0

@Don merci, agréable d'être apprécié – Shadow

+0

Maintenant, allez-y et ** Protégez ** chaque question 'mysql': p – Drew

-1

Utilisez une fonction comme ceci:

CREATE FUNCTION [dbo].[fn_SplitString](
    @InputStr varchar(Max), 
    @Seperator varchar(10)) 
RETURNS @OutStrings TABLE (ItemNo int identity(1,1), Item varchar(256)) 

AS 
BEGIN 

    DECLARE @Str varchar(2000), 
      @Poz int, @cnt int 

    --DECLARE @OutStrings TABLE (Item varchar(2000)) 

    SELECT @Poz = CHARINDEX (@Seperator, @InputStr), @cnt = 0 
    WHILE @Poz > 0 AND @cnt <= 10000 
    BEGIN 
     SELECT @Str = SubString(@InputStr, 1, @Poz - 1) 
     INSERT INTO @OutStrings(Item) VALUES(@Str) 

     SELECT @InputStr = Right(@Inputstr, Len(@InputStr) - (len(@Str) + len(@Seperator))) 
     SELECT @Poz = CHARINDEX (@Seperator, @InputStr), @cnt = @cnt + 1 
    END 
    IF @InputStr <> '' 
    BEGIN 
     INSERT INTO @OutStrings(Item) VALUES(@InputStr) 
    END 

    RETURN 
END 

de la manière suivante:

SELECT opens, 
     visits, 
     date_intervals_open, 
     [evening(17-21)]/[All]*100 AS [evening(17-21)], 
     [day(12-16)]/[All]*100 AS [day(12-16)], 
     [morning (5-11)]/[All]*100 AS [morning (5-11)] 
FROM 
    ( 
    SELECT 
     count(session_id_open) as opens, 
     count(session_id_visit) as visits, 
     date_intervals_open, 
     (SELECT COUNT(Item) FROM [dbo].[fn_SplitString](LTRIM(RTRIM(group_concat(date_intervals_visit))), ',') WHERE item = 'evening(17-21)') AS [evening(17-21)], 
     (SELECT COUNT(Item) FROM [dbo].[fn_SplitString](LTRIM(RTRIM(group_concat(date_intervals_visit))), ',') WHERE item = 'day(12-16)') AS [day(12-16)], 
     (SELECT COUNT(Item) FROM [dbo].[fn_SplitString](LTRIM(RTRIM(group_concat(date_intervals_visit))), ',') WHERE item = 'morning (5-11)') AS [morning (5-11)], 
     (SELECT COUNT(Item) FROM [dbo].[fn_SplitString](LTRIM(RTRIM(group_concat(date_intervals_visit))), ',')) AS [All] 
    FROM 
     bla 
    GROUP BY date_intervals_open 
    )blabla 
+0

ms sql alors que la question concerne MySQL. – Shadow

+0

S'il vous plaît le tester en premier. Il utilise SQL de base que MySQL prend en charge. –

+0

Pour référence consultez http://dev.mysql.com/doc/refman/5.7/fr/adding-functions.html –

0
SELECT 
    count(session_id_open) as opens, 
    @visits := count(session_id_visit) as visits, 
    date_intervals_open, 
    ROUND(100 * SUM(date_intervals_visit = 'evening(17-21)')/@visits) AS 'evening(17-21)', 
    ROUND(100 * SUM(date_intervals_visit = 'day (12-16)')/@visits) AS 'day (12-16)', 
    ROUND(100 * SUM(date_intervals_visit = 'morning (5-11)')/@visits)'morning (5-11)', 
FROM 
    bla 
GROUP BY date_intervals_open