3

我有两张桌子:

ab_message

  • 用户身份
  • 标题
  • 内容
  • 问题

和 ab_message_rating:

  • ID
  • 用户身份
  • message_id
  • created_at
  • 更新时间

ab_message与 存在 OneToMany 关系ab_message_rating。每个条目ab_message_rating都有 1、2 或 3 作为评分值。

所以我想在一个查询中选择消息和所有相关的表条目。关键是,我需要在这个查询评级中按值计算。

例如,结果应该是:

消息 abc 有 5 个等级为 1 的条目、7 个等级为 2 的条目和 10 个等级为 3 的条目

如何在查询中做到这一点?像 Group By 和 A Join 之类的东西?

4

3 回答 3

3
SELECT ID, Title, Content, 
        MAX(CASE WHEN Rating = 'Rating 1' THEN totalCount ELSE NULL END) 'Rating 1',
        MAX(CASE WHEN Rating = 'Rating 2' THEN totalCount ELSE NULL END) 'Rating 2',
        MAX(CASE WHEN Rating = 'Rating 3' THEN totalCount ELSE NULL END) 'Rating 3'
FROM    
(
    SELECT  a.ID, a.Title, a.Content,
            b.Rating, COUNT(*) totalCount
    FROM    Message a
            LEFT JOIN Rating b
                ON a.ID = b.MessageID
    GROUP BY a.ID, a.Title, a.Content, b.Rating
) r
GROUP BY ID, Title, Content

样本结果:

╔════╦═══════════════╦══════════╦══════════╦══════════╦══════════╗
║ ID ║     TITLE     ║ CONTENT  ║ RATING 1 ║ RATING 2 ║ RATING 3 ║
╠════╬═══════════════╬══════════╬══════════╬══════════╬══════════╣
║  1 ║ Lost Prophets ║ CONTENT1 ║        1 ║        5 ║        7 ║
║  2 ║ Cannibal      ║ CONTENT2 ║        3 ║        4 ║        6 ║
║  3 ║ Sigbin        ║ CONTENT3 ║        4 ║        4 ║        1 ║
╚════╩═══════════════╩══════════╩══════════╩══════════╩══════════╝
于 2013-01-18T12:31:11.297 回答
0

不是非常有效或漂亮,但它会起作用:

select concat('Message "', m.title , '" has ', 
   cast((select count(*) 
        from Table_Rating r 
        where r.message_id = m.id 
        and rating = 1) as char),
   ' entries of rating 1, ',
   cast((select count(*) 
        from Table_Rating r 
        where r.message_id = m.id 
        and rating = 2) as char),
   ' entries of rating 2, and ',
   cast((select count(*) 
        from Table_Rating r 
        where r.message_id = m.id 
        and rating = 3) as char),
   ' entries of rating 3') as FullMessage
from Table_Message m
于 2013-01-18T12:28:17.950 回答
0
SELECT 'Message '+ m.title + ' has ' + 
    -- ISNULL(z.Rating1/2/3,0) because z.Rating1/2/3 could be NULL (see OUTER APPLY + Table_Rating may not have rows)
    CONVERT(VARCHAR(11), ISNULL(z.Rating1,0)) + 'entries of rating 1, ' +  
    CONVERT(VARCHAR(11), ISNULL(z.Rating2,0)) + 'entries of rating 2, and '+
    CONVERT(VARCHAR(11), ISNULL(z.Rating3,0)) +  'entries of rating 3' AS Description
FROM Table_Message tm
OUTER APPLY (
    SELECT y.[1] AS Rating1, y.[2] AS Rating2, y.[3] AS Rating3
    FROM (
        -- This query will generate 0, 1, 2 or 3 rows because of GROUP BY r.Rating
        SELECT r.Rating, COUNT(*) as Cnt 
        FROM Table_Rating r 
        WHERE r.message_id = m.id 
        GROUP BY r.Rating
    ) x
    -- The PIVOT operator will transponse (it converts rows into columns) the source rows (alias x) into just one row with 3 columns:
    -- [1] = COUNT for Rating 1, [2] = COUNT for Rating 2, [3] = COUNT for Rating 3
    PIVOT ( MAX(x.Cnt) FOR x.Rating IN ([1], [2], [3]) ) y
) z
于 2013-01-18T12:46:45.920 回答