我在尝试编写查询时遇到问题。 (这比我之前的问题略有修改)
我的表格如下:
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 =“已关闭”则
tblTicketAttribute.Attribute中的值包括“Urgent”,“Medium”,“Low”,“Over30”,“Over60”,“Over90”,“Closed”
我不需要显示所有记录。只有“紧急”,“中等”和“ “低”。
答案 0 :(得分:4)
我不是百分百肯定我理解,但我认为这满足了你所要求的。请注意,这是假设数据库是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;
答案 1 :(得分:2)
数据库设计使用tblTicketAttribute
表的Entity-Attribute-Value模式。尝试获得这个相当普通的查询结果时遇到的困难表明EAV如何导致很多问题。
@Chad Birch的{{3}}是获得结果的一种方式。这是获得所需结果的另一种方法:
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'));
此解决方案可以更好地扩展为SQL查询,因为您在获取更多属性时不必添加更多JOIN
子句。但它确实意味着您必须对应用程序代码中的结果集进行一些后处理,以使其达到您想要的格式。
答案 2 :(得分: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之间的关系是一对一还是一对多?
答案 3 :(得分:0)
执行此类操作的一种相对简单的方法是将三个查询组合在一起。我怀疑你正在寻找的东西是这样的:
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都不同)
毫无疑问,“光滑”的方式可以做到,但我喜欢这种方式,因为阅读它时非常简单。