MySQL中的其他SELECT如果不工作

时间:2014-06-02 16:25:24

标签: mysql

我试图执行以下查询而没有任何成功。 这是我第一次在SQL中使用if else语句,你可以验证它有什么问题吗? 感谢您的宝贵帮助!

SELECT 
        members.id AS friendID, 
        members.username AS friendName, 
        members.mainPicture AS thumbnail, 
        COUNT(*) AS numROW 
        FROM members 
        WHERE members.id IN (
            SELECT (IF (friends.senderID = 9, friends.receiverID, 
                        IF (friends.senderID <> 9, friends.senderID)
                       )
                   ) 
            AS fid 
            FROM friends 
            WHERE (friends.senderID = 9 OR friends.receiverID = 9) AND friends.approved=1
            )
            )

2 个答案:

答案 0 :(得分:0)

大问题似乎是你没有GROUP BY条款。 COUNT(*)取决于GROUP BY上的正确操作。

IF的问题是第二个没有其他条件。它可能应该是一个单一的IF:

 IF(friends.senderID = 9, friends.receiverID, friends.senderID)

答案 1 :(得分:0)

完全回答。

一个主要问题是你没有分组。因此,如果返回多个member.id,它们将全部汇总到一行。将返回哪些members.id / username / mainPicture将是未定义的。这也是您只返回一行的原因。

其次是你的IF条款。 IF语句有3个参数。如果第一个为真,则返回第二个,否则返回第三个。在这个例子中,第三个参数是另一个IF(很好,你可以嵌入它们)。但IF没有第三个参数。

因此,您的SQL可能应如下所示: -

SELECT  members.id AS friendID, 
        members.username AS friendName, 
        members.mainPicture AS thumbnail, 
        COUNT(*) AS numROW 
FROM members 
WHERE members.id IN 
(
    SELECT IF (friends.senderID = 9, friends.receiverID, friends.senderID) AS fid 
    FROM friends 
    WHERE (friends.senderID = 9 OR friends.receiverID = 9) 
    AND friends.approved = 1
)
GROUP BY members.id AS friendID, members.username AS friendName, members.mainPicture AS thumbnail

这样做的缺点是它使用带有子查询的IN子句,它可以执行奇怪的操作。此外,子查询还有2个不同字段的OR,这将阻止它使用索引。

这应该为每个成员返回一行(假设member.id是唯一的),但计数器将始终为1.

因此,做以下事情可能会更有效率,我怀疑这会让你得到你想要的东西

SELECT  members.id AS friendID, 
        members.username AS friendName, 
        members.mainPicture AS thumbnail, 
        (f1.aCount + f2.aCount) AS numROW 
FROM members 
LEFT OUTER JOIN 
(
    SELECT receiverID, COUNT(*) AS aCount 
    FROM friends  
    WHERE senderID = 9 
    AND approved = 1
    GROUP BY receiverID
) f1
ON members.id = f1.receiverID 
LEFT OUTER JOIN 
(
    SELECT senderID, COUNT(*) AS aCount 
    FROM friends  
    WHERE receiverID = 9 
    AND approved = 1
    GROUP BY senderID
) f2
ON members.id = f2.senderID 

这会计算会员的所有朋友记录。

如果friends表有一个唯一的id字段,那么你可以使用这样的东西来使它正确使用索引: -

SELECT  members.id AS friendID, 
        members.username AS friendName, 
        members.mainPicture AS thumbnail, 
        COUNT(DISTINCT f1.id) + COUNT(DISTINCT f2.id) AS numROW 
FROM members 
LEFT OUTER JOIN friends f1 ON members.id = f1.receiverID AND f1.senderID = 9 AND f1.approved = 1
LEFT OUTER JOIN friends f2 ON members.id = f2.senderID AND f2.receiverID = 9 AND f2.approved = 1
GROUP BY members.id AS friendID, members.username AS friendName, members.mainPicture AS thumbnail

如果你只是想要没有计数的朋友列表(重新阅读你的评论听起来可能),那么下面将会这样做并且应该相当有效(每个单独的查询可以使用索引,UNION将整理任何重复项): -

SELECT  members.id AS friendID, 
        members.username AS friendName, 
        members.mainPicture AS thumbnail 
FROM members 
INNER JOIN friends  
ON members.id = friends.receiverID 
WHERE senderID = 9 
AND approved = 1
UNION
SELECT  members.id AS friendID, 
        members.username AS friendName, 
        members.mainPicture AS thumbnail
FROM members 
INNER JOIN friends  
ON members.id = friends.senderID 
WHERE receiverID = 9 
AND approved = 1