Как получить голоса с результатами с начислением процентов - PullRequest
0 голосов
/ 16 октября 2018

В моем приложении Laravel 5.7 / mysql 5 у меня есть таблица с результатами голосования:

`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`vote_item_id` INT(10) UNSIGNED NOT NULL,
`user_id` INT(10) UNSIGNED NOT NULL,
`is_correct` TINYINT(1) NOT NULL DEFAULT '0',
`created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,

, где логическое поле is_correct, если ответ был правильным или неправильным.Мне нужно получить данные о процентах правильных ответов.

Создание такого запроса

$voteItemUsersResultsCorrect = VoteItemUsersResult::    // Grouped by vote name
getByIsCorrect(true)->
getByCreatedAt($filter_voted_at_from, ' > ')->
getByCreatedAt($filter_voted_at_till, ' <= ')->
getByUserId($filterSelectedUsers)->
getByVote($filterSelectedVotes)->
getByVoteCategories($filterSelectedVoteCategories)->
getByVoteIsQuiz(true)->
getByVoteStatus('A')->
select( \DB::raw('count(vote_item_users_result.id) as count, votes.id, votes.name as vote_name') )->
orderBy('vote_name', 'asc')->
groupBy( 'votes.id' )->
groupBy( 'vote_name' )->
join(\DB::raw('vote_items'), \DB::raw('vote_items.id'), '=', \DB::raw('vote_item_users_result.vote_item_id'))->
join(\DB::raw('votes '), \DB::raw('votes.id'), '=', \DB::raw('vote_items.vote_id'))->
get();

Я могу получить количество правильных голосов с запросом sql.

 SELECT count(vote_item_users_result.id)     AS count, votes.id, votes.name     AS vote_name 
    FROM `vote_item_users_result` 
    INNER JOIN vote_items on vote_items.id = vote_item_users_result.vote_item_id 
    INNER JOIN votes  on votes.id = vote_items.vote_id 
    WHERE `vote_item_users_result`.`is_correct` = '1'     AND vote_item_users_result.created_at  > '2018-08-01'      AND vote_item_users_result.created_at  <= '2018-09-22 23:59:59'      AND `votes`.`is_quiz` = '1'     AND `votes`.`status` = 'A' 
    GROUP BY `votes`.`id`, `vote_name` 
    ORDER BY `vote_name` asc 

Iзнаете способ получения 2-го аналогичного запроса с is_correct = '0' и на стороне php, чтобы объединить результаты с вычислением процентов, но мне интересно, можно ли это сделать с помощью eloquent в 1 запросе?

Если да,как?

Спасибо!

1 Ответ

0 голосов
/ 16 октября 2018

Один правильный сырой MySQL будет использовать условное агрегирование:

SELECT
    v.id,
    100.0 * COUNT(CASE WHEN vir.is_correct = 1 THEN 1 END) / COUNT(*) AS pct_correct,
    100.0 * COUNT(CASE WHEN vir.is_correct = 0 THEN 1 END) / COUNT(*) AS pct_incorrect
FROM votes v
INNER JOIN vote_items vi
    ON v.id = vi.vote_id
INNER JOIN vote_item_users_result vir
    ON vi.id = vir.vote_item_id 
WHERE
    vir.created_at  > '2018-08-01' AND vir.created_at  < '2018-09-23' AND
    v.is_quiz = '1' AND
    v.status = 'A'
GROUP BY
    v.id;

Теперь мы можем попробовать написать код Laravel для этого:

DB::table('vote')
    ->select('vote.id',
             DB::raw('100.0 * COUNT(CASE WHEN vir.is_correct = 1 THEN 1 END) / COUNT(*) AS pct_correct'),
             DB::raw('100.0 * COUNT(CASE WHEN vir.is_correct = 0 THEN 1 END) / COUNT(*) AS pct_incorrect'))
    ->join('vote_items', 'votes.id', '=', 'vote_items.vote_id')
    ->join('vote_item_users_result', 'vote_items.id', '=', 'vote_item_users_result.vote_item_id ')
    ->where([
        ['vote_item_users_result.created_at', '>', '2018-08-01'],
        ['vote_item_users_result.created_at', '<', '2018-09-23'],
        ['vote.is_quiz', '=', '1'],
        ['vote.status', '=', 'A']
    ])
    ->groupBy('vote.id')
    ->get();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...