2016-08-25 27 views
0

我需要得到獨特的計數與國家數和總速率以及對每一位用戶的Mysql得到統計數據庫的多個罪名

我想出了數據庫這一基本設計,其中uid是用戶ID

DROP TABLE IF EXISTS `stats`; 
CREATE TABLE IF NOT EXISTS `stats` (
    `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, 
    `uid` int(5) UNSIGNED NOT NULL, 
    `country` int(3) UNSIGNED NOT NULL, 
    `ip` int(10) UNSIGNED NOT NULL, 
    `date` int(10) UNSIGNED NOT NULL, 
    `timestamp` int(10) UNSIGNED NOT NULL, 
    `rate` int(10) UNSIGNED NOT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; 

INSERT INTO `stats` 
(`id`, `uid`, `country`, `ip`, `date`, `timestamp`, `rate`) VALUES 
(1, 1, 10, 1111111111, 2222222222, 3333333333, 100), 
(2, 1, 10, 1111111112, 2222222222, 3333333333, 100), 
(3, 2, 10, 1111111111, 2222222222, 3333333333, 100), 
(4, 1, 10, 1111111114, 2222222223, 3333333333, 100), 
(5, 1, 11, 1111111112, 2222222223, 3333333333, 100), 
(6, 1, 10, 1111111111, 2222222223, 3333333333, 100); 

這是我使用的日常讀取查詢計數

$query=" 
SELECT `uid`, 
COUNT(DISTINCT `ip`)AS `count`, 
`country`, 
SUM(`rate`) AS `sum`, 
`date` 
FROM `stats` 
GROUP BY `uid`, `date` 
"; 
$result=mysqli_query($connection, $query) or trigger_error(mysqli_error($connection), E_USER_ERROR); 
while($row = mysqli_fetch_assoc($result)){ 
echo 'userid:'.$row['uid'].' count:'.$row['count'].' country:'.$row['country'].' sum:'.$row['sum'].' date:'.$row['date'].'<br>'; 
}; 

我得到這個結果

userid:1 count:2 country:10 sum:200 date:2222222222 
userid:1 count:3 country:10 sum:300 date:2222222223 
userid:2 count:1 country:10 sum:100 date:2222222222 

預期結果

userid:1 count:2 country:10=>2  sum:200 date:2222222222 
userid:1 count:3 country:10=>2, 11=>1 sum:300 date:2222222223 
userid:2 count:1 country:10=>1  sum:100 date:2222222222 

我想我需要這樣的東西SELECT DISTINCT country FROM stats獲得國家計數主查詢。

請參閱並提出任何可能的方式來做到這一點。

感謝

+0

你也想統計不同的國家嗎? – Strawberry

+0

@Strawberry是的,但結果應該顯示在單行來回一天的任何用戶 –

+0

你怎麼知道哪個日期對應而導致 – Strawberry

回答

2

您可以使用子查詢來實現這一目標:

SELECT 
    t.uid, 
    SUM(t.count) AS count, 
    GROUP_CONCAT(CONCAT(t.country, ' => ', t.views) SEPARATOR ', ') AS country, 
    SUM(t.sum) as sum, 
    t.date 
FROM (
    SELECT 
    s.uid, 
    COUNT(DISTINCT s.ip) AS count, 
    s.country, 
    COUNT(s.country) as views, 
    SUM(s.rate)AS sum, 
    s.date 
    FROM stats s 
    GROUP BY uid, date, country 
) AS t 
GROUP BY 
t.uid, 
t.date 

也可在sqlfiddle

+0

這正是我需要的,我也想知道它是否能正確處理數百萬行並經常使數據庫不會變慢。 –

+1

性能取決於多少行將被分組到一個行中。 MySQL將首先執行子查詢。然後外部查詢將在結果數據集上執行。如果第一個查詢返回許多行,則第二個查詢可能會花費大量時間。如果使用分組的第一個查詢返回少量行,則第二個查詢將很快並且幾乎不影響總執行時間。 – Andrew

+0

所以這意味着數百萬行用戶很多,它會很慢 –

1

SUM需要一列,你在它給串'rate',從率列名稱中刪除'試試這個,

SELECT 
    COUNT(DISTINCT `ip`)AS `count`, 
    `country`, 
    SUM(rate) AS `sum` 
    FROM `stats` 
    GROUP BY `uid`, `date` 
+0

由於它是一個錯字的錯誤,這就是解決之和,但我仍然需要國家統計 –

+0

我還糾正我的問題 –

1

您必須添加country入組條件太:

SELECT 
    COUNT(DISTINCT `ip`) AS `count`, 
    `country`, 
    COUNT(`country`) as `countryViewsByUser`, -- added 
    SUM(`rate`)AS `sum` 
FROM 
    `stats` 
GROUP BY 
    `uid`, 
    `date`, 
    `country` -- added 
+0

這給了一個額外的行爲同一天,我需要的所有數據在一排了一天。 –

+0

'userid:1 count:2 country:10 sum:200 userid:1 count:2 country:10 sum:200 userid:1 count:1 country:11 sum:100 userid:2 count:1 country:10總和:100' –

+0

它給出4行,這就是你的數據會給。第2天爲第1天,第2天爲第2天。 – Shaharyar

0

你只需要通過條款,包括加入國到組下方

$query=" 
SELECT 
COUNT(DISTINCT `ip`)AS `count`, 
`country`, 
COUNT(DISTINCT `country`) AS country_count, 
SUM(`rate`) AS `sum` 
FROM `stats` 
GROUP BY `country`, `uid`, `date` 
"; 

並請你需要擺脫mysqli_ *函數去,看看PDO代替

+0

它並未給出一行中用戶的所有數據,而是兩行中的數據。 –