Mysql 查找每个国家评分最高的图书。如果有平局 "print" 评分最高的书
Mysql find the book with the highest rating for each country. If there is a tie "print" the book with the highest number of ratings
我有以下表格:
CREATE TABLE `country` (
`name` VARCHAR(60) NOT NULL,
`code` VARCHAR(3) UNIQUE NOT NULL,
PRIMARY KEY (`code`)
);
CREATE TABLE `user` (
`userId` INT UNIQUE NOT NULL AUTO_INCREMENT,
`country` VARCHAR(3) NOT NULL,
`age` INT NOT NULL,
PRIMARY KEY (`userId`),
CONSTRAINT `fk_user_country` FOREIGN KEY (`country`) REFERENCES `country`(`code`)
);
CREATE TABLE `bookRating` (
`userId` INT NOT NULL,
`isbn` VARCHAR(13) NOT NULL,
`rate` INT NOT NULL,
`date` DATE NOT NULL,
CONSTRAINT `fk_bookRating_user` FOREIGN KEY (`userId`) REFERENCES `user`(`userId`),
CONSTRAINT `fk_bookRating_book` FOREIGN KEY (`isbn`) REFERENCES `book`(`isbn`)
);
CREATE TABLE `book` (
`isbn` varchar(13) UNIQUE NOT NULL,
`bookTitle` VARCHAR(280),
`bookAuthor` VARCHAR(150),
`yearPublication` int(4),
-- `yearPublication` must be an integer because we have value less that 1901 in dataset
`publisher` VARCHAR(135),
PRIMARY KEY (`isbn`),
CONSTRAINT `publication_yea_chk` check ((`yearPublication` > -1) && (`yearPublication` < 2101))
);
正如我在标题上所说的,我想为每个国家/地区找到平均评分最高的书
我试过这个查询:
select T1.name, T1.BookTitle, Rate
from
(
select C.Code, AVG(BR.rate) MAXRating
from `bookRating` BR
inner join `book` B on BR.isbn = B.isbn
INNER JOIN `USER` U ON BR.UserID = U.USERId
INNER JOIN `COUNTRY` C ON U.country = C.Code
group by C.Code
) T
inner join
(
select C.Code, C.name, B.BookTitle, BR.ISBN, BR.rate
from `bookRating` BR
inner join `book` B on BR.isbn = B.isbn
INNER JOIN `USER` U ON BR.UserID = U.USERId
INNER JOIN `COUNTRY` C ON U.country = C.Code
) T1 ON T.Code = T1.Code AND T.MAXRATING = T1.RATE;
我很确定这行得通。但我想让它像如果 2 本书或更多书的平均评分相同,我想要评分最高的那本书。
我想我可以使用 If() 语句,但我怎么能 If(... , a condition)
我该怎么做?
UPDATE
我已经创建了数据库并在 db fidle 中插入了一些信息:
https://www.db-fiddle.com/f/s6wKhKhxXMX1W2x9VZn9da/1
您可以加入表格,按国家和书籍聚合以获得所有平均评分,并对聚合结果使用 window 函数 MAX()
和 FIRST_VALUE()
以获得书籍每个国家的平均水平最高:
SELECT DISTINCT c.name,
FIRST_VALUE(b.bookTitle) OVER (
PARTITION BY c.Code
ORDER BY AVG(r.rate) DESC, COUNT(*) DESC
) bookTitle,
MAX(AVG(r.rate)) OVER () AverageRating
FROM country c
INNER JOIN users u ON u.country = c.Code
INNER JOIN bookRating r ON r.UserID = u.UserID
INNER JOIN book b ON b.isbn = r.isbn
GROUP BY c.Code, b.isbn;
参见demo。
我有以下表格:
CREATE TABLE `country` (
`name` VARCHAR(60) NOT NULL,
`code` VARCHAR(3) UNIQUE NOT NULL,
PRIMARY KEY (`code`)
);
CREATE TABLE `user` (
`userId` INT UNIQUE NOT NULL AUTO_INCREMENT,
`country` VARCHAR(3) NOT NULL,
`age` INT NOT NULL,
PRIMARY KEY (`userId`),
CONSTRAINT `fk_user_country` FOREIGN KEY (`country`) REFERENCES `country`(`code`)
);
CREATE TABLE `bookRating` (
`userId` INT NOT NULL,
`isbn` VARCHAR(13) NOT NULL,
`rate` INT NOT NULL,
`date` DATE NOT NULL,
CONSTRAINT `fk_bookRating_user` FOREIGN KEY (`userId`) REFERENCES `user`(`userId`),
CONSTRAINT `fk_bookRating_book` FOREIGN KEY (`isbn`) REFERENCES `book`(`isbn`)
);
CREATE TABLE `book` (
`isbn` varchar(13) UNIQUE NOT NULL,
`bookTitle` VARCHAR(280),
`bookAuthor` VARCHAR(150),
`yearPublication` int(4),
-- `yearPublication` must be an integer because we have value less that 1901 in dataset
`publisher` VARCHAR(135),
PRIMARY KEY (`isbn`),
CONSTRAINT `publication_yea_chk` check ((`yearPublication` > -1) && (`yearPublication` < 2101))
);
正如我在标题上所说的,我想为每个国家/地区找到平均评分最高的书
我试过这个查询:
select T1.name, T1.BookTitle, Rate
from
(
select C.Code, AVG(BR.rate) MAXRating
from `bookRating` BR
inner join `book` B on BR.isbn = B.isbn
INNER JOIN `USER` U ON BR.UserID = U.USERId
INNER JOIN `COUNTRY` C ON U.country = C.Code
group by C.Code
) T
inner join
(
select C.Code, C.name, B.BookTitle, BR.ISBN, BR.rate
from `bookRating` BR
inner join `book` B on BR.isbn = B.isbn
INNER JOIN `USER` U ON BR.UserID = U.USERId
INNER JOIN `COUNTRY` C ON U.country = C.Code
) T1 ON T.Code = T1.Code AND T.MAXRATING = T1.RATE;
我很确定这行得通。但我想让它像如果 2 本书或更多书的平均评分相同,我想要评分最高的那本书。
我想我可以使用 If() 语句,但我怎么能 If(... , a condition)
我该怎么做?
UPDATE
我已经创建了数据库并在 db fidle 中插入了一些信息: https://www.db-fiddle.com/f/s6wKhKhxXMX1W2x9VZn9da/1
您可以加入表格,按国家和书籍聚合以获得所有平均评分,并对聚合结果使用 window 函数 MAX()
和 FIRST_VALUE()
以获得书籍每个国家的平均水平最高:
SELECT DISTINCT c.name,
FIRST_VALUE(b.bookTitle) OVER (
PARTITION BY c.Code
ORDER BY AVG(r.rate) DESC, COUNT(*) DESC
) bookTitle,
MAX(AVG(r.rate)) OVER () AverageRating
FROM country c
INNER JOIN users u ON u.country = c.Code
INNER JOIN bookRating r ON r.UserID = u.UserID
INNER JOIN book b ON b.isbn = r.isbn
GROUP BY c.Code, b.isbn;
参见demo。