0

PropertyValueUserProfile表中有一个名为的字段,其中可以包含地址、电话号码、名字、姓氏、用户名、城市等信息...此表中的每条记录都通过 UserId 与用户关联,它也关联到一个ProfilePropertyDefinition包含每个属性的定义(即PropertyName)。

通过这种关系,我可以获得所有属性值及其属性名称。我想做的是从这两列(PropertyValue,PropertyName)中提取数据并创建一个类似的表:

First Name | Last Name | Email | Phone | City | Country
-------------------------------------------------------
           |           |       |       |      |

所以,我想知道我是否可以使用 SQL 语句来执行此操作,这是我的尝试:

SELECT FirstName = (SELECT PropertyValue FROM UserProfile WHERE PropertyDefinitionID = (SELECT PropertyDefinitionID WHERE PropertyName = 'first name')), 
LastName = (SELECT PropertyValue FROM UserProfile WHERE PropertyDefinitionID = (SELECT PropertyDefinitionID WHERE PropertyName = 'last name')), 
Email = (SELECT PropertyValue FROM UserProfile WHERE PropertyDefinitionID = (SELECT PropertyDefinitionID WHERE PropertyName = 'email'))

但这并没有奏效,而且有些东西看起来很奇怪......任何人都知道如何取一列并在几个不同的列中显示它的值?

4

7 回答 7

1
SELECT fn.PropertyValue FirstName,
       ln.PropertyValue LastName,
       etc...

From UserProfile fN
   Join UserProfile lN
      On fN.PropertyName = 'first name' 
         And ln.PropertyName = 'last name' 
         And fn.user = ln.user
   Join UserProfile eM
      On fN.PropertyName = 'first name' 
         And eM.PropertyName = 'email' 
         And eM.user = fn.user

(

于 2009-07-28T20:08:26.853 回答
1

就个人而言,我现在会停下来考虑这种设计对性能的影响。这通常是一种用于存储此类数据的非常糟糕的技术。如果您有 20 个要显示的属性,您将必须加入(并且留下加入,因为您不能保证每个属性都会被表示)到该表 20 次。此外,如果这是您的数据结构的核心(听起来它来自您似乎存储的数据类型),那么几乎每个查询都需要执行类似的操作,并且性能将非常糟糕。有时这是最好的模型(当您无法提前知道需要存储哪些属性时),但大多数时候,它的使用是糟糕设计的标志。

http://en.wikipedia.org/wiki/Entity-Attribute-Value_model

于 2009-07-28T21:54:11.693 回答
0

我想您可以多次从同一张表中进行选择。假设 tA 是具有 UserProfileID、PropertyDefinition 和 PropertyValue 的名称表

你可以做

select
t1.PropertyValue as FirstName,
t2.PropertyValue as LastName,
...
FROM
tA as t1, tA as t2, ....
WHERE
t1.PropertyDefinition Like 'FirstName' AND
t2.PropertyDefinition Like 'LastName' AND
....
AND
t1.UserId = @user AND
t2.UserID = @user ....

不理想,但它会工作

于 2009-07-28T20:02:46.113 回答
0

您需要多次加入表格(与字段一样多次):

SELECT UPFN.PropertyValue AS FirstName, UPLN.PropertyValue AS LastName, ...
FROM UserProfile UPFN
INNER JOIN ProfilePropertyDefinition PPDFN ON PPDFN.PropertyDefinitionID = UPFN.PropertyDefinitionID AND PPDFN.PropertyName = 'first name'
INNER JOIN UserProfile UPLN ON UPLN.id = UPFN.id
INNER JOIN ProfilePropertyDefinition PPDLN ON PPDLN.PropertyDefinitionID = UPLN.PropertyDefinitionID AND PPDLN.PropertyName = 'last name'
...

请注意,这依赖于它们是 UserProfile 中的某个 ID 字段,您可以使用该字段将同一用户的所有行绑定在一起。

于 2009-07-28T20:05:22.053 回答
0

假设架构像

UserProfile#
{userid,
ProfileName, 
propertyValue
}

你想做

SELECT 
 FirstName.PropertyValue  FirstNAme,
 LastName.PropertyValue  LastName,
FROM
users
JOIN (USERPROFILE) FirstName ON
FirstName.userid = users.userid
and PropertName ='FirstName'
JOIN (USERPROFILE) LastName ON
LastName.userid = users.userid
and PropertName ='LastName'
于 2009-07-28T20:08:50.737 回答
0

我会这样写查询:

Select 
  aa.userId,
  Coalesce(Max(Case when PropertyName = 'First Name' then PropertyValue else '' end),'') as FirstName,
  and so on
from
  UserTable as aa
left join
  UserProfile as bb
  on
  aa.UserId = bb.UserId
left join
  ProfilePropertyDefinition as cc
  on bb.PropertyDefinitionId = cc.PropertdefinitionId
group by
  aa.UserId
于 2009-07-28T20:09:57.113 回答
0

我需要更多地了解您的表格结构以及您想要完成的内容,但一个选项可能是创建一个 SQL 标量函数来检索属性的值。我正在对表名和数据库设置做出一些假设,但请尝试...

CREATE FUNCTION [dbo].[UserProperty] 
(
    @UserProfileID UNIQUEIDENTIFIER, @Property VARCHAR(200)
)
RETURNS VARCHAR(max)
AS
BEGIN
    -- Declare the return variable here
    DECLARE @Value AS VARCHAR(MAX)
    SELECT @Value = PropertyValue FROM UserProfile up INNER JOIN PropertyDefinitions pd ON 
    up.PropertyDefinitionID = pd.PropertyDefinitionID 
    WHERE pd.PropertyName = @Property AND up.UserProfileID=@UserProfileID

    RETURN ISNULL(@Value,'')

END

SELECT 
    [dbo].[UserProperty](UserProfileID, 'first name') AS [First Name],
    [dbo].[UserProperty](UserProfileID, 'last name') AS [Last Name],
    [dbo].[UserProperty](UserProfileID, 'email') AS [Email] 
FROM 
    [Users]
于 2009-07-28T20:13:22.613 回答