質問

リクエストトラッカーの使用状況に関するレポートを生成するように依頼されました。 リクエストトラッカーは、私が働いていたいくつかの部門で使用するチケットシステムです。これを行うには、その日に変更されたチケットに関する詳細の夜間スナップショットを別のデータベースに取得します。このアプローチにより、RTが使用する内部データベーススキーマからレポートが分離されます。

レポートに関する他の多くの質問の中で、部門ごとに毎月解決されたチケットの数を報告する必要があります。 RTでは、部門はCustomFieldとして保存され、以下のクエリでわかるように、モデリングはその傾向に従います。ただし、毎晩スナップショットを取得する方法のために、チケットには複数の行があり、Departmentフィールドは1か月にわたって変化する可能性があります。私が興味を持っているのは、最近の部門の分野だけです。クエリでそれを取得する方法がわかりません。

「GROUP BY」を使用してクエリ結果をチケットごとに1つに減らすことができることは知っていますが、それを行うと、最後の部門設定を取得する方法がわかりません。部門はすべて文字列であるため、MAX()は最後のものを取得しません。 MySQLでは、選択するフィールドに集計関数を使用する必要はありませんが、結果は不定です(私のテストでは、MySQLのバージョンで最初の関数を取得するようです)。

説明のために、2つのチケットと、そのすべての部門フィールド設定を表示するクエリの結果を次に示します。

"ticket_num","date","QueueName","CF","CFValue","closed"
35750,"2009-09-22","IT_help","Department","",""
35750,"2009-09-23","IT_help","Department","",""
35750,"2009-09-24","IT_help","Department","",""
35750,"2009-09-25","IT_help","Department","",""
35750,"2009-09-26","IT_help","Department","",""
35750,"2009-10-02","IT_help","Department","",""
35750,"2009-10-03","IT_help","Department","",""
35750,"2009-10-12","IT_help","Department","",""
35750,"2009-10-13","IT_help","Department","",""
35750,"2009-10-26","IT_help","Department","Conference/Visitors","2009-10-26 10:10:32"
35750,"2009-10-27","IT_help","Department","Conference/Visitors","2009-10-26 10:10:32"
36354,"2009-10-20","IT_help","Department","",""
36354,"2009-10-21","IT_help","Department","",""
36354,"2009-10-22","IT_help","Department","FS Students",""
36354,"2009-10-23","IT_help","Department","FS Students",""
36354,"2009-10-26","IT_help","Department","FS Students","2009-10-26 12:23:00"
36354,"2009-10-27","IT_help","Department","FS Students","2009-10-26 12:23:00"

ご覧のとおり、両方のチケットは26日にクローズされ、両方のチケットには、最初に現れた数日間空のDepartmentフィールドがありました。以下にクエリを含めました。whereステートメントの後半で返される列の数を人為的に制限していることがわかります。

SELECT d.ticket_num, d.date, q.name as QueueName, cf.name as CF, cfv.value as CFValue, d.closed
FROM daysCF dcf
INNER JOIN daily_snapshots d on dcf.day_id = d.id
INNER JOIN Queues q on d.queue_id = q.id
INNER JOIN CustomFieldValues cfv on dcf.cfv_id = cfv.id
INNER JOIN CustomFields cf on cf.id = cfv.field_id
WHERE cf.name = 'Department' and (d.ticket_num = 35750 or d.ticket_num = 36354)
ORDER by d.ticket_num, d.date

どうすればそのクエリを変更して、10月に" FS Students"のチケットが1つ閉じられたという結果セットを取得できます。 「会議/訪問者」のために1枚のチケットをクローズしましたか?

役に立ちましたか?

解決

これは「グループごとの最大のn」です;スタックオーバーフローで頻繁に発生する問題。

あなたの場合の解決方法は次のとおりです:

SELECT d1.ticket_num, d1.date, q.name as QueueName, 
  cf.name as CF, cfv.value as CFValue, d1.closed
FROM daysCF dcf
INNER JOIN daily_snapshots d1 ON (dcf.day_id = d1.id)
INNER JOIN Queues q ON (d1.queue_id = q.id)
INNER JOIN CustomFieldValues cfv ON (dcf.cfv_id = cfv.id)
INNER JOIN CustomFields cf ON (cf.id = cfv.field_id)
LEFT OUTER JOIN daily_snapshots d2 ON (d1.ticket_num = d2.ticket_num AND d1.date < d2.date)
WHERE d2.id IS NULL AND cf.name = 'Department'
ORDER by d1.ticket_num, d1.date;

他のヒント

MysqlにはLAST演算子がないため、一時テーブルを使用してこれを行う必要があります。

CREATE TEMPORARY TABLE last_dates SELECT ticket_num, MAX(date) AS date
  FROM daily_snapshots GROUP BY ticket_num

これにより、各チケットの最終日が記載されたテーブルが取得されます。次に、メインクエリで、ticket_numフィールドとdateフィールドの両方を使用してこのテーブルに対して結合します。これにより、対応するチケット番号の日付が最新ではないすべての行が除外されます。

その一時テーブルのインデックスが必要になる場合がありますので、お任せします。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top