2014-11-18 2 views
0

У меня есть два набора (пользователи и их данные тестов) данных из MySQL. Я собираюсь собрать таблицу лидеров из этих данных таким образом, чтобы каждый пользователь имел средний класс (%), баллов (сумма всех результатов тестов) и общее количество тестов, которые посетил пользователь. В конце, когда все данные формируются для таблицы лидеров, они должны быть отсортированы по убыванию, поэтому первый самый высокий средний класс и баллы со связанным пользователем и т. Д. Я начал с while-loop, но уложился в связку с данными в имена пользователей.PHP - построение учебника из данных MySQL

код 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') 
+1

Я предполагаю, что вы хотите использовать объединение при запросе данных, а не два отдельных запросов. Вы должны показать свои текущие запросы, а также схему для своих таблиц, чтобы вы могли лучше узнать, как сформулировать ваш запрос. –

+0

Чтобы следить за @MikeBrant - это должно быть возможно с помощью одного запроса. Должно быть возможно рассчитать доли и упорядочить их в рамках этого запроса. Можете ли вы опубликовать объявления таблиц и немного выборочных данных? – Kickstart

+0

@MikeBrant, пожалуйста, взгляните на ** ОБНОВЛЕНО ** часть моего вопроса – Dozent

ответ

1

На основании данных, существует одна небольшая проблема. Ваш расчет для среднего значения - это счетчик, где 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 результатов: -

http://www.sqlfiddle.com/#!2/ecf3d2/1

+0

, возможно, я не был достаточно ясен во время объяснения вопроса, но в отношении ** среднее ** Я хочу подсчитать общее количество положительных (истинных или 1) результатов, деленное на общее количество отрицательных (ложных или 1) для каждого учащегося. Таким образом, я хочу получить процент положительных оценок для конкретного ученика. – Dozent

+0

, если мы посмотрим на результаты ожидаемых лидеров: ** мы можем видеть, что наш пользователь Джон имеет 4 положительных (пройденных: TRUE) и 5 ​​отрицательных (прошедших: FALSE) тестах, в общей сложности он посетил 9 тестов. И сумма всех этих тестов дает ему 143 балла (его просто сумма поля баллов в таблице mysql). – Dozent

+1

Вы поняли это. Но что, если пользователь Джон имеет 9 положительных и 0 отрицательных? Это даст 9/0, что является бесконечностью (которая, вероятно, выйдет как NULL, что бессмысленно, или в php даст ошибку), что и даст первое решение. Сумма баллов должна быть уже в обоих решениях, которые я дал. – Kickstart

0
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 
Смежные вопросы