【问题标题】:sql statement question. Need to query 3 tables in one go!sql语句问题。需要一口气查询3张表!
【发布时间】:2010-05-02 22:35:49
【问题描述】:

我有一个 sql 数据库。在这个数据库中,我需要查询 3 个表。第一个表包含名为item 的所有项目信息,另外两个表包含名为userComment 的投票和cmets 数据,第三个表包含名为userItem 的投票数据

我目前有一个函数,它使用这个 sql 查询来获取最新的更流行的(就投票和 cmets 而言):

$sql = "SELECT  itemID, COUNT(*) AS cnt
FROM    (
        SELECT  `itemID`
        FROM   `userItem`
        WHERE  FROM_UNIXTIME( `time` ) >= NOW() - INTERVAL 1 DAY
        UNION ALL
        SELECT  `itemID`
        FROM    `userComment`
        WHERE  FROM_UNIXTIME( `time` ) >= NOW() - INTERVAL 1 DAY AND `itemID` > 0
        ) q
GROUP BY
        `itemID`
ORDER BY
        cnt DESC";

我知道如何通过单独投票或 cmets 更改此设置....

但是 - 我需要查询数据库以仅返回仅在 item 表中具有特定条件的项目 ID,这些是 WHERE categoryID = 'xx' AND typeID = 'xx'

如果 sql ninja 可以帮我解决这个问题?我是否必须首先返回上述查询的结果以及获取的数组中的每个结果,然后根据item 表检查每个结果,看看它是否符合构建新数组的条件 - 或者这是否矫枉过正?

谢谢, 斯蒂芬

【问题讨论】:

    标签: php sql mysql database


    【解决方案1】:

    我不清楚您的数据库是如何设置的,或者其中一些属性在哪里,但可能类似于:

    $sql = "SELECT  q.itemID, COUNT(*) AS cnt
    FROM    (
            SELECT  `itemID`
            FROM   `userItem`
            WHERE  FROM_UNIXTIME( `time` ) >= NOW() - INTERVAL 1 DAY
            UNION ALL
            SELECT  `itemID`
            FROM    `userComment`
            WHERE  FROM_UNIXTIME( `time` ) >= NOW() - INTERVAL 1 DAY AND `itemID` > 0
            ) q inner join item i on q.itemID = i.itemID
    WHERE i.categoryID = 'xx' AND i.typeID = 'xx'
    GROUP BY
            q.`itemID`
    ORDER BY
            cnt DESC";
    

    【讨论】:

    • 似乎不起作用?您需要哪些您不确定的额外信息? categoryID 和 itemID 等属性在名为 item 的表中,所有项目都实际存储在该表中
    • 内部联接仅作为具有投票或 cmets 的项目的过滤器。将其更改为左连接 - 这有帮助吗?
    • 返回:您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以在第 10 行的 'q.itemID = i.itemID WHERE i.categoryID = '1' AND i.typeID = '1' GROUP BY ' 附近使用正确的语法 - SELECT q .itemID, COUNT(*) AS cnt FROM ( SELECT itemID FROM userItem WHERE FROM_UNIXTIME( time ) >= NOW() - 间隔 1 天联合所有 SELECT itemID FROM userComment WHERE FROM_8UNIXTIME( @9876542 @ ) >= NOW() - INTERVAL 1 DAY AND itemID > 0 ) q left join item i q.itemID = i.itemID WHERE i.categoryID = '1' AND i.typeID = '1' GROUP BY q。 itemID 按 cnt DESC 订购
    • @Stefan,好像我没有使用“on”关键字。
    • 这很有效,例如:如果我有一个有 1 票且有评论的东西,它会归于有 1 票但没有评论的评论?这是为什么呢?
    【解决方案2】:

    我倾向于在每个查询中包含过滤器。我需要验证,但我认为它会更好,因为在 Group By 中分析的行更少。因此,我会做类似的事情(这是一个猜测,因为我们没有被告知 item 表与其他表的关系):

    $sql = "Select  itemID, Count(*) AS cnt
    From    (
            Select ui.`itemID`
            From `userItem` ui
                Join `item` i
                    On i.itemid = ui.itemid
            Where From_UnixTime( `time` ) >= Now() - Interval 1 Day
                And i.categoryID = 'xx'
                And i.typeid = 'xx'
            Union All
            Select uc.`itemID`
            From `userComment` uc
                Join `item` i
                    On i.itemid= uc.itemid
            Where From_UnixTime( `time` ) >= Now() - Interval 1 Day
                And uc.itemID > 0
                And i.categoryID = 'xx'
                And i.typeid = 'xx'
            )  q
    Group By `itemID`
    Order By cnt Desc";
    

    【讨论】:

    • 收到此回复,有什么想法吗?字段列表中的列 'itemID' 不明确 - SELECT itemID, Count(*) AS cnt FROM ( SELECT itemID FROM userItem ui JOIN item i ON i.itemid = ui.itemid WHERE From_UnixTime( time ) >= Now() - Interval 7 Day AND i.categoryID = 'popular' UNION ALL SELECT itemID FROM userComment uc Join item i On i.itemid= uc.itemid Where From_UnixTime(time) >= Now() - 间隔 7 天且 uc.itemID > 0 且 i.categoryID = 'popular' ) q Group By itemID Order By cnt Desc
    • @Stefan - 您只需为每个内部选择子句中的 itemid 起别名。我已经更新了我的帖子来说明。
    猜你喜欢
    • 1970-01-01
    • 2016-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-11
    相关资源
    最近更新 更多