0

クエリを作成しようとして問題に直面しています。(これは私の前の質問から少し変更されています)

私のテーブルは次のようにレイアウトされています:

 tblTicketIssues.TicketID
 tblTicketIssues.RequesterID

 tblPersonnelProfile.PersonnelID
 tblPersonnelProfile.FirstName
 tblPersonnelProfile.LastName

 tblTicketAttribute.TicketID
 tblTicketAttribute.Attribute
 tblTicketAttribute.AttributeValue

次のフィールドを表示する必要があります。

 TicketID, RequesterFullName, UrgentPriorityID, MediumPriorityID, 
 LowPrioritytID

これは挑戦的な部分です:

tblTicketAttribute.Attribute= "Urgent" の場合、tblTicketAttribute.AttributeValue の値が UrgentPriority 列に表示されます。

tblTicketAttribute.Attribute= "Medium" の場合、tblTicketAttribute.AttributeValue の値が MediumPriority 列に表示されます。

tblTicketAttribute.Attribute= "Low" の場合、tblTicketAttribute.AttributeValue の値が LowPriority 列に表示されます。

tblTicketAttribute.Attribute= "Closed" の場合

tblTicketAttribute.Attribute の値には、「緊急」、「中」、「低」、「30 以上」、「60 以上」、「90 以上」、「クローズ」があります。

すべてのレコードを表示する必要はありません。「至急」「中」「低」のみ。

4

4 に答える 4

4

100% 理解しているとは言えませんが、これであなたの求めているものは満たされると思います。これは、データベースが MySQL であると想定していたことに注意してください。指定していません。IF() と CONCAT() の構文は、それ以外の場合は少し異なる場合があります。

編集: 以下の Csharp の「回答」に従ってクエリを更新しました。MAX-名前を付けるのはちょっとしたハックです。

SELECT t.TicketID,
    MAX(CONCAT(p.FirstName, ' ', p.LastName)) AS RequesterFullName,
    MAX(IF(a.Attribute = 'Urgent', a.AttributeValue, NULL)) AS UrgentPriorityID,
    MAX(IF(a.Attribute = 'Medium', a.AttributeValue, NULL)) AS MediumPriorityID,
    MAX(IF(a.Attribute = 'Low', a.AttributeValue, NULL)) AS LowPriorityID
FROM tblTicketIssues AS t
    LEFT JOIN tblPersonnelProfile AS p ON p.PersonnelID = t.RequesterID
    LEFT JOIN tblTicketAttribute AS a ON a.TicketID = t.TicketID
WHERE a.Attribute IN ('Urgent', 'Medium', 'Low')
GROUP BY t.TicketID;
于 2009-03-19T17:06:33.683 に答える
2

データベース設計では、テーブルにEntity-Attribute-Valueパターンを使用しtblTicketAttributeます。このかなり普通のクエリ結果を取得しようとして直面した困難は、EAV がいかに多くの問題を引き起こすかを示しています。

@Chad Birch による解決策は、結果を得るための 1 つの方法です。必要な結果を得る別の方法を次に示します。

SELECT t.TicketID,
    CONCAT(p.FirstName, ' ', p.LastName) AS RequesterFullName,
    a1.AttributeValue AS UrgentPriorityID,
    a2.AttributeValue AS MediumPriorityID,
    a3.AttributeValue AS LowPriorityID
FROM tblTicketIssues AS t
  JOIN tblPersonnelProfile AS p ON (p.PersonnelID = t.RequesterID)
  LEFT JOIN tblTicketAttribute AS a1 
    ON (a1.TicketID = t.TicketID AND a1.Attribute = 'Urgent')
  LEFT JOIN tblTicketAttribute AS a2 
    ON (a2.TicketID = t.TicketID AND a2.Attribute = 'Medium')
  LEFT JOIN tblTicketAttribute AS a3 
    ON (a3.TicketID = t.TicketID AND a3.Attribute = 'Low');

このソリューションでは句を使用しませんが、取得する属性ごとにGROUP BY個別の句が必要です。JOIN

さらに別の解決策は、結果セットの複数の行で属性をフェッチすることです。

SELECT t.TicketID,
    CONCAT(p.FirstName, ' ', p.LastName) AS RequesterFullName,
    a.AttributeValue AS AnyPriorityID
FROM tblTicketIssues AS t
  JOIN tblPersonnelProfile AS p ON (p.PersonnelID = t.RequesterID)
  LEFT JOIN tblTicketAttribute AS a 
    ON (a1.TicketID = t.TicketID AND a.Attribute IN ('Urgent', 'Medium', 'Low'));

JOINこのソリューションは、より多くの属性を取得するときに句を追加する必要がないため、SQL クエリとしてより適切にスケーリングされます。ただし、結果セットを目的の形式にするために、アプリケーション コードで結果セットの後処理を行う必要があることを意味します。

于 2009-03-19T18:22:39.787 に答える
1

なぜこのようにしたいのかわかりませんが、ここに行きます(SQL Serverを想定):

 SELECT TicketID, FirstName + ' ' + LastName AS RequestFullName,
 CASE WHEN Attribute = "Low" THEN AttributeValue ELSE "" END AS LowPriorityID,
 CASE WHEN Attribute = "Medium" THEN AttributeValue ELSE "" END AS MediumPriorityID,
 CASE WHEN Attribute = "Urgent" THEN AttributeValue ELSE "" END AS UrgentPriorityID
 FROM ...
 WHERE Attribute IN ("Urgent", "Low", "Medium")

しかし、それは私には奇妙なやり方のように思えます。

tbTicketIssues と tbTicketAttributes の関係が 1 対 1 なのか、それとも 1 対多なのかを明確にできますか?

于 2009-03-19T17:09:29.870 に答える
0

このようなことを行う比較的簡単な方法の 1 つは、3 つのクエリを結合することです。あなたが探しているのは次のようなものだと思います:

SELECT i.TicketID, a.FirstName, pp.AttributeValue AS UrgentPriorityID, null AS MediumPriorityID, null AS LowPrioritytID
FROM tblTicketIssues i, tblTicketAttribute a, tblPersonnelProfile pp
WHERE i.RequesterID = a.PersonnelID
AND i.TicketID = pp.TicketID
AND pp.Attribute = "Urgent"
UNION
SELECT i.TicketID, a.FirstName, null AS UrgentPriorityID, pp.AttributeValue AS MediumPriorityID, null AS LowPrioritytID
FROM tblTicketIssues i, tblTicketAttribute a, tblPersonnelProfile pp
WHERE i.RequesterID = a.PersonnelID
AND i.TicketID = pp.TicketID
AND pp.Attribute = "Medium"
UNION
SELECT i.TicketID, a.FirstName, null AS UrgentPriorityID, null AS MediumPriorityID, pp.AttributeValue AS LowPrioritytID
FROM tblTicketIssues i, tblTicketAttribute a, tblPersonnelProfile pp
WHERE i.RequesterID = a.PersonnelID
AND i.TicketID = pp.TicketID
AND pp.Attribute = "Low"

(これは SQL Server ですが、ほぼすべての RDBMS で大きく異なるとは思えません)

これを行うための「より洗練された」方法は間違いなくありますが、私はこの方法が好きです。

于 2009-03-19T17:12:47.490 に答える