0
There are many sub selects, how could improve this query in Mysql and make a max SUM of total_points_period'?
Pick up the total points for a period from the "user_bigdata" table and the total points from the "olympic_players_levels" table according to the period.
The table user_bigdata, is a list where you have all points per user of the system, but I need to take and sum all the maximum points of the same relationship action_id, already the score of olympic_player_levels is the score of a particular competition by period, which is related to the active competition in the table Olympic, where it contains the initial and final period of this competition. I would like to relate both without needing a subquery to another subquery.
The current query:
SELECT `tab`.`user_id`, `tab`.`total_points`,
(SELECT max(CASE WHEN ub.action_type = 'points' and ub.value <> 'giveup' and ub.created between start_date and end_date THEN CAST(ub.value as UNSIGNED) ELSE 0 END ) AS pontos_obtidos
FROM user_bigdata ub
WHERE ub.usr_id = user_id
AND (ub.action_type in ('points') and ub.type_utilization=2)
group by ub.action_id, ub.question_id) as total_points_period
FROM (
SELECT
SUM(opn.points) AS `total_points`,
ol.start_date AS start_date,
ol.end_date AS end_date,
u.ID as user_id,
u.avatar_json
FROM
`olympic_players_niveis` AS `opn`
INNER JOIN
olympics ol ON (ol.active = 1 AND ol.ID = opn.olympic_id AND ol.ID = 1 )
INNER JOIN users u ON(`opn`.`user_id`=u.ID)
GROUP BY `opn`.`user_id`
ORDER BY SUM(opn.points) DESC , `opn`.`created` DESC , FIELD(opn.tip_resolved, 1, NULL) DESC
) AS `tab` ORDER BY `total_points` DESC, `total_points_period` DESC
Tables:
CREATE TABLE `olympic_players_niveis` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`nivel_id` int(4) NOT NULL,
`points` int(6) NOT NULL,
`olympic_id` int(4) DEFAULT NULL,
`created` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
`tip_resolved` int(1) DEFAULT NULL,
`updated` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`ID`),
KEY `fk_olympic_players_Olympics1_idx` (`olympic_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;
CREATE TABLE `olympics` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`active` int(11) NOT NULL,
`title` text CHARACTER SET utf8 NOT NULL,
`badge_id` int(11) NOT NULL,
`person_1` int(3) DEFAULT NULL,
`person_2` int(3) DEFAULT NULL,
`initial_talk_id` int(3) DEFAULT NULL,
`end_talk_id` int(3) DEFAULT NULL,
`logo` varchar(80) COLLATE utf8_unicode_ci DEFAULT NULL,
`regulation` text COLLATE utf8_unicode_ci,
`start_date` datetime DEFAULT NULL,
`end_date` datetime DEFAULT NULL,
`free_users_access` text COLLATE utf8_unicode_ci,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE `user_bigdata` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`usr_id` int(4) NOT NULL,
`action_type` varchar(50) NOT NULL,
`action_id` int(4) NOT NULL,
`question_id` int(4) NOT NULL,
`data_type` varchar(30) NOT NULL,
`value` varchar(100) NOT NULL,
`created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`start` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`end` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`seconds` int(5) NOT NULL,
`answer` varchar(5) DEFAULT NULL,
`answer_correct` int(2) DEFAULT NULL,
`type_utilization` int(2) DEFAULT NULL,
PRIMARY KEY (`ID`),
KEY `indice1` (`value`,`data_type`,`action_id`,`usr_id`),
KEY `type_value` (`data_type`,`value`,`usr_id`),
KEY `indiceusuario` (`usr_id`),
KEY `actiontimeid` (`action_type`,`action_id`,`question_id`),
KEY `action_search` (`usr_id`,`action_type`,`data_type`,`action_id`),
KEY `index_busca_atividade` (`usr_id`,`action_type`,`question_id`,`created`,`value`,`action_id`),
KEY `index_recentes` (`usr_id`,`action_id`,`action_type`),
KEY `index_data` (`created`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
CREATE TABLE `users` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(200) CHARACTER SET utf8 NOT NULL,
`role` varchar(50) CHARACTER SET utf8 NOT NULL,
`password` varchar(500) CHARACTER SET utf8 NOT NULL,
`status` int(11) NOT NULL,
PRIMARY KEY (`ID`),
KEY `idx_role` (`ID`,`role`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
The data would be basically these:
INSERT INTO `user_bigdata` (`ID`, `usr_id`, `action_type`, `action_id`, `question_id`, `value`, `type_utilization`) VALUES ('', 1, 'points', 1, 0, 200, 2);
INSERT INTO `user_bigdata` (`ID`, `usr_id`, `action_type`, `action_id`, `question_id`, `value`, `type_utilization`) VALUES ('', 1, 'points', 1, 0, 100, 2);
INSERT INTO `user_bigdata` (`ID`, `usr_id`, `action_type`, `action_id`, `question_id`, `value`, `type_utilization`) VALUES ('', 1, 'points_tips', 1, 0, 50, 2);
INSERT INTO `user_bigdata` (`ID`, `usr_id`, `action_type`, `action_id`, `question_id`, `value`, `type_utilization`) VALUES ('', 2, 'points', 1, 0, 100, 2);
INSERT INTO `user_bigdata` (`ID`, `usr_id`, `action_type`, `action_id`, `question_id`, `value`, `type_utilization`) VALUES ('', 2, 'points', 1, 0, 80, 2);
INSERT INTO `user_bigdata` (`ID`, `usr_id`, `action_type`, `action_id`, `question_id`, `value`, `type_utilization`) VALUES ('', 2, 'points_tips', 1, 0, 10, 2);
INSERT INTO `user_bigdata` (`ID`, `usr_id`, `action_type`, `action_id`, `question_id`, `value`, `type_utilization`) VALUES ('', 3, 'points', 1, 0, 'giveup', 2);
INSERT INTO `olympics` (`ID`, `active`, `title`, `start_date`, `end_date`) VALUES (1, 1, "Jogo", 0, DATE_ADD(NOW(), INTERVAL -1 DAY), DATE_ADD(NOW(), INTERVAL +10 DAY));
INSERT INTO `olympic_players_niveis` (`ID`, `user_id`, `nivel_id`, `points`, `olympic_id`, `created`, `tip_resolved`)
VALUES ('', 1, 1, 30, 1, now(), null);
INSERT INTO `olympic_players_niveis` (`ID`, `user_id`, `nivel_id`, `points`, `olympic_id`, `created`, `tip_resolved`)
VALUES ('', 2, 1, 130, 1, now(), null);
INSERT INTO `users` (`ID`, `username`, `role`, `password`) VALUES (1, 'ononnoonon1', 'nonono', 'onnonono');
INSERT INTO `users` (`ID`, `username`, `role`, `password`) VALUES (2, 'ononnoonon2', 'nonono', 'onnonono');
INSERT INTO `users` (`ID`, `username`, `role`, `password`) VALUES (3, 'ononnoonon2', 'nonono', 'onnonono');
I believe it is important to inform the data you want in the query. Facilitates a possible improvement in your
query
or even a newquery
to satisfy your need.– Thiago Magalhães
@Thiagomagalhães, I edited the question, to be clear.
– Ivan Ferrer
Put a real example using sql fiddle: And I started one here, but the data Voce placed is not correct
– William John Adam Trindade
http://sqlfiddle.com/#! 9/d26084/1
– Ivan Ferrer
Here is an example, if it were 2 records: http://sqlfiddle.com/#! 9/7c2e4/2
– Ivan Ferrer
@Ivanferrer, I am trying to understand the relations and query that you presented and a question arose. Is this query right? Because the points of
user_bigdata
per player shown inquery
is 200, but looking at the test data of the link that passed, I believe that one would have 200 and the other 180.– Thiago Magalhães
Actually, there is a problem in the query, it should do a SUM in max(...).
– Ivan Ferrer