Sql 在单独的列中查询多个EAV属性
我在尝试编写查询时遇到了一些问题。(这是对我上一个问题的轻微修改) 我的桌子布置如下:Sql 在单独的列中查询多个EAV属性,sql,entity-attribute-value,Sql,Entity Attribute Value,我在尝试编写查询时遇到了一些问题。(这是对我上一个问题的轻微修改) 我的桌子布置如下: tblTicketIssues.TicketID tblTicketIssues.RequesterID tblPersonnelProfile.PersonnelID tblPersonnelProfile.FirstName tblPersonnelProfile.LastName tblTicketAttribute.TicketID tblTicketAttribute.Attrib
tblTicketIssues.TicketID
tblTicketIssues.RequesterID
tblPersonnelProfile.PersonnelID
tblPersonnelProfile.FirstName
tblPersonnelProfile.LastName
tblTicketAttribute.TicketID
tblTicketAttribute.Attribute
tblTicketAttribute.AttributeValue
我必须显示以下字段:
TicketID, RequesterFullName, UrgentPriorityID, MediumPriorityID,
LowPrioritytID
这是具有挑战性的部分:
如果tblTicketAttribute.Attribute=“紧急”,则tblTicketAttribute.AttributeValue中的值将显示在UrgentPriority列中
如果tblTicketAttribute.Attribute=“Medium”,则来自tblTicketAttribute.AttributeValue的值将显示在MediumPriority列中
如果tblTicketAttribute.Attribute=“低”,则tblTicketAttribute.AttributeValue中的值将显示在低优先级列中
如果tblTicketAttribute.Attribute=“Closed”,则
tblTicketAttribute.属性中的值包括“紧急”、“中等”、“低”、“超过30”、“超过60”、“超过90”、“关闭”
我不需要显示所有记录。只有“紧急”、“中等”和“低”。我不能100%确定我是否理解,但我认为这满足了您的要求。请注意,这是假设数据库是MySQL,您没有指定。IF()和CONCAT()的语法可能稍有不同 编辑:根据Csharp下面的“答案”更新查询
MAX
-盗用这个名字有点麻烦
我不知道您为什么要这样做,但下面是(假设SQL Server): 但这对我来说似乎是一种奇怪的方式
您能否澄清tbTicketAttributes和tbTicketAttributes之间的关系是一对一还是一对多?这样做的一种相对简单的方法是将三个查询合并在一起。我怀疑你要找的是这样的东西:
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上都会有很大不同)
毫无疑问,有一些“更巧妙”的方法可以做到这一点,但我喜欢这种方法,因为它在阅读时非常简单。数据库设计使用了
tblTicketAttribute
表的模式。您在尝试获取这个相当普通的查询结果时遇到的困难表明了EAV是如何导致许多问题的
通过@Chad Birch的测试是获得结果的一种方法。以下是获得您想要的结果的另一种方法:
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
子句。但这确实意味着您必须对应用程序代码中的结果集进行一些后处理,以将其转换为您想要的格式。这个问题实际上可以有一个更好(更具描述性)的标题和一些额外的适当标记。
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');
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'));