У меня есть два набора (данные пользователей и их тесты) данных из MySQL. Я собираюсь построить таблицу лидеров из этих данных таким образом, чтобы каждый пользователь имел Средняя оценка (%), множество (сумма результатов всех испытаний) и общее количество тестов этот пользователь присутствовал. В конце, когда все данные сформированы для списка лидеров, они должны быть отсортированы по убыванию, поэтому сначала наивысшая средняя оценка и оценки у ассоциированного пользователя и т. Д. Я начал с цикла while, но сложил со связыванием данных в имена пользователей.
Код PHP:
// contains set of data with fields user_id(INT) and name(VARCHAR)
$users = mysqli_fetch_assoc($result_users);
// contains set of data with fields user_id(INT), socres(DECIMAL), passed(BOOL)
$data = mysqli_fetch_assoc($result_data);
$pos = null; // collect positive tests
$neg = null; // collect negative tests
while ($data = mysqli_fetch_assoc($result_all)) {
if ($data['quiz_passed'] == 1) {
$pos += 1;
} elseif ($data['quiz_passed'] == 0) {
$neg += 1;
}
}
Ожидаемые результаты таблицы лидеров:
Name Average (Pos/Neg) Scores (Sum of scores field) Total tests (Pos+Neg)
-------------------------------------------------------------------------------------
John 80% 143 9
// 4 Pos / 5 Neg // 4 Pos + 5 Neg
Любая помощь будет оценена.
ОБНОВЛЕНИЕ:
User Table
----------
CREATE TABLE IF NOT EXISTS `user` (
`user_id` int(11) NOT NULL, // PRIMARY KEY
`name` varchar(100) NOT NULL,
`password` varchar(255) NOT NULL,
`fullname` varchar(255) NOT NULL,
`token` varchar(128) NOT NULL,
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
(4, 'test1', 'password_here1', 'Tim Roth', 'token_here1'),
(5, 'test2', 'password_here2', 'Christoph Waltz', 'token_here2'),
(6, 'test3', 'password_here3', 'John Travolta', 'token_here3'),Data Table
----------
CREATE TABLE IF NOT EXISTS `data` (
`id` int(11) NOT NULL, // PRIMARY KEY
`user_id` int(11) NOT NULL,
`scores` decimal(3,2) NOT NULL,
`passed` tinyint(1) NOT NULL,
`time` datetime NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
(1, 6, '0.60', 0, '2014-11-12 01:24:43'),
(2, 4, '0.75', 1, '2014-10-31 06:33:48'),
(3, 4, '0.90', 1, '2014-11-02 15:11:09'),
(4, 4, '0.50', 0, '2014-11-06 19:29:19'),
(5, 5, '0.75', 1, '2014-11-07 08:21:44'),
(6, 5, '0.60', 0, '2014-11-10 17:34:00'),
(7, 6, '0.60', 0, '2014-11-11 16:13:50'),
(8, 4, '0.85', 1, '2014-11-12 13:22:49')
Основываясь на данных, есть одна небольшая проблема. Ваше среднее значение, по-видимому, представляет собой число, где pass = 1, деленное на где pass = 0. Так что, если кто-то не провалил экзамен, будет деление на ноль. Хотя это достаточно просто для программирования, мне нужно знать, что вы хотите сделать в этой ситуации.
SELECT u.user_id, SUM(d.passed) / SUM(IF(d.passed = 0, 1, 0)) AS `Average`, SUM(d.scores) AS `Scores`, COUNT(d.id) AS `Total Tests`
FROM user u
INNER JOIN data d
ON u.user_id = d.user_id
GROUP BY u.user_id;
Не уверен, что было бы правильнее посчитать количество проходов по количеству экзаменов.
SELECT u.user_id, SUM(d.passed) / COUNT(d.passed) AS `Average`, SUM(d.scores) AS `Scores`, COUNT(d.id) AS `Total Tests`
FROM user u
INNER JOIN data d
ON u.user_id = d.user_id
GROUP BY u.user_id;
SQL скрипка, чтобы показать 2 результата: —
SELECT
ROUND(SUM(d.passed) / COUNT(*) * 100, 2) AS average,
SUM(d.score) AS score,
COUNT(*) AS total
FROM user AS u
INNER JOIN data AS d ON d.user_id = u.id
GROUP BY u.id