3

私は2つのテーブルを持っています:

ab_メッセージ

  • ユーザーID
  • 題名
  • コンテンツ
  • 質問

および ab_message_rating:

  • ID
  • ユーザーID
  • message_id
  • created_at
  • updated_at

ab_messageは と OneToMany 関係にありab_message_ratingます。すべてのエントリにab_message_ratingは、評価値として 1、2、または 3 があります。

したがって、1 つのクエリでメッセージと関連するすべてのテーブル エントリを選択したいと考えています。キーは、このクエリの評価で値でカウントする必要があることです。

たとえば、結果は次のようになります。

メッセージ abc には、評価 1 のエントリが 5 つ、評価 2 のエントリが 7 つ、評価 3 のエントリが 10 あります。

クエリでそれを行う方法は?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 '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 に答える
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 に答える