2016-11-30 20 views
1

中我有一個查詢:的mysql:計值的數量各組

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 

我得到下表。我需要的是找出出現在group_concat中的每個值的百分比。所以,基本上,我需要計算各組(data_intervals_open)值(date_intervals_visit)的數量

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 

這大約是我需要的表格。在第一記錄晚上有40個是因爲「晚(17-21)」出現兩次並且所有出現的次數是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:我用GROUP_CONCAT只是以可視化的值我在那裏。我不必使用它,因爲這將是一個額外的努力來解析它之後。

+0

請提供'SHOW CREATE TABLE bla'和幾個樣本數據行。這就好像您在執行count(session_id_visit)時依賴於NULL。這似乎很奇怪。 –

回答

1

你基本上需要一個支點,有一些進一步的計算。我的回答的基礎來自於以下關於pivoting records in MySQL的SO專題。我假設你有一個固定值date_intervals_visit的值,因爲這些值似乎覆蓋了整個一天,因此我使用具有固定數量計數的條件計數方法。我將在示例代碼中添加2個類別,您可以將其擴展爲涵蓋所有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 

如果有可能有0互訪date_intervals_open值,那麼你需要在表達式檢查0:

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

啊,甚至很好的代表號碼。 15000.很好的回答和支持。 – Drew

+0

@Drew謝謝,不勝感激 – Shadow

+0

現在出去吧**保護**每個'mysql'問題:p – Drew

-1

使用這樣的功能:

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 

以下列方式:

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,而問題是關於MySQL。 – Shadow

+0

請先測試一下。它使用mySQL支持的基本SQL。 –

+0

參考http://dev.mysql.com/doc/refman/5.7/en/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