简体   繁体   English

PHP mySQL 从多个表中检索唯一正确的数据

[英]PHP mySQL retrieve unique correct data from multiple tables

So i am making this webpage (for fun to practice web dev) where users can rate or comment on a movie.所以我正在制作这个网页(为了练习网络开发的乐趣),用户可以在其中对电影进行评分或评论。 One page I have is where you click on the movie for full details and it lists all the ratings and comments (together if the user has commented by review and rated through a page called "reviewMovie"...which if they went this way the rating is mandatory, otherwise they can comment on this page "listMovieReviews").我拥有的一页是您单击电影以获取完整详细信息的地方,它列出了所有评分和评论(如果用户通过评论进行评论并通过名为“reviewMovie”的页面进行评分......评级是强制性的,否则他们可以在此页面上评论“listMovieReviews”)。

The problem I am having is incorrect details when doing my queries我在查询时遇到的问题是详细信息不正确

  1. the discussion table stores: the discussion ID (primary key) the timestamp of the comment, the comment, the user who made the comment, and the movie they commented about.讨论表存储:讨论 ID(主键)、评论的时间戳、评论、发表评论的用户以及他们评论的电影。

  2. the discussion table stores: the discussion ID (primary key) the timestamp of the comment, the comment, the user who made the comment, and the movie they commented about.讨论表存储:讨论 ID(主键)、评论的时间戳、评论、发表评论的用户以及他们评论的电影。

  3. the rating table stores: the rating ID (primary key), the movie being rated, the user who did the rating, and the rating score (out of 10)评分表存储:评分 ID(主键)、被评分的电影、评分的用户和评分(满分 10)

So some examples of the combined data are:因此,组合数据的一些示例是:

  • User1 (user1) has rated "American Psycho" a 4/10 and has made a comment "comment1" on it用户 1(用户 1)已将“美国精神病”评为 4/10 并对其发表评论“评论 1”

  • User2 (admin..for testing purposes) has rated "American Psycho" a 8/10 and has made a comment "comment2" on it User2(管理员..出于测试目的)已将“American Psycho”评为 8/10 并对其发表评论“comment2”

So on the page that lists the details of "American Psycho" and the ratings/comments I should have this list of ratings and comments:因此,在列出“美国精神病人”的详细信息和评级/评论的页面上,我应该有以下评级和评论列表:

<TIMESTAMP FOR COMMENT1> User1 Rating 4/10 "comment1"
<TIMESTAMP FOR COMMENT2> admin Rating 8/10 "comment2"

Using the following queries:使用以下查询:

SELECT * 
FROM discussion 
INNER JOIN users ON discussion.userID = users.userID                                                 
WHERE discussion.movieID = <American Psycho's Movie ID>;

AND

SELECT * 
FROM ratings 
INNER JOIN movies ON ratings.movieID = movies.movieID 
WHERE ratings.movieID = <American Psycho's Movie ID>;  

I get this:我明白了:

<TIMESTAMP FOR COMMENT2> admin Rating 4/10 "comment2"
<TIMESTAMP FOR COMMENT2> admin Rating 8/10 "comment2"

I have tried several other INNER JOINS with joining the table that stores user information and table that stores movies information but I keep getting mixed data我已经尝试了其他几个 INNER JOINS 连接存储用户信息的表和存储电影信息的表,但我不断收到混合数据

Also tried DISTINCT and UNION but still to no avail也尝试了 DISTINCT 和 UNION 但仍然无济于事

Where am I going wrong??我哪里错了??

Also first post so sorry If I have not been too clear, bad formatting, or not shown enough work but I am really really stuck也是第一次发帖很抱歉如果我不太清楚,格式错误,或者没有显示足够的工作,但我真的被卡住了

I assume:我假设:

  • A movie could have from 0 to n comments.一部电影可以有 0 到 n 条评论。
  • A movie could have from 0 to n ratings.一部电影可以有 0 到 n 个评分。
  • A user could rate a movie only once or none.用户只能对电影评分一次或不评分。
  • A user could comment a movie from 0 to n times.用户可以评论一部电影 0 到 n 次。

Your queries are fine, maybe your problem is in your php code.您的查询很好,也许您的问题出在您的 php 代码中。

You have to account that a user maybe comment a movie several time and never rated it.您必须考虑到用户可能多次评论一部电影但从未对其进行评分。

In second query you should JOIN with user (instead of with movie, because you do not get movie information) to get the user name.在第二个查询中,您应该使用用户(而不是电影,因为您没有获得电影信息)来获得用户名。

Maybe you should display the info in two table: one for ratings and other for comments.也许您应该在两张表中显示信息:一张用于评分,另一张用于评论。

(You have to replace quotation marks by movie ID) (必须用电影ID替换引号)

SELECT u.userName, r.score
FROM ratings AS r
INNER JOIN users AS u ON r.userID = u.userID 
WHERE r.movieID = ?; 
SELECT u.userName, d.commentTime, d.comment
FROM discussion AS d
INNER JOIN users AS u ON d.userID = u.userID                                                 
WHERE d.movieID = ?;

You could group all comments per user in one row this way (but I think this is not what you are looking for):您可以通过这种方式将每个用户的所有评论分组为一行(但我认为这不是您要查找的内容):

SELECT u.userName, GROUP_CONCAT(CONCAT(d.commentTime, ': ', d.comment) SEPARATOR '; ') AS comments
FROM discussion AS d
INNER JOIN users AS u ON d.userID = u.userID                                                 
WHERE d.movieID = ?
GROUP BY u.userName 

I think do not have sense to make one query in this case, but if you want get all data in one query you could try something like this:我认为在这种情况下进行一个查询没有意义,但是如果您想在一个查询中获取所有数据,您可以尝试这样的事情:

You will have a comment per row, so for example if a user make two comment you will have two rows for the same user with the same score.每行都会有一个评论,例如,如果一个用户发表了两条评论,那么对于同一用户,您将有两行评分相同。

First I get all user that comment or rating the selected movie and make a CROSS JOIN between movie and these users.首先,我让所有对所选电影进行评论或评级的用户,并在电影和这些用户之间进行 CROSS JOIN。 Then I make a LEFT JOIN with discussion ON movieID and userID and another LEFT JOIN with ratings ON movieID and userID.然后我用关于电影 ID 和用户 ID 的讨论进行 LEFT JOIN 和另一个对电影 ID 和用户 ID 进行评级的 LEFT JOIN。

You need to make LEFT JOIN instead of INNER JOIN because if a movie do not have ratings or comments your result will be empty.您需要使用 LEFT JOIN 而不是 INNER JOIN,因为如果电影没有评分或评论,您的结果将为空。

In SELECT clause you should list only the columns that you need.在 SELECT 子句中,您应该只列出您需要的列。

SELECT *
FROM movies m

CROSS JOIN (SELECT d.userID
            FROM discussion d
            WHERE d.movieID = ?
            
            UNION 
            
            SELECT r.userID
            FROM ratings r
            WHERE r.movieID = ?) AS u

LEFT JOIN discussion AS d ON m.movieID = d.movieID AND u.userID = d.userID

LEFT JOIN ratings AS r ON  m.movieID = r.movieID AND u.userID = r.userID

LEFT JOIN users ON u.userID = users.userID

WHERE m.movieID = ?;

You need to join all three tables.您需要加入所有三个表。

SELECT *
FROM movies AS m
JOIN ratings AS r ON r.movieID = m.movieID
JOIN discussion AS d ON d.userID = r.userID AND d.movieID = m.movieID
WHERE m.movieID = <American Psycho's Movie ID>
ORDER BY r.userID, d.timestamp

This will repeat the movie and rating information for each comment.这将重复每个评论的电影和评级信息。 You can remove those duplicates in the application code that displays the results.您可以在显示结果的应用程序代码中删除这些重复项。 See How can i list has same id data with while loop in PHP?请参阅如何在 PHP 中列出与 while 循环相同的 id 数据? for an example of how to do this.有关如何执行此操作的示例。

SELECT * FROM movies AS MOVIE
JOIN ratings AS RATING ON `RATING.movieID` = `MOVIE.movieID`
JOIN discussion AS DISCUS ON `DISCUS.userID` = `RATING.userID`
WHERE `MOVIE.movieID` = <SOME Movie ID> 
ORDER BY `RATING.userID`, `DISCUS.timestamp`

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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