How do I best combine and optimize these two queries? - mysql

Here is my main query which pulls in thread information as one row, it lacks the # of votes and currently I'm pulling that in with a second query.
SELECT Group_concat(t.tag_name) AS `tags`,
`p`.`thread_id`,
`p`.`thread_name`,
`p`.`thread_description`,
`p`.`thread_owner_id`,
`p`.`thread_view_count`,
`p`.`thread_reply_count`,
`p`.`thread_comment_count`,
`p`.`thread_favorite_count`,
`p`.`thread_creation_date`,
`p`.`thread_type_id`,
`p`.`thread_edited_date`,
`u`.*,
`x`.*,
`t`.*
FROM `shoop_posts` AS `p`
INNER JOIN `shoop_users` AS `u`
ON u.user_id = p.thread_owner_id
LEFT JOIN `shoop_tags_map` AS `x`
ON x.thread_id = p.thread_id
LEFT JOIN `shoop_tags` AS `t`
ON t.tag_id = x.tag_id
WHERE (p.thread_id = '1')
GROUP BY `p`.`thread_id`
My second query which pulls in the # of votes per thread:
SELECT Sum(vote_value)
FROM shoop_votes
INNER JOIN shoop_vote_codes
ON shoop_votes.vote_type = shoop_vote_codes.vote_type
WHERE thread_id = 1
AND shoop_votes.vote_type = 3
OR shoop_votes.vote_type = 2
A vote type of 2 is an upvote, 3 is a downvote. Here's the schema if you need it, and some sample data:
CREATE TABLE `shoop_posts` (
`thread_id` int(11) unsigned NOT NULL auto_increment,
`thread_name` text,
`thread_description` text,
`thread_parent_id` int(11) default NULL,
`thread_owner_id` int(11) default NULL,
`thread_view_count` int(11) default NULL,
`thread_reply_count` int(11) default NULL,
`thread_comment_count` int(11) default NULL,
`thread_favorite_count` int(11) default NULL,
`thread_creation_date` timestamp NULL default NULL,
`thread_type_id` int(11) default NULL,
`thread_edited_date` timestamp NULL default NULL,
PRIMARY KEY (`thread_id`)
) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of shoop_posts
-- ----------------------------
INSERT INTO `shoop_posts` VALUES ('1', 'Shoop that', '\r\n<img class=\"image-shoop\" src=\"\">\r\n\r\n<p>test:<br>\r\n\r\n\r\n</p>', null, '2', '217', '0', '0', '0', '2010-01-10 02:06:25', '1', null);
-- ----------------------------
-- Table structure for `shoop_tags`
-- ----------------------------
CREATE TABLE `shoop_tags` (
`tag_id` int(11) NOT NULL auto_increment,
`tag_name` varchar(11) default NULL,
PRIMARY KEY (`tag_id`)
) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of shoop_tags
-- ----------------------------
INSERT INTO `shoop_tags` VALUES ('1', 'mma');
INSERT INTO `shoop_tags` VALUES ('2', 'strikeforce');
INSERT INTO `shoop_tags` VALUES ('3', 'ufc');
-- ----------------------------
-- Table structure for `shoop_tags_map`
-- ----------------------------
DROP TABLE IF EXISTS `shoop_tags_map`;
CREATE TABLE `shoop_tags_map` (
`map_id` int(11) NOT NULL auto_increment,
`tag_id` int(11) default NULL,
`thread_id` int(11) default NULL,
PRIMARY KEY (`map_id`)
) ENGINE=MyISAM AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of shoop_tags_map
-- ----------------------------
INSERT INTO `shoop_tags_map` VALUES ('1', '1', '1');
INSERT INTO `shoop_tags_map` VALUES ('2', '2', '2');
INSERT INTO `shoop_tags_map` VALUES ('3', '1', '2');
INSERT INTO `shoop_tags_map` VALUES ('4', '3', '1');
INSERT INTO `shoop_tags_map` VALUES ('5', '3', '2');
-- ----------------------------
-- Table structure for `shoop_vote_codes`
-- ----------------------------
CREATE TABLE `shoop_vote_codes` (
`vote_type` smallint(1) NOT NULL default '0',
`vote_value` smallint(2) default NULL,
PRIMARY KEY (`vote_type`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of shoop_vote_codes
-- ----------------------------
INSERT INTO `shoop_vote_codes` VALUES ('2', '1');
INSERT INTO `shoop_vote_codes` VALUES ('3', '-1');
-- ----------------------------
-- Table structure for `shoop_votes`
-- ----------------------------
DROP TABLE IF EXISTS `shoop_votes`;
CREATE TABLE `shoop_votes` (
`thread_id` int(11) NOT NULL default '0',
`user_id` int(11) NOT NULL default '0',
`vote_type` smallint(1) NOT NULL default '0',
PRIMARY KEY (`thread_id`,`user_id`,`vote_type`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of shoop_votes
-- ----------------------------
INSERT INTO `shoop_votes` VALUES ('1', '1', '2');
INSERT INTO `shoop_votes` VALUES ('1', '2', '2');
INSERT INTO `shoop_votes` VALUES ('1', '3', '3');

If I understand you correctly, just using a subquery will do what you're after:
SELECT Group_concat(t.tag_name) AS `tags`,
`p`.`thread_id`,
`p`.`thread_name`,
`p`.`thread_description`,
`p`.`thread_owner_id`,
`p`.`thread_view_count`,
`p`.`thread_reply_count`,
`p`.`thread_comment_count`,
`p`.`thread_favorite_count`,
`p`.`thread_creation_date`,
`p`.`thread_type_id`,
`p`.`thread_edited_date`,
`u`.*,
`x`.*,
`t`.*,
`v`.VoteTotal
FROM `shoop_posts` AS `p`
INNER JOIN `shoop_users` AS `u`
ON u.user_id = p.thread_owner_id
LEFT JOIN `shoop_tags_map` AS `x`
ON x.thread_id = p.thread_id
LEFT JOIN `shoop_tags` AS `t`
ON t.tag_id = x.tag_id
LEFT JOIN (SELECT thread_id, Sum(vote_value) as VoteTotal
FROM shoop_votes
INNER JOIN shoop_vote_codes
ON shoop_votes.vote_type = shoop_vote_codes.vote_type
WHERE shoop_votes.vote_type = 3
OR shoop_votes.vote_type = 2
GROUP BY thread_id) as `v`
ON p.thread_id = v.thread_id
WHERE (p.thread_id = '1')
GROUP BY `p`.`thread_id`
This will let you get all threads as well if you just leave off where last where p.thread_id clause.

Related

Mysql find users after table pattern

I have the following five tables:
users: id, name
region: id, usersId, region
country: id, usersId, country
status: id, usersId, status
search: id, usersId, region, country, status
The search table includes the given data after what we will search in the other tables.
So, if the search-table has 5 users from 'DE', 'US', 'CH' ... with different or same zipcodes, all users from users, region, country and status should be displayed, where this pattern is true
For example:
I have 10 users in my database and the user with the user.id = 1 stores his data in search-table:
users:
id:8, "John"
search:
id: 8, usersId:1, region: 47798, country: "DE", status: "Boss"
Now i want all other user who comes from 'DE' from the region LIKE "4%" and who works as a "Boss" :-)
This is my database:
SET NAMES utf8;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for `country`
-- ----------------------------
DROP TABLE IF EXISTS `country`;
CREATE TABLE `country` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`usersId` int(11) NOT NULL,
`country` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1;
-- ----------------------------
-- Records of `country`
-- ----------------------------
BEGIN;
INSERT INTO `country` VALUES ('1', '1', 'US'), ('2', '2', 'US'), ('3', '3', 'AUT'), ('4', '4', 'DE'), ('5', '5', 'DE'), ('6', '6', 'CH');
COMMIT;
-- ----------------------------
-- Table structure for `region`
-- ----------------------------
DROP TABLE IF EXISTS `region`;
CREATE TABLE `region` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`usersId` int(11) NOT NULL,
`region` varchar(150) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1;
-- ----------------------------
-- Records of `region`
-- ----------------------------
BEGIN;
INSERT INTO `region` VALUES ('1', '1', '47798'), ('2', '2', '47798'), ('3', '3', '444'), ('4', '4', '78965'), ('5', '5', '7856'), ('6', '6', '7856');
COMMIT;
-- ----------------------------
-- Table structure for `search`
-- ----------------------------
DROP TABLE IF EXISTS `search`;
CREATE TABLE `search` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`country` varchar(100) NOT NULL,
`usersId` int(11) NOT NULL,
`region` varchar(100) NOT NULL,
`status` varchar(150) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1;
-- ----------------------------
-- Records of `search`
-- ----------------------------
BEGIN;
INSERT INTO `search` VALUES ('1', 'US', '1', '47798', 'Angestellter'), ('2', 'US', '2', '79653', 'Angestellter'), ('3', 'AUT', '3', '444', 'Chef'), ('4', 'DE', '4', '78965', 'Gesellschafter'), ('5', 'DE', '5', '7856', 'Vertrieb'), ('6', 'DE', '6', '47798', 'Angestellter');
COMMIT;
-- ----------------------------
-- Table structure for `status`
-- ----------------------------
DROP TABLE IF EXISTS `status`;
CREATE TABLE `status` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`usersId` int(11) NOT NULL,
`status` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1;
-- ----------------------------
-- Records of `status`
-- ----------------------------
BEGIN;
INSERT INTO `status` VALUES ('1', '1', 'Angestellter'), ('2', '2', 'Angestellter'), ('3', '3', 'Chef'), ('4', '4', 'Gesellschafter'), ('5', '5', 'Vertrieb'), ('6', '6', 'Vertrieb');
COMMIT;
-- ----------------------------
-- Table structure for `users`
-- ----------------------------
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT;
-- ----------------------------
-- Records of `users`
-- ----------------------------
BEGIN;
INSERT INTO `users` VALUES ('1', 'Heinz'), ('2', 'Karl'), ('3', 'Helmut'), ('4', 'Viktor'), ('5', 'Thomas'), ('6', 'Kurt');
COMMIT;
SET FOREIGN_KEY_CHECKS = 1;
And this is my Select, what not working correctly, i only geht the search-table entries:
select * from users
inner join region on users.id=region.usersid
inner join country on users.id=country.usersid
inner join status on users.id=status.usersid
where users.id in (select usersId from search where country = 'DE' AND region LIKE '7%');
You can use the following query (modified the select you were using in your question):
select * from users
inner join search
on search.usersid = users.id
where country = 'DE' AND region LIKE '7%'
You can change the where clause as per your requirement.
Also, it is a good practice to maintain consistency in nomenclature of the columns within different tables especially the primary keys/identity columns. For example: In your table definition, Id in users table but usersId in search table.

MySQL - Remove duplicate records entity relationship many to many

As I can get records from multiple tables omitting duplicate, for example I have this table "code attached tables":
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for interests
-- ----------------------------
DROP TABLE IF EXISTS `interests`;
CREATE TABLE `interests` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(45) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of interests
-- ----------------------------
INSERT INTO `interests` VALUES ('1', 'Sport');
INSERT INTO `interests` VALUES ('2', 'Technology');
INSERT INTO `interests` VALUES ('3', 'Games');
INSERT INTO `interests` VALUES ('4', 'Security');
INSERT INTO `interests` VALUES ('5', 'Movies');
-- ----------------------------
-- Table structure for interests_has_user
-- ----------------------------
DROP TABLE IF EXISTS `interests_has_user`;
CREATE TABLE `interests_has_user` (
`interests_id` int(10) unsigned NOT NULL,
`user_id` int(10) unsigned NOT NULL,
PRIMARY KEY (`interests_id`,`user_id`),
KEY `fk_interests_has_user_user1_idx` (`user_id`),
KEY `fk_interests_has_user_interests_idx` (`interests_id`),
CONSTRAINT `fk_interests_has_user_interests` FOREIGN KEY (`interests_id`) REFERENCES `interests` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `fk_interests_has_user_user1` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of interests_has_user
-- ----------------------------
INSERT INTO `interests_has_user` VALUES ('1', '1');
INSERT INTO `interests_has_user` VALUES ('2', '1');
INSERT INTO `interests_has_user` VALUES ('3', '1');
INSERT INTO `interests_has_user` VALUES ('4', '1');
INSERT INTO `interests_has_user` VALUES ('5', '1');
-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(45) DEFAULT NULL,
`email` varchar(45) DEFAULT NULL,
`password` varchar(45) DEFAULT NULL,
`country` varchar(45) DEFAULT NULL,
`state` varchar(45) DEFAULT NULL,
`city` varchar(45) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES ('1', 'Name', 'email#email.com', '123123', '1', '1', '1');
I need to get records from the table[ user ] and the table[ interests_has_user ], where a user can have many interests at the table table[ interests_has_user ], I'm doing the query this way:
SELECT
user.id,
user.name,
user.email,
user.country,
user.state,
user.city,
interests_has_user.interests_id,
interests_has_user.user_id
FROM
user
LEFT JOIN interests_has_user
ON user.id = interests_has_user.user_id
WHERE user.id = 1;
And I throw all records of the table table[ interests_has_user ], but in all rows the user is repeated, image attached with the result.
Note: What is shaded in yellow should be empty or null fields.
What the best solution for this, use INNER JOIN, or separate consutas.
I appreciate your help, thank you very much.
INNER JOIN will not return users without interests. So it is not what you want.
If you want to lighten-up the query results you could do two queries:
First find out the user details
SELECT
user.id,
user.name,
user.email,
user.country,
user.state,
user.city
FROM
user
WHERE user.id = 1
Then the interests ids.
SELECT user.id, interests_has_user.interests_id, interests_has_user.user_id
FROM user
LEFT JOIN interests_has_user ON user.id = interests_has_user.user_id
WHERE user.id = 1

MySQL Group_concat result IN given numbers

I'm trying to find out, if any number in a group_concat result is in a given set of numbers.
This example data can be used to try it out:
CREATE TABLE `events` (
`eventid` int(11) NOT NULL AUTO_INCREMENT,
`eventname` varchar(255) DEFAULT NULL,
PRIMARY KEY (`eventid`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1;
-- ----------------------------
-- Records of `events`
-- ----------------------------
BEGIN;
INSERT INTO `events` VALUES ('1', 'my event');
COMMIT;
-- ----------------------------
-- Table structure for `events2groups`
-- ----------------------------
CREATE TABLE `events2groups` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`eventid` int(11) DEFAULT NULL,
`groupid` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1;
-- ----------------------------
-- Records of `events2groups`
-- ----------------------------
BEGIN;
INSERT INTO `events2groups` VALUES ('1', '1', '5'), ('2', '1', '3'), ('3', '1', '1');
COMMIT;
-- ----------------------------
-- Table structure for `groups`
-- ----------------------------
CREATE TABLE `groups` (
`groupid` int(11) NOT NULL AUTO_INCREMENT,
`groupname` varchar(255) DEFAULT NULL,
PRIMARY KEY (`groupid`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=latin1;
-- ----------------------------
-- Records of `groups`
-- ----------------------------
BEGIN;
INSERT INTO `groups` VALUES ('1', 'group1'), ('2', 'group2'), ('3', 'group3'), ('4', 'group4'), ('5', 'group5');
COMMIT;
SET FOREIGN_KEY_CHECKS = 1;
Then fire this query:
SELECT GROUP_CONCAT(groups.groupid),
IF ( GROUP_CONCAT(groups.groupid) IN (1,2,3), 'yes', 'no' ) as isInGroup
FROM `events`
LEFT JOIN events2groups ON events.eventid = events2groups.eventid
LEFT JOIN groups ON events2groups.groupid = groups.groupid
GROUP BY events.eventid
the first result column shows, that the event has the groups 5, 3 and 1.
The user has the groups 1, 2 and 3, so the 3 and the 1 match. How can I query this to get the 'yes' from the IF?
Why use the group_concat() results? Just use conditional aggregation:
SELECT GROUP_CONCAT(groups.groupid),
(case when max(groups.group_id in (1, 2, 3)) > 0 then 'yes' else 'no'
end) as isInGroup
FROM `events` LEFT JOIN
events2groups
ON events.eventid = events2groups.eventid LEFT JOIN
groups
ON events2groups.groupid = groups.groupid
GROUP BY events.eventid;
SELECT GROUP_CONCAT(groups.groupid),
GROUP_CONCAT(case when groups.groupid IN (1,2,3) then 'yes' else 'no' end) as isInGroup
FROM `events`
LEFT JOIN events2groups ON events.eventid = events2groups.eventid
LEFT JOIN groups ON events2groups.groupid = groups.groupid
GROUP BY events.eventid
;
result
no,yes,yes

MySQL: Select records where joined table matches ALL values

I'm trying to find all employees with multiple skills. Here are the tables:
CREATE TABLE IF NOT EXISTS `Employee` (
`ID` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`Name` varchar(100) DEFAULT NULL,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=3 ;
INSERT INTO `Employee` (`ID`, `Name`, `Region_ID`) VALUES (1, 'Fred Flintstone'), (2, 'Barney Rubble');
CREATE TABLE IF NOT EXISTS `Skill` (
`ID` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`Name` varchar(100) DEFAULT NULL,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=3 ;
INSERT INTO `Skill` (`ID`, `Name`) VALUES (1, 'PHP'), (2, 'JQuery');
CREATE TABLE IF NOT EXISTS `Emp_Skills` (
`ID` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`Emp_ID` bigint(20) unsigned NOT NULL DEFAULT '0',
`Skill_ID` bigint(20) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=5 ;
INSERT INTO `Emp_Skills` (`ID`, `Emp_ID`, `Skill_ID`) VALUES (1, 1, 1), (2, 1, 2), (3, 2, 1);
Here is the query I have so far:
SELECT DISTINCT(em.ID), em.Name
FROM Employee em
INNER JOIN Emp_Skills es ON es.Emp_ID = em.ID
WHERE es.Skill_ID IN ('1', '2')
This returns both employees, however, I need to find the employee that has both skills (ID 1 and 2).
Any ideas? Thanks
This will do it:
SELECT EmpId, Name
FROM
(
SELECT em.ID as EmpId, em.Name, es.ID as SkillID
FROM Employee em
INNER JOIN Emp_Skills es ON es.Emp_ID = em.ID
WHERE es.Skill_ID IN ('1', '2')
) X
GROUP BY EmpID, Name
HAVING COUNT(DISTINCT SkillID) = 2;
Fiddle here:
The distinct is just in case the same employee has the skill listed twice.
Thanks for the test data.
You can do this with aggregation and a having clause:
SELECT em.ID, em.Name
FROM Employee em INNER JOIN
Emp_Skills es
ON es.Emp_ID = em.ID
GROUP BY em.id, em.name
HAVING sum(es.Skill_id = '1') > 0 and
sum(es.Skill_id = '2') > 0;
Each condition in the having clause counts the number of rows for each employee that have a particular skill. The filter guarantees that both skills are present.

how to get vistors_sum and reviews_count in 3 table?

how to get vistors_sum and reviews_count in 3 table ?
see the bellow codes, how to get my result in one sql?
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for `a`
-- ----------------------------
DROP TABLE IF EXISTS `a`;
CREATE TABLE `a` (
`products_id` int(11) NOT NULL,
`products_name` varchar(255) default NULL,
PRIMARY KEY (`products_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of a
-- ----------------------------
INSERT INTO `a` VALUES ('1', 'jimmy');
INSERT INTO `a` VALUES ('2', 'tina');
INSERT INTO `a` VALUES ('3', 'emma');
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for `b`
-- ----------------------------
DROP TABLE IF EXISTS `b`;
CREATE TABLE `b` (
`id` int(11) NOT NULL auto_increment,
`products_id` int(11) NOT NULL,
`vistors` int(11) NOT NULL,
`date` date default NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of b
-- ----------------------------
INSERT INTO `b` VALUES ('1', '1', '1', '2013-11-13');
INSERT INTO `b` VALUES ('2', '1', '2', '2013-11-04');
INSERT INTO `b` VALUES ('3', '2', '1', '2013-11-13');
INSERT INTO `b` VALUES ('4', '2', '3', '2013-11-13');
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for `c`
-- ----------------------------
DROP TABLE IF EXISTS `c`;
CREATE TABLE `c` (
`id` int(11) NOT NULL auto_increment,
`products_id` int(11) NOT NULL,
`review_content` varchar(255) default NULL,
`date` date default NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of c
-- ----------------------------
INSERT INTO `c` VALUES ('1', '1', 'hello', '2013-11-13');
INSERT INTO `c` VALUES ('2', '1', 'world', '2013-11-13');
INSERT INTO `c` VALUES ('3', '2', 'good', '2013-11-12');
INSERT INTO `c` VALUES ('4', '3', 'boy', '2013-11-13');
this code bellow can do but the date condition is in sub children temp table. this make the sql not flexible (if I want to query any time not 2013-11-13)
select
a.products_id,
a.products_name,
b.vistors_sum,
c.reviews_count
from
a
left join
(
select
b.products_id,
b.date,
sum(b.vistors) as vistors_sum
from b
where b.date = '2013-11-13'
group by b.products_id
) as b on a.products_id = b.products_id
left join
(
select
c.products_id,
count(c.products_id) as reviews_count
from c
where c.date = '2013-11-13'
group by c.products_id
) as c on a.products_id = c.products_id
SQLFiddle demo
select a.products_id,
products_name,
COALESCE(b.sum_visitors,0) as sum_visitors,
COALESCE(c.count_comments,0) as count_comments
from a
left join
( SELECT products_id,sum(vistors) as sum_visitors
FROM b
WHERE date='2013-11-13'
GROUP BY products_id
) as b
on (a.products_id=b.products_id)
left join
(
SELECT products_id,count(*) as count_comments
FROM c
WHERE date='2013-11-13'
GROUP BY products_id
) as c
on (a.products_id=c.products_id)