我有这样的表格:
Fields (ID int, Name varchar(20))
ID Name
===============
1 FieldName
2 FeildDesc
Container (ID int, Name varchar(100))
ID Name
====================================
1 C1
2 C2
3 C3
ContainerField (ContainerId int, FieldId int, FieldValue varchar(100))
ContainerId FieldId FieldValue
====================================
1 1 Container1
1 2 Container1 Desc
2 1 Container2
2 2 Container3 Desc
3 1 Container3
我希望我的结果如下:
ContainerId Name Desc
===================================
1 Container1 Container1 Desc
2 Container2 Container2 Desc
3 Container3 NULL
我尝试在ContainerField和Field之间进行LEFT OUTER JOIN,但这似乎不起作用。如果有人能提供帮助,我会很感激。
答案 0 :(得分:3)
加入表格两次,一次是名字,一次是说明。
select
c.Id as ContainerId,
cfn.FieldValue as Name,
cfd.FieldValue as Desc
from
Container c
left join ContainerField cfn
on cfn.ContainerId = c.ID and cfn.FieldId = 1
left join ContainerField cfd
on cfd.ContainerId = c.ID and cfd.FieldId = 2
如您所见,不是群组或聚合。此外,您在查询中并不真正需要Fields tabel本身,尽管将它放在数据库中是很好的,因为它强制引用完整性(如果您有正确的密钥)并且它提供了一种文档。但你也可以使用枚举。
或者,如果您不仅有两个字段,但其数目未知,则可能需要考虑pivot tables
。我必须承认我对这些并不是很好,特别是在TSQL中,所以我会为你提供一个链接供你探索:http://technet.microsoft.com/en-us/library/ms177410(v=sql.105).aspx或者希望其他人可以给你一个具体的例子。
答案 1 :(得分:1)
不需要外部联接,内部联接将执行此操作。您还没有使用Container
中的任何内容(如果您想显示容器名称而不是ID,则可以使用它进行内部联接以获取该内容)。
SELECT c.id AS ContainerID,
MAX(CASE WHEN f.name = 'FieldName' THEN c.FieldValue END) AS Name,
MAX(CASE WHEN f.name = 'FieldDesc' THEN c.FieldValue END) AS `Desc`
FROM ContainerField AS c
JOIN Fields AS f ON c.FieldID = f.id
GROUP BY ContainerID
请注意,您的Fields
表格中存在拼写错误:FeildsDesc
应为FieldsDesc
。
答案 2 :(得分:1)
不妨投入我的两分钱。这将为您提供所需的一切。它在Oracle中完成但应该也一样。
编辑:SQL Fiddle Demo了解一个工作示例。
Select * From (
WITH
/* Example Tables.*/
Container As
(
Select 1 as ID, 'C1' as Name From Dual Union All
Select 2 as ID, 'C2' as Name From Dual Union All
Select 3 as ID, 'C3' as Name From Dual
)
,ContainerField as
(
Select 1 as ContainerId, 1 as FieldId, 'Container1 ' as FieldValue From Dual UNION ALL
Select 1 as ContainerId, 2 as FieldId, 'Container1 Desc' as FieldValue From Dual UNION ALL
Select 2 as ContainerId, 1 as FieldId, 'Container2 ' as FieldValue From Dual UNION ALL
Select 2 as ContainerId, 2 as FieldId, 'Container2 Desc' as FieldValue From Dual UNION ALL
Select 3 as ContainerId, 1 as FieldId, 'Container3 ' as FieldValue From Dual
)
/*Code*/
Select
C.ID,
Max(Case When CF.FieldId = 1 Then FieldValue End) as Name,
Max(Case When CF.FieldId = 2 Then FieldValue End) as Descrption
From
Container C
Left Join ContainerField CF on C.ID = CF.ContainerID
Group By
C.ID,
C.Name
Order By
C.ID
)
输出:
CONTAINERID NAME DESCRPTION
1 Container1 Container1 Desc
2 Container2 Container2 Desc
3 Container3
答案 3 :(得分:0)
你似乎需要一个left join
:
select c.id, c.name, cf.FieldValue
from Container c join
ContainerField cf
on cf.ContainerId = c.id and cf.FieldId = 2;
当然,你问题中的数据有点误导。我假设name
列旨在来自Container
表。
答案 4 :(得分:0)
我认为这就是你所追求的目标:
SELECT t1.ContainerId, t1.FieldValue, t2.FieldValue
FROM ContainerField t1
LEFT JOIN ContainerField t2 ON t1.ContainerId = t2.ContainerId
AND t1.FieldId = 1 and t2.FieldId = 2
编辑(SQL Fiddle):
SELECT DISTINCT t1.ContainerId,
(
SELECT t2.FieldValue FROM ContainerField t2
WHERE t2.FieldId = 1 AND t1.ContainerId = t2.ContainerId
) AS [Name],
(
SELECT t3.FieldValue FROM ContainerField t3
WHERE t3.FieldId = 2 AND t1.ContainerId = t3.ContainerId
) AS [Desc]
FROM ContainerField t1