简体   繁体   English

SQL查询和取消语法

[英]SQL Query & unpivot Syntax

I have a permission system that defines users access to certain items. 我有一个权限系统,用于定义用户对某些项目的访问权限。

I need a report page to show members and their access to the items. 我需要一个报告页面来显示成员及其对项目的访问权限。

The table needs to be like this: 该表需要像这样:

+---------+--------+--------+------+--------+
| Members | Item 1 | Item 2 | .... | Item N |
+---------+--------+--------+------+--------+
| Member1 |   x    |    +   | .... |   +    |
+---------+--------+--------+------+--------+
| Member2 |   +    |    x   | .... |   +    |
+---------+--------+--------+------+--------+

I have a 3 table joined query for listing the members and the items they can access but I could not convert it into pivot syntax. 我有一个3表联接查询,用于列出成员和他们可以访问的项目,但是我无法将其转换为数据透视语法。

Select members.id memberID, members.name memberName, items.name as item
From members
Left Join member_permission On memberID = members.id
Left Join items On items.id = member_permission.itemID

This is the not working query I have: 这是我无法使用的查询:

Select memberName, itemName
From (
    select members.id, members.name, item.name as itemName
    from members
    Left Join member_permission On memberID = members.id
    Left Join item On item.id = member_permission.itemID
) p
Unpivot
(itemName For name IN (item.name)) as unp

and the error I receive: 和我收到的错误:

The column name "name" specified in the UNPIVOT operator conflicts with the existing column name in the UNPIVOT argument. UNPIVOT运算符中指定的列名称“名称”与UNPIVOT参数中的现有列名称冲突。

I created an example to play with Sqlfiddle 我创建了一个使用Sqlfiddle的示例

You don't need to use UNPIVOT for this query. 您无需为此查询使用UNPIVOT。 UNPIVOT is used to convert multiple columns into multiple rows. UNPIVOT用于将多列转换为多行。 You only need to apply the PIVOT function to turn your items into columns. 您只需要应用PIVOT函数将您的项目变成列。

I would first suggest using a windowing function like row_number() to create your new column headers, then apply the PIVOT function: 我首先建议使用像row_number()这样的窗口函数来创建新的列标题,然后应用PIVOT函数:

select id, name, Item1, Item2, Item3
from
(
  select members.id, members.name, items.name as item,
    'item'+
      cast(row_number() over(partition by members.id 
                             order by members.id) as varchar(10)) col
  from members
  Left Join member_permission 
    On memberID = members.id
  Left Join items 
    On items.id = member_permission.itemID
) d
pivot
(
  max(item)
  for col in (Item1, Item2, Item3)
) piv;

See SQL Fiddle with Demo . 请参阅带有演示的SQL Fiddle Then if you have an unknown number of values your query would need to use dynamic SQL: 然后,如果您有未知数量的值,则查询将需要使用动态SQL:

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT ',' + QUOTENAME('item'+cast(seq as varchar(10))) 
                    from
                    (
                      select row_number() over(partition by memberid
                                               order by memberid) seq
                      from member_permission
                    ) d
                    group by seq
                    order by seq
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = N'SELECT id, name, ' + @cols + N' 
            from 
            (
              select members.id, members.name, items.name as item,
                ''item''+
                  cast(row_number() over(partition by members.id 
                                         order by members.id) as varchar(10)) col
              from members
              Left Join member_permission 
                On memberID = members.id
              Left Join items 
                On items.id = member_permission.itemID
            ) x
            pivot 
            (
                max(item)
                for col in (' + @cols + N')
            ) p '

execute sp_executesql @query;

See SQL Fiddle with Demo 参见带有演示的SQL Fiddle

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM