未确定列

时间:2018-03-01 22:55:59

标签: sql sql-server tsql pivot

我有多个表需要加入并展平。用户表,用户的属性类型表以及包含属性值的表。以下是用户表的示例:

Id  User
1   Sam
2   Bill

属性类型:

Id  Order   Property
1   30      Weight
2   20      Hair Color
3   10      Eye Color

属性值:

UserId  PropertyId  Value
1       3           Blue
1       2           Blond
1       1           170
2       3           Brown
2       2           Black
2       1           180

我希望得到这样的结果:

User    Eye Color   Hair Color  Weight
Sam     Blue        Blond       170
Bill    Brown       Black       180

请注意,属性列的顺序由属性类型中的Order列驱动。我不会提前知道属性名称是什么或可能有多少。

以下是创建3个表的代码。

DECLARE @TableA TABLE (ProperyId int, DisplayOrder int, Property varchar(50))
DECLARE @TableB TABLE (UserId int, [User] varchar(50))
DECLARE @TableC TABLE (UserId int, PropertyId varchar(50), Value varchar(50))
INSERT INTO @TableA SELECT 1, 30, 'Weight'
INSERT INTO @TableA SELECT 2, 20, 'Hair Color'
INSERT INTO @TableA SELECT 3, 30, 'Eye Color'
INSERT INTO @TableB SELECT 1, 'Sam'
INSERT INTO @TableB SELECT 2, 'Bill'
INSERT INTO @TableC SELECT 1, 3, 'Blue'
INSERT INTO @TableC SELECT 1, 2, 'Blond'
INSERT INTO @TableC SELECT 1, 1, '170'
INSERT INTO @TableC SELECT 2, 3, 'Brown'
INSERT INTO @TableC SELECT 2, 2, 'Black'
INSERT INTO @TableC SELECT 2, 1, '180'
select * from @TableA
select * from @TableB
select * from @TableC 

提前致谢! 史蒂夫。

2 个答案:

答案 0 :(得分:0)

我有一个解决方案。您可以在查询中使用第二个表(TableA)在属性,属性和订单中进行编码。所以,你实际上并不需要它。您可以使用第一个和第三个表格获得相同的结果!这是因为用户不会有两种类型的头发,眼睛和重量,因此userID和PropertyId的组合将成为第三个表(TableC)中的关键。

在这种情况下,我喜欢做的是为每个Property创建一个子查询,然后将它们与用户表连接起来。我知道这可能是更多代码,但在我处理更复杂的数据时总是更容易。

FirebaseAnimatedList(
                query: reference,
                sort: (DataSnapshot a, DataSnapshot b) =>
                    b.key.compareTo(a.key),
                padding: EdgeInsets.all(8.0),
                reverse: true,
                itemBuilder: (BuildContext context, DataSnapshot snapshot,
                    Animation<double> animation) {
                  return ChatMessage(snapshot: snapshot, animation: animation);
                },
              ),

祝你好运!

答案 1 :(得分:0)

尝试在将表构建为临时表时使其工作太麻烦,因此我更改了模式代码以使其成为实际表(并更正了其中一个列名称中的拼写错误)。可以在SQL Fiddle上找到更改的模式代码和结果代码here,以便您可以对其进行测试,但我也将结果代码放在下面。关键是你必须使用SQL来编写你需要的SQL(因为你不知道所有的列是什么):

DECLARE
    @Columns NVARCHAR(MAX),
    @SQL_Statement NVARCHAR(MAX)

SELECT  @Columns = ISNULL( @Columns + ', ', '') + '[' + s.Property + ']' FROM (SELECT DISTINCT [Property] FROM TableA) AS s

SELECT @SQL_Statement = '
WITH cte_Flat AS
(
SELECT
    b.[User],
    a.[Property],
    C.[Value]
FROM
    TableC AS c
JOIN
    TableB AS b
ON
    c.[UserID] = b.[UserID]
JOIN
TableA AS a
ON
    c.[PropertyId] = a.[PropertyID]
)
SELECT
    [User],
    ' + @Columns + '
FROM
    cte_Flat
PIVOT
    (
      MAX([Value])
      for [Property] in (' + @Columns + ')
    ) AS u'

EXEC SP_EXECUTESQL  @SQL_Statement = @SQL_Statement