1

severity私たちはカスタマイズされたバージョンの trac を使用しており、人々は 2 つの基準に基づいてバグのスコアを付けることができますimportance

簡単にするために、データベースに次のテーブルが含まれているとします。

テーブルticket

id | title           | reporter
1  | SQL injection   | Torvalds
2  | Buffer Overflow | Linus
3  | Localization    | bofh

テーブルvotes

ticket_id | value | type       | voter
1         | 4     | severity   | Linus
1         | 2     | severity   | Torvalds
1         | 3     | severity   | bofh
1         | 4     | importance | Linus
1         | 3     | importance | Torvalds
2         | 4     | severity   | Linus
2         | 2     | severity   | Torvalds
2         | 1     | importance | Linus
2         | 1     | importance | bofh
3         | 1     | importance | Linus

たとえば、最初の行は、ユーザーLinusがチケット #1 の重大度スコアとして 4 を提案したことを意味します。

これで、平均スコアを取得するために使用する trac レポートに次の SQL クエリがあります。

SELECT t.title, t.reporter, AVG(vs.value), AVG(vi.value), COUNT(vs.value), COUNT(vi.value)
FROM ticket t
LEFT JOIN votes vs ON vs.type = 'severity'   AND vs.ticket_id=t.id
LEFT JOIN votes vi ON vi.type = 'importance' AND vi.ticket_id=t.id;

私の希望では、これは次の値を持つテーブルを返すはずです:

title | reporter | severity avg | importance avg | number of sev. votes | number of imp. votes
SQL injection | Torvalds | 3 | 3.5 | 3 | 2

このようにして、チケットに投票した人数とその投票数を教えてくれます。

ただし、LEFT JOIN仕組み上、得られるエントリは重大度と重要度の投票のデカルト積であるため、平均は有効ですが、両方のカウントは正しい値ではなく 3x2=6 に設定されています。

このクエリを修正して、必要なものを返す簡単な方法はありますか?

4

1 に答える 1

2

CASE ステートメントと集計関数を組み合わせます。

SELECT 
  t.title, 
  t.reporter, 
  SUM(CASE WHEN v.type = 'importance' THEN 1 ELSE 0 END) AS Count_Imp,
  SUM(CASE WHEN v.type = 'severity' THEN 1 ELSE 0 END) AS Count_Sev,
  SUM(CASE WHEN v.type = 'importance' THEN v.value ELSE 0 END) / 
    Count_Imp AS Avg_Imp,
  SUM(CASE WHEN v.type = 'severity' THEN 1 ELSE 0 END) / 
    Count_Sev AS Avg_Sev
FROM 
  ticket t
  LEFT JOIN votes v 
  ON v.ticket_id = t.id;

Count_ImpTrac SQL でエイリアスの再利用が許可されていない場合Count_Sevは、単純に平均計算列でこれらのステートメントを繰り返します。

于 2013-02-19T20:46:04.303 に答える