how to get vistors_sum and reviews_count in 3 table? - mysql

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)

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 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

how can i query all records in mysql where field is not empty or null?

how can i query all records in mysql where field is not empty or null?
such as bellow, some products_name is empty ,and some is null , how to get other has values records?
-- ----------------------------
-- 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', 'hello');
INSERT INTO `a` VALUES ('2', '222');
INSERT INTO `a` VALUES ('3', null);
INSERT INTO `a` VALUES ('4', '');
INSERT INTO `a` VALUES ('5', '5555');
You could just do:
SELECT * FROM `a` WHERE `products_name` IS NOT NULL AND `products_name` != '';
You can express it succinctly as:
SELECT * FROM a
WHERE ifnull(products_name, '') != ''

Showing all categories for every product for which it belongs to in one query

how can i get the result as bellow in mysql?
I want to get all products group by id and show what categories it belongs to.
how can I get it 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', 'hello');
INSERT INTO `a` VALUES ('2', 'world');
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for `b`
-- ----------------------------
DROP TABLE IF EXISTS `b`;
CREATE TABLE `b` (
`products_id` int(11) NOT NULL,
`categories_id` int(11) NOT NULL,
PRIMARY KEY (`products_id`,`categories_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of b
-- ----------------------------
INSERT INTO `b` VALUES ('1', '1');
INSERT INTO `b` VALUES ('1', '2');
INSERT INTO `b` VALUES ('2', '1');
INSERT INTO `b` VALUES ('2', '3');
This is what you want?
SELECT a.products_id, a.products_name,
GROUP_CONCAT(CONVERT(b.categories_id,CHAR(8))) as products_to_categories
FROM a,b
WHERE a.products_id = b.products_id
GROUP BY a.products_id, a.products_name
fiddle at http://www.sqlfiddle.com/#!2/39edfc/3/0
Resulting image in fiddle
there are alternative way by using inner join, cheer =)
SELECT a.products_id, a.products_name,group_concat(b.categories_id)
FROM a
INNER JOIN b ON a.products_id = b.products_id
group by a.products_id, a.products_name

How do I best combine and optimize these two queries?

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.