【问题标题】:SQL query that limits the results to one when using count inside count使用 count inside count 时将结果限制为一个的 SQL 查询
【发布时间】:2016-05-07 07:32:54
【问题描述】:

我正在尝试选择特定项目的点赞数。我想出的主意是

CAST(count(uploads.ID in (SELECT uploadID from votes)) as decimal) as numberoflikes

这可行,但查询只返回一件事。

整个查询

SELECT DISTINCT users.NAME AS username
    ,users.ID AS userID
    ,subjects.NAME AS subjectname
    ,uploads.TIME
    ,uploads.description
    ,uploads.NAME
    ,uploads.ID
    ,CASE 
        WHEN uploads.ID IN (
                SELECT uploadID
                FROM votes
                WHERE userID = 2
                )
            THEN CAST(1 AS DECIMAL)
        ELSE CAST(0 AS DECIMAL)
        END AS liked
    ,CASE 
        WHEN uploads.ID IN (
                SELECT uploadID
                FROM bookmarks
                WHERE userID = 2
                )
            THEN CAST(1 AS DECIMAL)
        ELSE CAST(0 AS DECIMAL)
        END AS bookmarked
    ,CAST(count(uploads.ID IN (
                SELECT uploadID
                FROM votes
                )) AS DECIMAL) AS numberoflikes
FROM uploads
INNER JOIN subjects ON (subjects.ID = uploads.subjectID)
INNER JOIN users ON (users.ID = uploads.userID)
INNER JOIN uploadGrades ON (uploads.ID = uploadGrades.uploadID)
INNER JOIN grades ON (grades.ID = uploadGrades.gradeID)
WHERE uploads.active = 1
    AND subjects.ID IN (
        SELECT subjectID
        FROM userSubjects
        INNER JOIN users ON (users.ID = userSubjects.userID)
        WHERE userSubjects.userID = 2
        )
    AND grades.ID IN (
        SELECT userGrades.gradeID
        FROM uploadGrades
        INNER JOIN userGrades ON (uploadGrades.gradeID = userGrades.gradeID)
        WHERE userGrades.userID = 2
        )
ORDER BY uploads.trueRating DESC;

【问题讨论】:

  • 我想我会很想把这个装箱并重新开始。如果您愿意,请考虑遵循这个简单的两步操作: 1. 如果您还没有这样做,请提供适当的 CREATE 和 INSERT 语句(和/或 sqlfiddle),以便我们可以更轻松地复制问题。 2. 如果您尚未这样做,请提供与步骤 1 中提供的信息相对应的所需结果集。
  • “in”子句效率极低。你真的需要重写它来使用连接。即使使用一个“in”也是冒险的;我在这里数不下五个。随着您的数据库的增长,此查询将逐渐消失。
  • 查询有效。我知道 in 子句效率低下,我真的不希望数据库增长很多。但我遇到的问题是,当添加这一行“CAST(count(uploads.ID in (SELECT uploadID from votes)) as decimal) as numberoflikes”时,查询只返回一个结果。
  • 所以您想计算每次上传的票数吗?我将用 joins 而不是 in 子句重写查询。
  • 我认为这行不通,因为IN 是一个返回TRUE/FALSE 的表达式,COUNT 将计算除NULL 之外的任何内容,因此将计算true and false

标签: mysql join count


【解决方案1】:

count(uploads.ID in (SELECT uploadID from votes)) as numberoflikes

按uploads.Id ORDER BY uploads.trueRating DESC 分组

我设法做到了这一点。如果我在那时添加了该组,它会将点赞数分成几行并返回多于一行。感谢您的帮助!

【讨论】:

    【解决方案2】:

    试试这样的...

    SELECT users.name as username, users.ID as userID, subjects.name as subjectname,
           uploads.time, uploads.description, uploads.name, uploads.ID, 
           count(userVotes.userId), count(bookmarksMade.userId),
    FROM uploads 
         join subjects     on(subjects.ID = uploads.subjectID) 
         join users        on(users.ID = uploads.userID)
         join uploadGrades on(uploads.ID = uploadGrades.uploadID) 
         join grades       on(grades.ID = uploadGrades.gradeID)
         left join (select userId, uploadId from votes where userId = 2) as userVotes on uploads.id = userVotes.uploadId
         left join (select userId, uploadId from bookmarks where userId = 2) as bookmarksMade on uploads.id = bookmarksMade.uploadId
         join userSubjects on subjects.id = userSubjects.subjectID
    WHERE uploads.active = 1 AND 
          userSubjects.userID = 2
    ORDER BY uploads.trueRating DESC;
    

    但是,我忽略了 userGrades 的事情,因为你在那里做了一个我不太理解的时髦连接(在看起来不是两个表上的整个主键的东西上连接两个表)。

    无论如何,你真的需要去更多像这样或 Oropeza 在他的回答中建议的东西。更直接地了解您想要什么。这个查询看起来像一个怪物,它一直在增长,并根据您的需要添加了“IN”子句。是时候回到绘图板上思考你想要什么以及如何直接实现它了。

    【讨论】:

    • 这个查询只返回一行。感谢您的努力。+
    【解决方案3】:

    让我们试试你的查询的简化版本,这是获得更好答案的基础

    1. 我将初始查询减少到 user 和 upload 开始。同时删除您已经知道如何计算的字段。

    .

    SELECT DISTINCT users.NAME AS username
        ,users.ID AS userID
        ,uploads.NAME
        ,uploads.ID
        ,CAST(count(uploads.ID IN (
                    SELECT uploadID
                    FROM votes
                    )) AS DECIMAL) AS numberoflikes
    FROM uploads
    INNER JOIN users ON (users.ID = uploads.userID)
    WHERE uploads.active = 1
    ORDER BY uploads.trueRating DESC;
    
    1. 然后用LEFT JOIN添加投票以替换COUNT中的SELECT,这样如果不匹配,您将获得NULL,正如我在评论中所说COUNT不计入NULL's

    .

    SELECT DISTINCT users.NAME AS username
        ,users.ID AS userID
        ,uploads.NAME
        ,uploads.ID
        ,CAST(count(votes.uploadID)) AS DECIMAL) AS numberoflikes
    FROM uploads
    INNER JOIN users ON (users.ID = uploads.userID)
    LEFT JOIN votes ON (uploads.ID = votes.uploadID)
    WHERE uploads.active = 1
    ORDER BY uploads.trueRating DESC;
    

    【讨论】:

    • 我尝试了内部连接版本,但仍然遇到同样的错误。它只返回一行数据。
    • 那是别的,你能在SqlFiddle.com创建一个工作样本吗??
    猜你喜欢
    • 2018-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-15
    • 1970-01-01
    相关资源
    最近更新 更多