0

我有两张桌子,imagegradeReason。每个图像都因其质量而被授予一个等级,用户可以通过选择一个来选择 4 个不同的原因( reasonID_1reasonID_2reasonID_3、 ) 。原因的细目存储在表中。reasonID_4reasonIDgradeReason

image

imageID   auditID  reasonID_1  reasonID_2  reasonID_3  reasonID_4
-------   -------  ----------  ----------  ----------  ----------
1         123      1           13          7           3
2         124      8           13          8           6 
4         125      3           2           5           6
5         125      7           4           2           3

gradeReason

reasonID   category   name
--------   --------   ----
1          exposure   overexposed
2          exposure   underexposed
3          patient    patient moved
4          equipment  sensor too big
5          equipment  sensor too small

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

例如

审计 125 -

reasonID 3 被使用了两次 - 名称“患者已移动”,

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

老实说,我已经为此苦苦挣扎了好几天,我什至想不出从哪里开始。

4

3 回答 3

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; 
于 2013-08-08T11:16:21.510 回答
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 中,但我想您有更多的gradeReason。

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

于 2013-08-08T11:27:31.817 回答
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
于 2013-08-08T12:37:04.947 回答