挣扎着MySQL子查询

时间:2013-08-08 11:09:52

标签: mysql

我有两个表,imagegradeReason。每张图片都会根据其质量获得评分,用户可以通过选择{{1}来选择4个不同的原因(reasonID_1reasonID_2reasonID_3reasonID_4) }}。原因的细分存储在reasonID表中。

gradeReason

我想要的是一个查询,它将返回每个reasonID在审核中使用的次数以及gradeReason的名称

e.g。

审计125 -

reasonID 3被使用了两次 - 名字'患者感动',

reasonID 2使用了两次 - 名称为“曝光不足”。

我会诚实地说,我已经挣扎了好几天,我甚至不知道从哪里开始。

3 个答案:

答案 0 :(得分:5)

这更难,因为您的数据未正确规范化。以下方法首先规范化数据,然后进行连接和聚合:

select ir.auditId, gr.ReasonId, gr.category, gr.name, count(*) as cnt
from (select i.imageID, i.auditID,
             (case when n.n = 1 then ReasonID_1
                   when n.n = 2 then ReasonID_2
                   when n.n = 3 then ReasonID_3
                   when n.n = 4 then ReasonID_4
              end) as ReasonId
      from image i cross join
           (select 1 as n union all select 2 union all select 3 union all select 4
           ) n
      ) ir join
      gradeReason gr
      on ir.ReasonId = gr.ReasonId
group by ir.auditId, gr.ReasonId, gr.category, gr.name
order by cnt desc; 

答案 1 :(得分:0)

对于您的选择,您必须为gradeReason的每个外键加入gradeReason:

    SELECT imageID
         , auditID
         , r1.name
         , r2.name
         , r3.name
         , r4.name
     FROM image i
LEFT JOIN gradeReason r1 on i.reasonID_1 = r1.reasonID
LEFT JOIN gradeReason r2 on i.reasonID_2 = r2.reasonID
LEFT JOIN gradeReason r3 on i.reasonID_3 = r3.reasonID
LEFT JOIN gradeReason r4 on i.reasonID_4 = r4.reasonID

你的示例数据不合理,因为你的桌面图片中gradeReason的外键不在gradeReason中,但我猜你还有更多的gradeRasons。

此外,您的结构未规范化: gradeReason在类别的行中有重复的条目。这不是太糟糕,但最好有一个单独的gradeReasonCategories表。

答案 2 :(得分:0)

使用UNIONS的另一个选项: -

SELECT auditId, ReasonId, category, name, SUM(cnt)
FROM
(
    SELECT ir.auditId, gr.ReasonId, gr.category, gr.name, count(*) as cnt
    FROM image ir
    INNER JOIN gradeReason gr
    ON ir.reasonID_1 = gr.ReasonId
    WHERE ir.auditId = 123
    GROUP BY ir.auditId, gr.ReasonId, gr.category, gr.name
    UNION ALL
    SELECT ir.auditId, gr.ReasonId, gr.category, gr.name, count(*) as cnt
    FROM image ir
    INNER JOIN gradeReason gr
    ON ir.reasonID_2 = gr.ReasonId
    WHERE ir.auditId = 123
    GROUP BY ir.auditId, gr.ReasonId, gr.category, gr.name
    UNION ALL
    SELECT ir.auditId, gr.ReasonId, gr.category, gr.name, count(*) as cnt
    FROM image ir
    INNER JOIN gradeReason gr
    ON ir.reasonID_3 = gr.ReasonId
    WHERE ir.auditId = 123
    GROUP BY ir.auditId, gr.ReasonId, gr.category, gr.name
    UNION ALL
    SELECT ir.auditId, gr.ReasonId, gr.category, gr.name, count(*) as cnt
    FROM image ir
    INNER JOIN gradeReason gr
    ON ir.reasonID_4 = gr.ReasonId
    WHERE ir.auditId = 123
    GROUP BY ir.auditId, gr.ReasonId, gr.category, gr.name
) Sub1
GROUP BY auditId, ReasonId, category, name