Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.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
Sql server 无笛卡尔结果的T-SQL多透视语句_Sql Server_Tsql_Pivot - Fatal编程技术网

Sql server 无笛卡尔结果的T-SQL多透视语句

Sql server 无笛卡尔结果的T-SQL多透视语句,sql-server,tsql,pivot,Sql Server,Tsql,Pivot,我在下面的T-SQL语句中尝试以两个不同的数据元素为中心,即studentname和instrumentname。每所学校的成绩应该只有一条线,学生们应该和他们的仪器一起绕着顶端旋转 不幸的是,我得到了一个笛卡尔结果,学生和仪器跨越多行(见查询后的屏幕截图)。我怎么能像我想的那样在每所学校排一排呢 查询: DECLARE @tempMusicSchoolStudent TABLE (school VARCHAR(50), studentname VARCHAR(50), instrumentna

我在下面的T-SQL语句中尝试以两个不同的数据元素为中心,即studentname和instrumentname。每所学校的成绩应该只有一条线,学生们应该和他们的仪器一起绕着顶端旋转

不幸的是,我得到了一个笛卡尔结果,学生和仪器跨越多行(见查询后的屏幕截图)。我怎么能像我想的那样在每所学校排一排呢

查询:

DECLARE @tempMusicSchoolStudent TABLE
(school VARCHAR(50),
studentname VARCHAR(50),
instrumentname VARCHAR(255))

INSERT INTO @tempMusicSchoolStudent(school, studentname, instrumentname)
SELECT 'Foster','Matt','Guitar'
UNION
SELECT 'Foster','Matt','Violin'
UNION
SELECT 'Foster','Jenny','Keyboard'
UNION
SELECT 'Midlothean','Kyle','Drums'
UNION
SELECT 'Midlothean','Mary','Piano'
UNION
SELECT 'Midlothean','Mary','Trumpet'

SELECT 
    p1.school, [Student1], [Instrument1], [Instrument2], [Student2],      [Instrument1], [Instrument2]
FROM 
    (SELECT 
         school, studentname, instrumentname,
         'Student' + CONVERT(VARCHAR(255), 
         DENSE_RANK() OVER(PARTITION BY school ORDER BY studentname)) [StudentNum],
         'Instrument' + CONVERT(VARCHAR(255),ROW_NUMBER() OVER(PARTITION BY school, studentname ORDER BY instrumentname)) AS [InstrumentNum]
     FROM 
         @tempMusicSchoolStudent) src
PIVOT
    (MAX(studentname) FOR [StudentNum] IN ([Student1], [Student2])) p
PIVOT
(
   MAX([instrumentname])
   FOR [InstrumentNum] IN ([Instrument1],[Instrument2])
) p1
ORDER BY p1.school
错误结果屏幕截图:

我希望结果如下所示:


这是可行的,但有点混乱,尤其是动态创建,我希望有一个更干净的选项。我甚至想不出如何用案例陈述来做到这一点,不确定这是否会更干净。如果有人有一个更干净、更易读的解决方案,正确的答案仍然可以得到。谢谢

DECLARE @tempMusicSchoolStudent TABLE
(school VARCHAR(50),
studentname VARCHAR(50),
instrumentname VARCHAR(255))

INSERT INTO @tempMusicSchoolStudent(school,studentname, instrumentname)
SELECT 'Foster','Matt','Guitar'
UNION
SELECT 'Foster','Matt','Violin'
UNION
SELECT 'Foster','Jenny','Keyboard'
UNION
SELECT 'Midlothean','Kyle','Drums'
UNION
SELECT 'Midlothean','Mary','Piano'
UNION
SELECT 'Midlothean','Mary','Trumpet'



;WITH studentPivot AS
(
    SELECT p1.school,[Student1],[Student2]
    FROM 
    (
        SELECT school, studentname,
        'Student' + CONVERT(VARCHAR(255),DENSE_RANK() OVER(PARTITION BY school ORDER BY studentname)) [StudentNum]
        FROM @tempMusicSchoolStudent
    ) src
    PIVOT
    (
        MAX(studentname)
        FOR [StudentNum] IN ([Student1],[Student2])
    ) p1
),
instrumentPivot AS
(
    SELECT p1.studentname,[Instrument1],[Instrument2]
    FROM 
    (
        SELECT school, studentname, instrumentname,
        'Instrument' + CONVERT(VARCHAR(255),ROW_NUMBER() OVER(PARTITION BY school,studentname ORDER BY instrumentname)) AS [InstrumentNum]
        FROM @tempMusicSchoolStudent
    ) src
    PIVOT
    (
        MAX(instrumentname)
        FOR [InstrumentNum] IN ([Instrument1],[Instrument2])
    ) p1
 )

SELECT sp.school,sp.Student1,ip.Instrument1,ip.Instrument2,sp.Student2,ip1.Instrument1,ip1.Instrument2
FROM studentPivot sp
JOIN instrumentPivot ip ON ip.studentname=sp.Student1
JOIN instrumentPivot ip1 ON ip1.studentname=sp.Student2
结果: +两个s:

输出:

school      student1    instrument11    instrument12    student2    instrument21    instrument22
Foster      Jenny       Keyboard        NULL            Matt        Guitar          Violin
Midlothean  Kyle        Drums           NULL            Mary        Piano           Trumpet

其主要思想是为学生和乐器制作2个序列。而不是解压数据并将学生与序列号和两个序列的仪器连接起来,因为如果我们只使用仪器序列,那么在哪个学生拥有这个仪器或第一(或第二)个仪器是谁之间就没有联系。

对于学校的“Foster”,您希望在“instrument1”列中包含哪些数据?>我用我要查找的结果编辑了原始帖子。我确实找到了一种方法,但我必须做两个单独的pivot查询,然后将它们连接在一起。我们希望有一个更干净的解决方案,它工作得非常完美,在动态SQL方面比两个单独的pivot语句友好得多。
school      student1    instrument11    instrument12    student2    instrument21    instrument22
Foster      Jenny       Keyboard        NULL            Matt        Guitar          Violin
Midlothean  Kyle        Drums           NULL            Mary        Piano           Trumpet