与COERE重复COUNT,SELECT,LEFT JOIN?

时间:2014-09-29 02:27:51

标签: mysql

如何正确执行此查询?一切都好,除了新闻表。它只返回第一行。

 SELECT 
   (SELECT COUNT(*) FROM news WHERE news.author = '$user_name') as newscount,
   (SELECT COUNT(*) FROM torrents WHERE torrents.user = '$user_name') as torrcount,
   users.date as userdate, 
   users.rep as userrep, 
   torrents.title as tortitle, 
   torrents.torrent as torlink, 
   news.link as newslink, 
   news.title as newstitle 
 FROM 
   users,
   torrents, 
   news 
 WHERE 
   (users.name AND torrents.user AND news.author) = '$user_name' LIMIT 0,30

1 个答案:

答案 0 :(得分:0)

您现有的查询未指定3个表JOIN的方式以及您在where子句中使用的语法是如何不正确的。

FROM clauseWHERE clause看起来像这样:

FROM users
INNER JOIN torrents ON users.name = torrents.user
INNER JOIN news ON users.name= news.author
WHERE users.name = '$user_name'

因为我们已经加入了3个表,所以我们只需要过滤users表,其他表也将被限制为相同的用户名。

但是使用INNER JOIN的麻烦在于每个连接必须在两个表中加入记录。如果您的应用程序逻辑允许用户获得新闻但没有torrent,或没有新闻的种子或没有torrent或新闻的用户,那么我们无法使用INNER JOIN,因此我们使用OUTER JOIN代替

OUTER JOIN允许在一个表中记录但在另一个表中没有匹配的记录

所以:我会说你的FROM clause需要使用LEFT OUTER JOIN来获取种子和新闻

FROM users
LEFT OUTER JOIN torrents ON users.name = torrents.user
LEFT OUTER JOIN news ON users.name= news.author
WHERE users.name = '$user_name'

如果不熟悉联接我建议this visual guide

我相信你的整体查询会是这样的:

SELECT (
        SELECT COUNT(*)
        FROM news
        WHERE news.author = '$user_name'
        ) AS newscount
    , (
        SELECT COUNT(*)
        FROM torrents
        WHERE torrents.user = '$user_name'
        ) AS torrcount
    , users.DATE AS userdate
    , users.rep AS userrep
    , torrents.title AS tortitle
    , torrents.torrent AS torlink
    , news.link AS newslink
    , news.title AS newstitle
FROM users
LEFT OUTER JOIN torrents ON users.name = torrents.user
LEFT OUTER JOIN news ON users.name= news.author
WHERE users.name = '$user_name'
LIMIT 0, 30
;

建议

连接的效果是从所涉及的表中获取行的乘法。

set @ncount := (
        SELECT COUNT(*) c
        FROM news
        WHERE news.author = '$user_name'
        )

set @tcount :=    (
        SELECT COUNT(*) c
        FROM torrents
        WHERE torrents.user = '$user_name'
        )     

SELECT
      @ncount newscount
    , @tcount torrcount
    , users.DATE AS userdate
    , users.rep AS userrep
    , torrents.title         AS Item_Title
    , torrents.torrent       AS Item_link
    , 'torrent'              AS Item_Type
FROM users
INNER JOIN torrents ON users.name = torrents.user
WHERE users.name = '$user_name'

UNION ALL

SELECT
      @ncount newscount
    , @tcount torrcount
    , users.DATE AS userdate
    , users.rep AS userrep
    , news.link              AS Item_Title
    , news.title             AS Item_link
    , 'news'                 AS Item_Type
FROM users
INNER JOIN news ON users.name= news.author
WHERE users.name = '$user_name'
LIMIT 0, 30
;