应该很简单,但这会给我带来一些问题。
我有一个类似于以下的数据集:
User
UserID
Name
Age
UserPropertyValues
UserID
PropertyCodeValueID
PropertyCodes
PropertyCodeID
PropertyCodeName
PropertyCodeValues
PropertyCodeValueID
PropertyCodeID
PropertValue
现在让我们假设这些表包含以下数据:
1 John 25
2 Sarah 34
1 2
1 3
2 1
2 3
1 FavColour
2 CarMake
3 PhoneType
1 1 Blue
2 1 Yellow
3 2 Ford
4 3 Mobile
5 3 Landline
现在我要创建一个视图来返回用户详细信息,以及属性代码1和2的属性值,如下所示:
John 25 Yellow Ford
Sarah 34 Blue Ford
到目前为止我尝试过的查询往往会返回重复的数据行:
John 25 Yellow
John 25 Ford
Sarah 34 Blue
Sarah 34 Ford
感谢任何帮助,提前谢谢大家。
答案 0 :(得分:2)
输入数据:
DECLARE @User TABLE (UserID INT, Name VARCHAR(10), Age INT)
INSERT INTO @User
SELECT 1, 'John', 25 UNION
SELECT 2, 'Sarah', 34
DECLARE @UserPropertyValues TABLE(UserID INT, PropertyCodeValueID INT)
INSERT INTO @UserPropertyValues
SELECT 1, 2 UNION
SELECT 1, 3 UNION
SELECT 2, 1 UNION
SELECT 2, 3
DECLARE @PropertyCodes
TABLE (PropertyCodeID INT, PropertyCodeName VARCHAR(10))
INSERT INTO @PropertyCodes
SELECT 1, 'FavColour' UNION
SELECT 2, 'CarMake' UNION
SELECT 3, 'PhoneType'
DECLARE @PropertyCodeValues TABLE (PropertyCodeValueID INT,
PropertyCodeID INT, PropertValue VARCHAR(10))
INSERT INTO @PropertyCodeValues
SELECT 1, 1, 'Blue' UNION
SELECT 2, 1, 'Yellow' UNION
SELECT 3, 2, 'Ford' UNION
SELECT 4, 3, 'Mobile' UNION
SELECT 5, 3, 'Landline'
如果结果中需要两个属性,并且每个用户都具有这些属性,请尝试以下操作:
SELECT U.Name, U.Age, PCVFC.PropertValue, PCVCM.PropertValue
FROM @User U
INNER JOIN @UserPropertyValues UPVFC ON U.UserID = UPVFC.UserID
INNER JOIN @PropertyCodeValues PCVFC
ON UPVFC.PropertyCodeValueID = PCVFC.PropertyCodeValueID
AND PCVFC.PropertyCodeID = 1
INNER JOIN @UserPropertyValues UPVCM ON U.UserID = UPVCM.UserID
INNER JOIN @PropertyCodeValues PCVCM
ON UPVCM.PropertyCodeValueID = PCVCM.PropertyCodeValueID
AND PCVCM.PropertyCodeID = 2
[edit] 但要处理可能的NULL值,请更好地使用:
SELECT U.Name, U.Age, FC.PropertValue, CM.PropertValue
FROM @User U
LEFT JOIN (
SELECT UserID, PropertValue FROM @UserPropertyValues UPV
INNER JOIN @PropertyCodeValues PCV
ON UPV.PropertyCodeValueID = PCV.PropertyCodeValueID
AND PCV.PropertyCodeID = 1
) FC ON U.UserID = FC.UserID
LEFT JOIN (
SELECT UserID, PropertValue FROM @UserPropertyValues UPV
INNER JOIN @PropertyCodeValues PCV
ON UPV.PropertyCodeValueID = PCV.PropertyCodeValueID
AND PCV.PropertyCodeID = 2
) CM ON U.UserID = CM.UserID
答案 1 :(得分:1)
您真正需要的是尽快放弃这种类型的数据库设计。它永远不会有效率。要获得三种类型的值,您必须三次加入表中。一旦您有30或40种不同类型的信息,您将需要多次加入该表(并且左键加入该表)。每当您需要任何信息时,您都需要加入此表。我认为这是在数据库中创建一个主要的锁定问题。最初设计我使用的数据库之一的人就是这样做的,当公司从拥有一两个客户发展成为我们行业中最大的客户时,就会产生巨大的性能问题。
如果属性是每个人可能只有一个实际记录的属性,则将它们放入用户表中。如果他们将有多个记录,那么为每种类型的信息创建一个单独的表(一个用于hones,一个用于电子邮件,一个用于cartype等)。因为您最终想要收集的信息通常不仅仅是简单的值和对于每种类型的信息,它们必须在不同的表中。然后,当您只需要查看一个值(比如电话号码而不是电子邮件)时,您就可以加入到该表中,并且您不会干扰尝试访问电子邮件而非电话号码的人。如果您有黄色福特或白色本田,它将仅存储在自动表中的一个记录中,而不是存储在您设计中的两个属性记录中。
答案 2 :(得分:0)
SELECT
u.[Name],
u.Age,
pcv1.PropertValue,
pcv2.PropertValue
FROM
Users u
LEFT JOIN
( UserPropertyValues upv1
JOIN PropertyCodeValues pcv1 ON
upv1.PropertyCodeValueID = pcv1.PropertyCodeValueID
AND pcv1.PropertyCodeID = 1
)
ON upv1.UserID = u.UserID
LEFT JOIN (
UserPropertyValues upv2
JOIN PropertyCodeValues pcv2 ON
upv2.PropertyCodeValueID = pcv2.PropertyCodeValueID
AND pcv2.PropertyCodeID = 2
)
ON upv2.UserID = u.UserID
编辑:我将用户重命名为用户
Edit2:允许为空(未输入值)