Related
I'm struggling with what is a complicated SQL query for me, although I believe that it is not particularly complicated. I'm close to the right answer, but not quite there yet.
My database represents a criminal abstract. I have three tables in my database (I've simplified my schema enormously for the purposes of this question): arrest, arrestcharges, and dispositions.
Each defendant can have multiple arrests (defendant table not included for simplification). Each arrest can have multiple charges, which are in the arrestcharges table. And each charge has a grade and is associated with a disposition (guilty, not guilty, etc...). The dispositions are categorized so that 0=some form of guilt disposition, 1=a non-guilty disposition.
I want to find individuals who have been convicted of a charge graded as "M1" on more than one case. If an individual has been convicted of more than M1, but they are in the same case, that person shouldn't be returned (unless they have another case with an M1 conviction).
A sqlfiddle link and the SQL to create and populate the table is below.
I believe that this query should work, but it doesn't:
select a.defendantid, count(a.id)
FROM `arrest` AS a LEFT JOIN `arrestcharges` AS ac
ON a.id=ac.arrestid LEFT JOIN `dispositions` AS d
ON ac.dispositionid=d.id
WHERE d.dispocategory=0 AND ac.grade="M1"
GROUP BY a.id HAVING COUNT(a.id) > 1 ORDER BY a.defendantid;
Based on the sql below, I expect that defendant IDs 1 and 5 should be returned since they are the only two defendants with an M1 conviction in more than one arrest. But the actual response I am getting is 2 and 5. 2 should not be returned b/c defendant 2 only has one arrest in the database.
Any thoughts on what I am doing wrong?
SQLFiddle
CREATE TABLE IF NOT EXISTS `arrest` (
`id` int(6) unsigned NOT NULL,
`defendantid` int(6) unsigned NOT NULL,
`docketno` varchar(21) NOT NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `arrestcharges` (
`id` int(6) unsigned NOT NULL,
`arrestid` int(6) unsigned NOT NULL,
`grade` varchar(2) NOT NULL,
`dispositionid` int(6) NOT NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `dispositions` (
`id` int(6) unsigned NOT NULL,
`disposition` varchar(30) NOT NULL,
`dispoCategory` int(1) unsigned NOT NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;
INSERT INTO `arrest` (`id`, `defendantid`, `docketno`) VALUES
('1', '1', 'MC-51-CR-0000222-1999'),
('2', '1', 'MC-51-CR-0000223-1999'),
('3', '1', 'MC-51-CR-0000224-1999'),
('4', '2', 'MC-51-CR-0002343-2000'),
('5', '3', 'MC-51-CR-0002349-2000'),
('6', '3', 'MC-51-CR-0002350-2000'),
('7', '3', 'MC-51-CR-0002351-2010'),
('8', '3', 'MC-51-CR-0002352-2013'),
('9', '4', 'MC-51-CR-1209293-2011'),
('10', '5', 'MC-51-CR-2389848-1999'),
('11', '5', 'MC-51-CR-3893923-1999'),
('12', '5', 'MC-51-CR-2393912-1999');
INSERT INTO `dispositions` (`id`, `disposition`, `dispoCategory`) VALUES
('1', 'Guilty', '0'),
('2', 'Not Guilty', '1'),
('3', 'Guilty Plea', '0'),
('4', 'Dismissed', '1');
INSERT INTO `arrestcharges` (`id`, `arrestid`, `grade`, `dispositionid`) VALUES
('1', '1', 'M1', '1'),
('2', '1', 'M', '2'),
('3', '2', 'F', '2'),
('4', '2', 'M1', '3'),
('5', '3', 'M1', '1'),
('6', '4', 'M2', '4'),
('7', '4', 'M1', '3'),
('8', '4', 'M1', '3'),
('9', '4', 'M1', '1'),
('10', '5', 'M1', '2'),
('11', '6', 'M1', '2'),
('12', '7', 'F2', '1'),
('13', '8', 'F3', '1'),
('14', '9', 'M1', '2'),
('15', '9', 'M1', '2'),
('16', '9', 'M1', '2'),
('17', '9', 'M1', '2'),
('18', '10', 'M1', '1'),
('19', '10', 'M1', '1'),
('20', '11', 'M2', '3'),
('21', '12', 'M1', '4'),
('22', '12', 'M1', '3');
Try this query:
select a.defendantid, count(distinct(ac.arrestid)) as count
FROM `arrest` AS a LEFT JOIN `arrestcharges` AS ac
ON a.id=ac.arrestid LEFT JOIN `dispositions` AS d
ON ac.dispositionid=d.id
WHERE d.dispocategory=0 AND ac.grade="M1"
GROUP BY a.defendantid HAVING count>1;
You should count the distinct number as distinct_count of rows you need and make use of having filter such as having distinct_count>1. This way you can ensure that the count are not getting repeated.
You appear to be aggregating by the wrong column. You need a.defendantid in the group by:
SELECT a.defendantid, count(*)
FROM `arrest` a JOIN
`arrestcharges` ac
ON a.id = ac.arrestid JOIN
`dispositions` d
ON ac.dispositionid = d.id
WHERE d.dispocategory = 0 AND ac.grade = 'M1'
GROUP BY a.defendantid
HAVING COUNT(DISTINCT a.id) > 1
ORDER BY a.defendantid;
Note that I also changed the outer joins to inner joins. If charges and dispositions are not available, then your filtering conditions cannot be met. Hence, the appropriate join is an inner join.
Please need help to complete the code to do the followin:
Calculate the number of votes and percentages of specific records, is a site of movies, where users can view and vote movies, then the website should show all films more to lower the number of votes by users, here the details of what I'm trying to do.
1) Calculate the number of votes in general each film.
2) Get the number of votes by separate "They are altogether 3 table[votes]" for each movie, such as:
Movie 1 There have been a total of 100 votes, 20% of users seemed Regular, 30% of users seemed Good and 50% of users seemed Very good.
3) Get the percentage of the maximum number of votes between "3 of table [votes]", if users voted more for the film was very good, I have to calculate the percentage of that, so we can create a small donut or graphic, showing movies and casts more than you liked to users, for example:
The film was voted Movie 1, with a total of 450 votes, which accounts for 50% of all votes received by user rating.
So far I have done this:
SELECT
M.name AS title_movie,
M.year AS premiere,
G.name AS gender,
COUNT(MHR.vote_id) AS total_voting_movie
FROM movies M
LEFT JOIN gender G ON M.gender_id = G.id
LEFT JOIN movies_has_rating MHR ON M.id = MHR.movie_id
GROUP BY M.id
ORDER BY M.id DESC
Graphic tables database:
The complete code for the entire database:
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for gender
-- ----------------------------
DROP TABLE IF EXISTS `gender`;
CREATE TABLE `gender` (
`id` int(11) NOT NULL,
`name` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-- ----------------------------
-- Records of gender
-- ----------------------------
INSERT INTO `gender` VALUES ('1', 'Action');
INSERT INTO `gender` VALUES ('2', 'Musical');
INSERT INTO `gender` VALUES ('3', 'Sci Fi');
-- ----------------------------
-- Table structure for movies
-- ----------------------------
DROP TABLE IF EXISTS `movies`;
CREATE TABLE `movies` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`year` varchar(255) DEFAULT NULL,
`gender_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=latin1;
-- ----------------------------
-- Records of movies
-- ----------------------------
INSERT INTO `movies` VALUES ('1', 'Alien', '1979', '1');
INSERT INTO `movies` VALUES ('2', 'Aliens', '1986', '1');
INSERT INTO `movies` VALUES ('3', 'Moulin Rouge', '2001', '3');
INSERT INTO `movies` VALUES ('4', 'Guys and Dolls', '1955', '3');
INSERT INTO `movies` VALUES ('5', 'Mama Mia', '1970', '3');
INSERT INTO `movies` VALUES ('6', 'Starman', '1984', '1');
INSERT INTO `movies` VALUES ('7', 'Tron', '1982', '1');
INSERT INTO `movies` VALUES ('8', 'The Matrix', '1988', '2');
-- ----------------------------
-- Table structure for movies_has_rating
-- ----------------------------
DROP TABLE IF EXISTS `movies_has_rating`;
CREATE TABLE `movies_has_rating` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`movie_id` int(11) NOT NULL,
`vote_id` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=156 DEFAULT CHARSET=latin1;
-- ----------------------------
-- Records of movies_has_rating
-- ----------------------------
INSERT INTO `movies_has_rating` VALUES ('1', '1', '1');
INSERT INTO `movies_has_rating` VALUES ('2', '1', '2');
INSERT INTO `movies_has_rating` VALUES ('3', '1', '2');
INSERT INTO `movies_has_rating` VALUES ('4', '1', '2');
INSERT INTO `movies_has_rating` VALUES ('5', '1', '2');
INSERT INTO `movies_has_rating` VALUES ('6', '1', '2');
INSERT INTO `movies_has_rating` VALUES ('7', '1', '2');
INSERT INTO `movies_has_rating` VALUES ('8', '1', '2');
INSERT INTO `movies_has_rating` VALUES ('9', '1', '2');
INSERT INTO `movies_has_rating` VALUES ('10', '1', '2');
INSERT INTO `movies_has_rating` VALUES ('11', '1', '2');
INSERT INTO `movies_has_rating` VALUES ('12', '1', '2');
INSERT INTO `movies_has_rating` VALUES ('13', '1', '1');
INSERT INTO `movies_has_rating` VALUES ('14', '1', '1');
INSERT INTO `movies_has_rating` VALUES ('15', '1', '1');
INSERT INTO `movies_has_rating` VALUES ('16', '1', '1');
INSERT INTO `movies_has_rating` VALUES ('17', '1', '1');
INSERT INTO `movies_has_rating` VALUES ('18', '1', '2');
INSERT INTO `movies_has_rating` VALUES ('19', '1', '2');
INSERT INTO `movies_has_rating` VALUES ('20', '1', '2');
INSERT INTO `movies_has_rating` VALUES ('21', '1', '3');
INSERT INTO `movies_has_rating` VALUES ('22', '1', '3');
INSERT INTO `movies_has_rating` VALUES ('23', '1', '3');
INSERT INTO `movies_has_rating` VALUES ('24', '1', '3');
INSERT INTO `movies_has_rating` VALUES ('25', '1', '3');
INSERT INTO `movies_has_rating` VALUES ('26', '1', '3');
INSERT INTO `movies_has_rating` VALUES ('27', '1', '1');
INSERT INTO `movies_has_rating` VALUES ('28', '1', '3');
INSERT INTO `movies_has_rating` VALUES ('29', '1', '3');
INSERT INTO `movies_has_rating` VALUES ('30', '1', '3');
INSERT INTO `movies_has_rating` VALUES ('31', '1', '3');
INSERT INTO `movies_has_rating` VALUES ('32', '1', '2');
INSERT INTO `movies_has_rating` VALUES ('33', '1', '1');
INSERT INTO `movies_has_rating` VALUES ('34', '1', '1');
INSERT INTO `movies_has_rating` VALUES ('35', '1', '1');
INSERT INTO `movies_has_rating` VALUES ('36', '1', '2');
INSERT INTO `movies_has_rating` VALUES ('37', '1', '2');
INSERT INTO `movies_has_rating` VALUES ('38', '1', '1');
INSERT INTO `movies_has_rating` VALUES ('39', '1', '2');
INSERT INTO `movies_has_rating` VALUES ('40', '1', '3');
INSERT INTO `movies_has_rating` VALUES ('41', '1', '2');
INSERT INTO `movies_has_rating` VALUES ('42', '1', '3');
INSERT INTO `movies_has_rating` VALUES ('43', '1', '1');
INSERT INTO `movies_has_rating` VALUES ('44', '2', '2');
INSERT INTO `movies_has_rating` VALUES ('45', '2', '2');
INSERT INTO `movies_has_rating` VALUES ('46', '2', '2');
INSERT INTO `movies_has_rating` VALUES ('47', '2', '2');
INSERT INTO `movies_has_rating` VALUES ('48', '2', '2');
INSERT INTO `movies_has_rating` VALUES ('49', '2', '2');
INSERT INTO `movies_has_rating` VALUES ('50', '2', '1');
INSERT INTO `movies_has_rating` VALUES ('51', '2', '1');
INSERT INTO `movies_has_rating` VALUES ('52', '2', '1');
INSERT INTO `movies_has_rating` VALUES ('53', '2', '1');
INSERT INTO `movies_has_rating` VALUES ('54', '2', '1');
INSERT INTO `movies_has_rating` VALUES ('55', '2', '1');
INSERT INTO `movies_has_rating` VALUES ('56', '2', '1');
INSERT INTO `movies_has_rating` VALUES ('57', '2', '1');
INSERT INTO `movies_has_rating` VALUES ('58', '2', '2');
INSERT INTO `movies_has_rating` VALUES ('59', '2', '2');
INSERT INTO `movies_has_rating` VALUES ('60', '2', '2');
INSERT INTO `movies_has_rating` VALUES ('61', '2', '3');
INSERT INTO `movies_has_rating` VALUES ('62', '2', '2');
INSERT INTO `movies_has_rating` VALUES ('63', '2', '3');
INSERT INTO `movies_has_rating` VALUES ('64', '2', '3');
INSERT INTO `movies_has_rating` VALUES ('65', '2', '3');
INSERT INTO `movies_has_rating` VALUES ('66', '2', '3');
INSERT INTO `movies_has_rating` VALUES ('67', '2', '3');
INSERT INTO `movies_has_rating` VALUES ('68', '2', '3');
INSERT INTO `movies_has_rating` VALUES ('69', '2', '3');
INSERT INTO `movies_has_rating` VALUES ('70', '2', '3');
INSERT INTO `movies_has_rating` VALUES ('71', '2', '3');
INSERT INTO `movies_has_rating` VALUES ('72', '2', '3');
INSERT INTO `movies_has_rating` VALUES ('73', '2', '3');
INSERT INTO `movies_has_rating` VALUES ('74', '2', '2');
INSERT INTO `movies_has_rating` VALUES ('75', '2', '2');
INSERT INTO `movies_has_rating` VALUES ('76', '2', '2');
INSERT INTO `movies_has_rating` VALUES ('77', '2', '2');
INSERT INTO `movies_has_rating` VALUES ('78', '2', '2');
INSERT INTO `movies_has_rating` VALUES ('79', '2', '2');
INSERT INTO `movies_has_rating` VALUES ('80', '2', '2');
INSERT INTO `movies_has_rating` VALUES ('81', '2', '2');
INSERT INTO `movies_has_rating` VALUES ('82', '2', '2');
INSERT INTO `movies_has_rating` VALUES ('83', '2', '2');
INSERT INTO `movies_has_rating` VALUES ('84', '2', '1');
INSERT INTO `movies_has_rating` VALUES ('85', '3', '1');
INSERT INTO `movies_has_rating` VALUES ('86', '3', '1');
INSERT INTO `movies_has_rating` VALUES ('87', '3', '1');
INSERT INTO `movies_has_rating` VALUES ('88', '3', '1');
INSERT INTO `movies_has_rating` VALUES ('89', '3', '2');
INSERT INTO `movies_has_rating` VALUES ('90', '3', '3');
INSERT INTO `movies_has_rating` VALUES ('91', '4', '2');
INSERT INTO `movies_has_rating` VALUES ('92', '4', '1');
INSERT INTO `movies_has_rating` VALUES ('93', '4', '2');
INSERT INTO `movies_has_rating` VALUES ('94', '4', '2');
INSERT INTO `movies_has_rating` VALUES ('95', '4', '2');
INSERT INTO `movies_has_rating` VALUES ('96', '4', '3');
INSERT INTO `movies_has_rating` VALUES ('97', '4', '3');
INSERT INTO `movies_has_rating` VALUES ('98', '4', '1');
INSERT INTO `movies_has_rating` VALUES ('99', '4', '1');
INSERT INTO `movies_has_rating` VALUES ('100', '4', '1');
INSERT INTO `movies_has_rating` VALUES ('101', '4', '1');
INSERT INTO `movies_has_rating` VALUES ('102', '4', '2');
INSERT INTO `movies_has_rating` VALUES ('103', '4', '3');
INSERT INTO `movies_has_rating` VALUES ('104', '4', '2');
INSERT INTO `movies_has_rating` VALUES ('105', '4', '3');
INSERT INTO `movies_has_rating` VALUES ('106', '4', '3');
INSERT INTO `movies_has_rating` VALUES ('107', '4', '3');
INSERT INTO `movies_has_rating` VALUES ('108', '4', '2');
INSERT INTO `movies_has_rating` VALUES ('109', '4', '2');
INSERT INTO `movies_has_rating` VALUES ('110', '4', '2');
INSERT INTO `movies_has_rating` VALUES ('111', '5', '2');
INSERT INTO `movies_has_rating` VALUES ('112', '5', '2');
INSERT INTO `movies_has_rating` VALUES ('113', '5', '2');
INSERT INTO `movies_has_rating` VALUES ('114', '5', '2');
INSERT INTO `movies_has_rating` VALUES ('115', '5', '2');
INSERT INTO `movies_has_rating` VALUES ('116', '5', '2');
INSERT INTO `movies_has_rating` VALUES ('117', '5', '2');
INSERT INTO `movies_has_rating` VALUES ('118', '5', '2');
INSERT INTO `movies_has_rating` VALUES ('119', '5', '2');
INSERT INTO `movies_has_rating` VALUES ('120', '5', '3');
INSERT INTO `movies_has_rating` VALUES ('121', '5', '3');
INSERT INTO `movies_has_rating` VALUES ('122', '5', '3');
INSERT INTO `movies_has_rating` VALUES ('123', '5', '3');
INSERT INTO `movies_has_rating` VALUES ('124', '6', '3');
INSERT INTO `movies_has_rating` VALUES ('125', '6', '3');
INSERT INTO `movies_has_rating` VALUES ('130', '8', '3');
INSERT INTO `movies_has_rating` VALUES ('131', '8', '1');
INSERT INTO `movies_has_rating` VALUES ('132', '8', '1');
INSERT INTO `movies_has_rating` VALUES ('133', '8', '1');
INSERT INTO `movies_has_rating` VALUES ('134', '8', '1');
INSERT INTO `movies_has_rating` VALUES ('135', '8', '1');
INSERT INTO `movies_has_rating` VALUES ('136', '8', '1');
INSERT INTO `movies_has_rating` VALUES ('137', '8', '1');
INSERT INTO `movies_has_rating` VALUES ('138', '8', '2');
INSERT INTO `movies_has_rating` VALUES ('139', '8', '3');
INSERT INTO `movies_has_rating` VALUES ('140', '8', '2');
INSERT INTO `movies_has_rating` VALUES ('141', '8', '2');
INSERT INTO `movies_has_rating` VALUES ('142', '8', '2');
INSERT INTO `movies_has_rating` VALUES ('143', '8', '2');
INSERT INTO `movies_has_rating` VALUES ('144', '8', '3');
INSERT INTO `movies_has_rating` VALUES ('145', '8', '3');
INSERT INTO `movies_has_rating` VALUES ('146', '8', '3');
INSERT INTO `movies_has_rating` VALUES ('147', '8', '3');
INSERT INTO `movies_has_rating` VALUES ('148', '8', '3');
INSERT INTO `movies_has_rating` VALUES ('149', '8', '3');
INSERT INTO `movies_has_rating` VALUES ('150', '8', '3');
INSERT INTO `movies_has_rating` VALUES ('151', '8', '3');
INSERT INTO `movies_has_rating` VALUES ('152', '8', '3');
INSERT INTO `movies_has_rating` VALUES ('153', '8', '3');
-- ----------------------------
-- Table structure for users
-- ----------------------------
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`email` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=latin1;
-- ----------------------------
-- Records of users
-- ----------------------------
INSERT INTO `users` VALUES ('1', 'Name user 1', '1#1.com');
INSERT INTO `users` VALUES ('2', 'Name user 2', '2#2.com');
INSERT INTO `users` VALUES ('3', 'Name user 3', '3#3.com');
-- ----------------------------
-- Table structure for votes
-- ----------------------------
DROP TABLE IF EXISTS `votes`;
CREATE TABLE `votes` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1;
-- ----------------------------
-- Records of votes
-- ----------------------------
INSERT INTO `votes` VALUES ('1', 'Very good');
INSERT INTO `votes` VALUES ('2', 'Good');
INSERT INTO `votes` VALUES ('3', 'Regular');
Much appreciate your support, thank you very much.
Your third part isn't clear. But the second part can be solved by:
SELECT
M.name AS title_movie,
M.year AS premiere,
G.name AS gender,
COUNT(MHR.vote_id) AS total_voting,
-- 2)
COUNT(MHR.vote_id = 1 OR NULL) AS count_very_good,
COUNT(MHR.vote_id = 2 OR NULL) AS count_good,
COUNT(MHR.vote_id = 3 OR NULL) AS count_regular
FROM movies M
LEFT JOIN gender G ON M.gender_id = G.id
LEFT JOIN movies_has_rating MHR ON M.id = MHR.movie_id
GROUP BY M.id
ORDER BY M.id DESC
http://sqlfiddle.com/#!9/5ba403/5
I'm sure you know how to calculate the percentages from that result.
Update: So OP asks to determine the vote type with the highest count and calculate its percantage within SQL. You can (but you should not) do it with the folowing query:
SELECT t.*,
CASE
WHEN highest_votes_id = 1
THEN 100 * count_very_good / total_voting
WHEN highest_votes_id = 2
THEN 100 * count_good / total_voting
WHEN highest_votes_id = 3
THEN 100 * count_regular / total_voting
END AS highest_votes_percentage
FROM (
SELECT t.*,
CASE
WHEN count_regular > count_good AND count_regular > count_very_good
THEN 3
WHEN count_good > count_very_good
THEN 2
ELSE 1
END AS highest_votes_id
FROM (
SELECT
M.id,
M.name AS title_movie,
M.year AS premiere,
G.name AS gender,
COUNT(MHR.vote_id) AS total_voting,
COUNT(MHR.vote_id = 1 OR NULL) AS count_very_good,
COUNT(MHR.vote_id = 2 OR NULL) AS count_good,
COUNT(MHR.vote_id = 3 OR NULL) AS count_regular
FROM movies M
LEFT JOIN gender G ON M.gender_id = G.id
LEFT JOIN movies_has_rating MHR ON M.id = MHR.movie_id
GROUP BY M.id
) t
) t
ORDER BY t.id DESC
http://sqlfiddle.com/#!9/5ba403/7
How ever you solve that problem in SQL, you will end up with unreasonable ugly code. You better do it in PHP.
if ($row['count_regular'] > $row['count_good'] &&
$row['count_regular'] > $row['count_very_good']
) {
$highestVoteType = 'Regular';
$highestVoteCount = $row['count_regular'];
} elseif ($row['count_good'] > $row['count_very_good']) {
$highestVoteType = 'Good';
$highestVoteCount = $row['count_good'];
} else {
$highestVoteType = 'Very Good';
$highestVoteCount = $row['count_very_good'];
}
if ($row['total_voting'] != 0) {
$highestVotePercantage = 100 * $highestVoteCount / $row['total_voting'];
} else {
$highestVotePercantage = null;
}
1)
Select movies_has_rating.movie_id,movies.name,count(movies_has_rating.vote_id) FROM movies_has_rating JOIN movies ON movies_has_rating.movied_id=movies.id
I have built a private messaging system and would like to group all id's like this :
With names(ids) and count of messages ,and after click on the user it will open into history of all message history between them .And the new message when arrives will bring the user on top with count increasing along with new message and chat history .How do I do that ?
I have shared this http://sqlfiddle.com/#!2/7b13a/1 .But I am unable to get the code or the procedure to arrive at it.
I really appreciate any help.Thanks in Advance.
Code:
CREATE TABLE if not exists tblA
(
id int(11) NOT NULL auto_increment ,
sender varchar(255),
receiver varchar(255),
msg varchar(255),
date timestamp,
PRIMARY KEY (id)
);
INSERT INTO tblA (sender, receiver,msg,date ) VALUES
('1', '2', 'buzz ...','2011-08-21 14:11:09'),
('1', '2', 'test ...','2011-08-21 14:12:19'),
('1', '2', 'check ...','2011-08-21 14:13:29'),
('1', '1', 'test2 ...','2011-08-21 14:14:09'),
('2', '1', 'check2 ...','2011-08-21 14:15:09'),
('2', '1', 'test3 ...','2011-08-21 14:16:09'),
('1', '2', 'buzz ...','2011-08-21 14:17:09'),
('1', '2', 'test ...','2011-08-21 14:18:19'),
('1', '2', 'check ...','2011-08-21 14:19:29'),
('1', '1', 'test2 ...','2011-08-21 14:10:09'),
('3', '1', 'check2 ...','2011-08-21 14:21:09'),
('3', '1', 'test3 ...','2011-08-21 14:22:09'),
('3', '2', 'buzz ...','2011-08-21 14:24:09'),
('3', '2', 'test ...','2011-08-21 14:25:19'),
('1', '3', 'check ...','2011-08-21 14:26:29'),
('1', '3', 'test2 ...','2011-08-21 14:27:09'),
('2', '3', 'check2 ...','2011-08-21 14:28:09'),
('2', '3', 'test3 ...','2011-08-21 14:29:09'),
('1', '2', 'check3 ...','2011-08-21 14:23:09');
Summarizing:
1.Group all users seperately with all their msgs and count ORDER BY date DESC
For EG:
A new feature is to group these messages like Facebook in one. Let's say:
user A is sending user B a message
user B is replying to A
User A is sending user C a Message
user D is sending user A a message
So user A must have three blocks of users : B, C, D. for the display.
B includes (1,2), C includes (3) and D includes (4), even if C is not replying to A (3) and A not to D (4).
Also on click of each user it will open their messaging history.
I am using the code below to retrieve the latest data w.r.t all users .But if the user had points added at the same time stamp then I would like to get the last entry not both like in the example below.How do I make sure that I get latest entry even if 2 records have same timestamp.
http://sqlfiddle.com/#!2/374db/1
I really appreciate any help.Thanks in Advance.
CREATE TABLE if not exists tblA
(
id int(11) NOT NULL auto_increment ,
sender varchar(255),
receiver varchar(255),
msg varchar(255),
date timestamp,
points varchar(255),
refno varchar(255),
PRIMARY KEY (id)
);
CREATE TABLE if not exists tblB
(
id int(11) NOT NULL auto_increment ,
sno varchar(255),
name varchar(255),
PRIMARY KEY (id)
);
CREATE TABLE if not exists tblC
(
id int(11) NOT NULL auto_increment ,
data varchar(255),
refno varchar(255),
extrarefno varchar(255),
PRIMARY KEY (id)
);
INSERT INTO tblA (sender, receiver,msg,date,points,refno ) VALUES
('1', '2', 'buzz ...','2011-08-21 14:11:09','10','001'),
('1', '2', 'test ...','2011-08-21 14:12:19','20','002'),
('4', '2', 'test ...','2011-08-21 14:13:19','30','003'),
('1', '3', 'buzz ...','2011-08-21 14:11:09','10','004'),
('1', '3', 'test ...','2011-08-21 14:12:19','20','005'),
('1', '4', 'buzz ...','2011-08-21 14:11:09','10','006'),
('1', '4', 'test ...','2011-08-21 14:12:19','20','007'),
('3', '4', 'test ...','2011-08-21 14:13:19','20','008'),
('2', '4', 'test ...','2011-08-21 14:13:19','20','009');
INSERT INTO tblB (sno, name ) VALUES
('1', 'Aa'),
('2', 'Bb'),
('3', 'Cc'),
('4', 'Dd'),
('5', 'Ee'),
('6', 'Ff'),
('7', 'Gg'),
('8', 'Hh');
INSERT INTO tblC (data,refno,extrarefno ) VALUES
('data1', '001', '101'),
('data2', '002', '102'),
('data3', '003', '103'),
('data4', '004', '101'),
('data5', '005', '102'),
('data6', '006', '103'),
('data7', '007', '101'),
('data8', '008', '101'),
('data9', '009', '101');
///
query:
SELECT *
FROM (
SELECT tblB.*, MAX(tblA.date) AS date
FROM tblB
JOIN tblA ON tblB.sno = tblA.receiver
GROUP BY tblB.sno
) AS subset
JOIN tblA ON subset.sno = tblA.receiver
AND subset.date = tblA.date JOIN tblC ON tblA.refno=tblC.refno
The key idea is to use the id column instead of the date column. It is auto-incremented, so the biggest id should be more recent.
However, your query has another problem which is the join to tblB in the subquery. Arbitrary ("indeterminate") values from tblB would be returned in the outer query. Instead, just aggregate on tblA and move the join to tblB to the outer level:
SELECT *
FROM (SELECT tblA.receiver, MAX(tblA.id) AS id
FROM tblA
GROUP BY tblA.receiver
) subset JOIN
tblA
ON subset.receiver = tblA.receiver AND subset.id = tblA.id JOIN
tblB
on tblA.receiver = tblB.sno join
tblC
ON tblA.refno=tblC.refno ;
Order by the date AND the id. The id is set to auto increment, if the date is the same, you can assume the higher id was created after.
ORDER BY date, id
How can I rank the users below based on points .I really appreciate any help.
Thanks in Advance .
http://sqlfiddle.com/#!2/374db/11
CREATE TABLE if not exists tblA
(
id int(11) NOT NULL auto_increment ,
sender varchar(255),
receiver varchar(255),
msg varchar(255),
date timestamp,
points varchar(255),
refno varchar(255),
PRIMARY KEY (id)
);
CREATE TABLE if not exists tblB
(
id int(11) NOT NULL auto_increment ,
sno varchar(255),
name varchar(255),
PRIMARY KEY (id)
);
CREATE TABLE if not exists tblC
(
id int(11) NOT NULL auto_increment ,
data varchar(255),
refno varchar(255),
extrarefno varchar(255),
PRIMARY KEY (id)
);
INSERT INTO tblA (sender, receiver,msg,date,points,refno ) VALUES
('1', '2', 'buzz ...','2011-08-21 14:11:09','10','001'),
('1', '2', 'test ...','2011-08-21 14:12:19','20','002'),
('4', '2', 'test ...','2011-08-21 14:13:19','30','003'),
('1', '3', 'buzz ...','2011-08-21 14:11:09','10','004'),
('1', '3', 'test ...','2011-08-21 14:12:19','20','005'),
('1', '4', 'buzz ...','2011-08-21 14:11:09','10','006'),
('1', '4', 'test ...','2011-08-21 14:12:19','20','007'),
('3', '4', 'test ...','2011-08-21 14:13:19','20','008'),
('2', '4', 'test ...','2011-08-21 14:13:19','20','009');
INSERT INTO tblB (sno, name ) VALUES
('1', 'Aa'),
('2', 'Bb'),
('3', 'Cc'),
('4', 'Dd'),
('5', 'Ee'),
('6', 'Ff'),
('7', 'Gg'),
('8', 'Hh');
INSERT INTO tblC (data,refno,extrarefno ) VALUES
('data1', '001', '101'),
('data2', '002', '102'),
('data3', '003', '103'),
('data4', '004', '101'),
('data5', '005', '102'),
('data6', '006', '103'),
('data7', '007', '101'),
('data8', '008', '101'),
('data9', '009', '101');
sql
SELECT *
FROM (SELECT tblA.receiver, MAX(tblA.id) AS id
FROM tblA
GROUP BY tblA.receiver
) subset JOIN
tblA
ON subset.receiver = tblA.receiver AND subset.id = tblA.id JOIN
tblB
on tblA.receiver = tblB.sno join
tblC
ON tblA.refno=tblC.refno ;
You can order the results of a query using ORDER BY. So, you can rank the rows in tblA as follows:
SELECT *
FROM tblA
ORDER BY points
However, I notice you are using varchar for the points column. If this is to hold a numerical value you probably want int or float.