简体   繁体   中英

how to get mysql query with reviews count and sum

I'm using below tables...

CREATE TABLE IF NOT EXISTS `cuisine` (
  `cuisine_id` int(5) NOT NULL AUTO_INCREMENT,
  `cuisine_name` varchar(100) CHARACTER SET utf8 NOT NULL,
  `addeddate` datetime NOT NULL,
  PRIMARY KEY (`cuisine_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ROW_FORMAT=DYNAMIC AUTO_INCREMENT=30 ;

--

-- Dumping data for table cuisine

INSERT INTO `cuisine` (`cuisine_id`, `cuisine_name`, `addeddate`) VALUES
(1, 'Lebanese', '2012-06-18 18:57:48'),
(2, 'Græsk', '2012-06-18 18:58:03'),
(3, 'Spansk', '2012-06-18 18:58:11'),
(4, 'Japansk', '2012-06-18 18:58:18'),
(5, 'Mexicansk', '2012-06-18 18:58:27'),
(6, 'Thai', '2012-06-18 18:58:37'),
(7, 'Indisk', '2012-06-18 18:58:43'),
(8, 'Kinesisk', '2012-06-18 18:58:50'),
(9, 'Italiensk', '2012-06-18 18:58:56'),
(10, 'Fransk', '2012-06-18 18:59:02'),
(22, 'Tyrkisk', '2013-05-28 11:40:40'),
(23, 'Amerikansk', '2013-07-04 22:03:04'),
(24, 'Dansk', '2013-07-04 22:23:05'),
(25, 'Tandhoori', '2013-07-15 07:02:34'),
(29, 'tanish', '2013-11-12 04:57:02');

--

-- Table structure for table restaurants

CREATE TABLE IF NOT EXISTS `restaurants` (
  `restaurant_id` int(11) NOT NULL AUTO_INCREMENT,
  `restaurant_name` varchar(100) CHARACTER SET latin1 NOT NULL,
  PRIMARY KEY (`restaurant_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ROW_FORMAT=DYNAMIC AUTO_INCREMENT=125 ;

--

-- Dumping data for table restaurants

INSERT INTO `restaurants` (`restaurant_id`, `restaurant_name`) VALUES
(9, 'Demo Restaurant'),
(21, 'Adria Pizza'),
(22, 'Triumf Pizza Cafe'),
(23, 'Faxe Pizza'),
(24, 'Amager By Night'),
(28, 'Cafe Station'),
(29, 'La Rosa Pizzeria og Grill');

--

-- Table structure for table reviews

CREATE TABLE IF NOT EXISTS `reviews` (
  `rating_id` int(11) NOT NULL AUTO_INCREMENT,
  `restaurant_id` int(11) NOT NULL,
  `rating` int(11) NOT NULL,
  PRIMARY KEY (`rating_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ROW_FORMAT=DYNAMIC AUTO_INCREMENT=137 ;

--

-- Dumping data for table reviews

INSERT INTO `reviews` (`rating_id`, `restaurant_id`, `rating`) VALUES
(108, 29, 3),
(109, 21, 5),
(127, 9, 5),
(128, 9, 5);

--

-- Table structure for table serving_cuisines

CREATE TABLE IF NOT EXISTS `serving_cuisines` (
  `sercuis_id` int(11) NOT NULL AUTO_INCREMENT,
  `restaurant_id` int(11) NOT NULL,
  `cuisine_id` int(11) NOT NULL,
  `status` enum('0','1') CHARACTER SET latin1 NOT NULL DEFAULT '1',
  `addeddate` datetime NOT NULL,
  PRIMARY KEY (`sercuis_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ROW_FORMAT=FIXED AUTO_INCREMENT=6245 ;

--

-- Dumping data for table serving_cuisines

INSERT INTO `serving_cuisines` (`sercuis_id`, `restaurant_id`, `cuisine_id`, `status`, `addeddate`) VALUES
(1901, 11, 7, '1', '2013-08-08 15:25:40'),
(6194, 21, 22, '1', '2016-04-14 11:27:39'),
(6193, 21, 5, '1', '2016-04-14 11:27:39'),
(6192, 21, 9, '1', '2016-04-14 11:27:39'),
(5823, 22, 22, '1', '2014-09-22 13:50:47'),
(5822, 22, 5, '1', '2014-09-22 13:50:47'),
(5783, 23, 5, '1', '2014-09-19 18:30:30'),
(5782, 23, 9, '1', '2014-09-19 18:30:30'),
(2625, 25, 5, '1', '2013-11-29 13:58:15'),
(2624, 25, 9, '1', '2013-11-29 13:58:15'),
(753, 26, 9, '1', '2013-06-16 18:21:18'),
(754, 26, 5, '1', '2013-06-16 18:21:18'),
(2009, 27, 5, '1', '2013-08-22 17:11:25'),
(2008, 27, 9, '1', '2013-08-22 17:11:25'),
(5703, 28, 22, '1', '2014-09-16 01:00:26'),
(5702, 28, 5, '1', '2014-09-16 01:00:26'),
(5713, 29, 22, '1', '2014-09-16 01:07:11'),
(5712, 29, 5, '1', '2014-09-16 01:07:11'),
(6244, 9, 22, '1', '2016-09-19 14:09:22'),
(6243, 9, 5, '1', '2016-09-19 14:09:22'),
(6242, 9, 9, '1', '2016-09-19 14:09:22'),
(6241, 9, 24, '1', '2016-09-19 14:09:22'),
(6240, 9, 23, '1', '2016-09-19 14:09:22'),
(5711, 29, 9, '1', '2014-09-16 01:07:11'),
(5710, 29, 24, '1', '2014-09-16 01:07:11'),
(5709, 29, 23, '1', '2014-09-16 01:07:11'),
(6191, 21, 24, '1', '2016-04-14 11:27:39'),
(6190, 21, 23, '1', '2016-04-14 11:27:39'),
(5582, 24, 22, '1', '2014-09-05 13:54:22'),
(5581, 24, 5, '1', '2014-09-05 13:54:22'),
(5580, 24, 9, '1', '2014-09-05 13:54:22'),
(5579, 24, 24, '1', '2014-09-05 13:54:22'),
(5578, 24, 23, '1', '2014-09-05 13:54:22'),
(5701, 28, 9, '1', '2014-09-16 01:00:26'),
(5700, 28, 24, '1', '2014-09-16 01:00:26'),
(5699, 28, 23, '1', '2014-09-16 01:00:26'),
(5781, 23, 24, '1', '2014-09-19 18:30:30'),
(5780, 23, 23, '1', '2014-09-19 18:30:30'),
(5821, 22, 9, '1', '2014-09-22 13:50:47'),
(5820, 22, 24, '1', '2014-09-22 13:50:47'),
(5819, 22, 23, '1', '2014-09-22 13:50:47');

I'm using below query

SELECT rest.restaurant_id, rest.restaurant_name, cui.cuisine_id,  ROUND( ( ( SUM(rvw.rating) / (COUNT(rvw.rating_id)*5) )*100 ) ,1) AS avg_rating, ROUND( ( ( SUM(rvw.rating) / (COUNT(rvw.rating_id)) )) ,1) AS ratingValue, COUNT(rvw.rating_id) AS ratingCount, SUM(rvw.rating) AS ratingSum FROM `restaurants`AS rest LEFT JOIN reviews AS rvw ON rest.restaurant_id = rvw.restaurant_id LEFT JOIN serving_cuisines AS cui ON rest.restaurant_id = cui.restaurant_id LEFT JOIN cuisine AS cuilist ON cuilist.cuisine_id = cui.cuisine_id WHERE 1 GROUP BY rest.restaurant_id

I'm getting the output as below.. 在此处输入图片说明

But my output should come like below..

在此处输入图片说明

This is your query with simplified table aliases:

SELECT r.restaurant_id, r.restaurant_name,
       ROUND( ( ( SUM(rvw.rating) / (COUNT(rvw.rating_id)*5) )*100 ) ,1) AS avg_rating,
       ROUND( ( ( SUM(rvw.rating) / (COUNT(rvw.rating_id)) )), 1) AS ratingValue,
       COUNT(rvw.rating_id) AS ratingCount,
       SUM(rvw.rating) AS ratingSum
FROM restaurants r LEFT JOIN
     reviews rvw
     ON r.restaurant_id = rvw.restaurant_id LEFT JOIN  
     serving_cuisines sc
     ON r.restaurant_id = sc.restaurant_id LEFT JOIN
     cuisine c
     ON c.cuisine_id = sc.cuisine_id
WHERE 1
GROUP BY r.restaurant_id;

Your problem is that you are joining in two "directions". A restaurant can have multiple ratings and (presumably) a restaurant can also have multiple cuisines. So, when you join, you are getting a Cartesian product for each restaurant.

The normal solution to this problem is to do the aggregation before doing the join .

You have a simpler solution. Just remove the joins to the cuisines:

SELECT r.restaurant_id, r.restaurant_name,
       ROUND( ( ( SUM(rvw.rating) / (COUNT(rvw.rating_id)*5) )*100 ) ,1) AS avg_rating,
       ROUND( ( ( SUM(rvw.rating) / (COUNT(rvw.rating_id)) )), 1) AS ratingValue,
       COUNT(rvw.rating_id) AS ratingCount,
       SUM(rvw.rating) AS ratingSum
FROM restaurants r LEFT JOIN
     reviews rvw
     ON r.restaurant_id = rvw.restaurant_id 
WHERE 1
GROUP BY r.restaurant_id;

You are not using those tables at all.

Next, you can simplify the query by using AVG() :

SELECT r.restaurant_id, r.restaurant_name,
       ROUND( AVG(rvw.rating) / 5)  * 100, 1) AS avg_rating,
       ROUND( AVG(rvw.rating), 1) AS ratingValue,
       COUNT(rvw.rating_id) AS ratingCount,
       SUM(rvw.rating) AS ratingSum
FROM restaurants r LEFT JOIN
     reviews rvw
     ON r.restaurant_id = rvw.restaurant_id 
WHERE 1
GROUP BY r.restaurant_id;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM