Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Tsql 使用两列的t sql动态透视_Tsql - Fatal编程技术网

Tsql 使用两列的t sql动态透视

Tsql 使用两列的t sql动态透视,tsql,Tsql,样本数据集如下所示[同样,这只是一个小样本]: DECLARE @Test Table ( Name Varchar(32), Code Varchar(20) ) INSERT INTO @Test(Name, Code) VALUES ('A-1', 'A-One') , ('A 2', 'A-Two') , ('B 1-b', 'B-One') , ('B', 'A-Two') , ('C', 'A-One') , ('C', 'B-One') , ('C', 'C-

样本数据集如下所示[同样,这只是一个小样本]:

DECLARE @Test Table
(
  Name   Varchar(32),
  Code   Varchar(20)
)

INSERT INTO @Test(Name, Code) VALUES
  ('A-1', 'A-One')
, ('A 2', 'A-Two')
, ('B 1-b', 'B-One')
, ('B', 'A-Two')
, ('C', 'A-One')
, ('C', 'B-One')
, ('C', 'C-One')
请注意,代码值[如A-One、A-Two和B-One]可能与多个名称值关联

例如,A-One以名称A-1和名称C出现

我想输出它,使其看起来像这样[除了,有比我显示的更多的值-这些值可以更改]:

Name    Code
A-1     A-One
A 1     A-Two
B 1-b   B-One
B       A-Two 
C       A-One
C       B-One
C       C-One
“名称”值和代码值的数量可以更改。它们不是常数

目标是能够查看左侧的代码值列表,并轻松查看代码与哪些名称值关联


我相信这需要创建动态pivot sql,我在理解pivot sql方面有困难,我将非常感谢任何帮助或指针。

pivot
将在公共列名下显示一个现有的值(更确切地说,是聚合的现有值)。您可以使用
PIVOT
解决此问题,方法是使用
CASE
语句返回
X
,然后尝试使用此值进行数据透视

但我认为,条件聚合可能是你的朋友:

             A-1      A 1        B 1-b          B      C
A-One        X                                         X
A-Two                  X                        X   
B-One                             X                    X
C-One                                                  X
带枢轴:

DECLARE @Test Table
(
  Name   Varchar(1),
  Code   Varchar(10)
)

INSERT INTO @Test(Name, Code) VALUES
  ('A', 'A-One')
, ('A', 'A-Two')
, ('B', 'B-One')
, ('B', 'A-Two')
, ('C', 'A-One')
, ('C', 'B-One')
, ('C', 'C-One');

SELECT t.Code
      ,MAX(CASE WHEN t.[Name]='A' THEN 'X' END) AS A
      ,MAX(CASE WHEN t.[Name]='B' THEN 'X' END) AS B
      ,MAX(CASE WHEN t.[Name]='C' THEN 'X' END) AS C
      ,MAX(CASE WHEN t.[Name]='D' THEN 'X' END) AS D
FROM @Test t
GROUP BY Code
动态,测试为永久表:

select Code, 
case when A > 0 then 'X' else '' end as A, 
case when B > 0 then 'X' else '' end as B, 
case when C > 0 then 'X' else '' end as C
from (
    select Name, Code from @Test
) p
pivot(count(Name) for Name in ([A], [B], [C])) as res;
仅使用单引号,以及处理名称中的空格/破折号:

set quoted_identifier off;

declare @caseStmts varchar(max) = '', @inList varchar(max) = '';

select 
    @caseStmts += 
    (case when len(@caseStmts) > 0 then ', ' else '' end) +
    ("case when " + t.Name + " > 0 then 'X' else '' end as " + t.Name + " "),
    @inList += 
    (case when len(@inList) > 0 then ', ' else '' end) +
    ('[' + t.Name + ']')
from (select distinct Name from Test)
as t;

declare @pivotSql nvarchar(max);
select @pivotSql =
    "select Code, " + @caseStmts + 
    " from (select Name, Code from Test) p " +
    "pivot(count(Name) for Name in (" + @inList + ")) as res;";

exec sp_executesql @pivotSql;

谢谢@Shnugo。您的代码为我显示的有限数据生成了我想要的精确输出。选择t.Code没有问题,因为它将获得表中的所有t.Code值。但是t.Name有很多值,它们经常变化。它不是一个固定数量的值-加上它经常变化-所以我不能像您那样硬编码每个值。如何对其进行编码以说明运行时表中所有可能的t.Name值?@Talay,您必须将整个语句创建为字符串(动态创建的SQL),并使用
EXEC()
触发执行。如果您需要这方面的帮助,请关闭此问题(因为初始问题已解决,且上述问题是一个全新的问题)。然后用更多的样本数据开始一个新的问题,帮助会立即到来。谢谢@Shnugo。在我最初的帖子中,我有这样一句话:“名称”值和代码值的数量可以改变。它们不是常数。”我希望这能清楚地表明,我发布的有限数据只是一个小样本?不过,我还是很感激你的建议!再次感谢!!!:DHi@Shnugo。我在Thank@Todd Bellamy上重新发布。您的代码为我显示的有限数据生成了我想要的精确输出。选择t.Code没有问题,因为它将获得表中的所有t.Code值。但是t.Name有很多值,它们经常变化。它不是一个固定数量的值——加上它经常变化——所以我不能像您在案例陈述中那样硬编码每个值。我该如何编写代码来说明运行时表中所有可能的t.Name值?谢谢@Todd Bellamy。我将尝试这一点,并张贴结果!嗨,托德·贝拉米。我得到一个错误:Msg 102,15级,状态1,第1行'-'附近语法不正确。Msg 102,15级,状态1,第1行“p”附近语法不正确。" ... 虽然我不确定这一点,但我相信这与正在使用的双引号有关。几天前,我从Shnugo那里得到了一个类似的解决方案,但它只使用了单引号。有什么建议吗?您是否关闭了“set quoted\u identifier;”电话?是的。我确实关闭了“set quoted\u标识符;”是否可以在不使用双引号的情况下对其进行编码?我问这个问题的唯一原因是,我用于不同输出的类似sql只使用单引号,这很好。我的SQL Server中是否有其他设置可能会干扰此SQL?
declare @caseStmts varchar(max) = '', @inList varchar(max) = '';

select 
    @caseStmts += 
    (case when len(@caseStmts) > 0 then ', ' else '' end) +
    ('case when [' + t.Name + '] > 0 then ''X'' else '''' end as ''' + t.Name + ''' '),
    @inList += 
    (case when len(@inList) > 0 then ', ' else '' end) +
    ('[' + t.Name + ']')
from (select distinct Name from Test)
as t;

declare @pivotSql nvarchar(max);
select @pivotSql =
    'select Code, ' + @caseStmts + 
    ' from (select Name, Code from Test) p ' +
    'pivot(count(Name) for Name in (' + @inList + ')) as res;';

exec sp_executesql @pivotSql;