Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/82.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 在多对多表上将行转换为列_Sql_Sql Server_Tsql_Pivot_Left Join - Fatal编程技术网

Sql 在多对多表上将行转换为列

Sql 在多对多表上将行转换为列,sql,sql-server,tsql,pivot,left-join,Sql,Sql Server,Tsql,Pivot,Left Join,所以我有三张桌子: 学生: StuID ------ 1 2 斯图肯: StuConId StuID ConID StuConType Priority ---------------------------------------------- 1 1 1 Parent 1 2 1 2 Guardian 2 3 2 3 Parent 1

所以我有三张桌子:

学生:

StuID
------
1
2
斯图肯:

StuConId   StuID   ConID  StuConType  Priority
----------------------------------------------
1          1       1      Parent      1
2          1       2      Guardian    2
3          2       3      Parent      1
联系人:

ConID  ConName ConPhn
----------------------
1      John    5555555
2      Sally   4444444
3      Dana    3333333
我试图得到如下结果:

StuID  ConID1 StuConType1  ConName1  ConPhone1   ConID2 StuConType2  ConName2  ConPhone2
----------------------------------------------------------------------------------------
1      1      Parent        John     5555555     2      Guardian     Sally     4444444
2      3      Parent        Dana     3333333     Null   Null         Null      Null
到目前为止,我唯一能想到的方法是做大量的左连接(一些学生最多有10个联系人,因此stucon有10个左连接,联系人有10个)


我很确定这里有一个可以应用的轴心,但我就是不知道怎么做。

这里有一种动态实现的方法:

DECLARE @selects VARCHAR(MAX) = '', @SQL VARCHAR(MAX) = '';
SELECT @selects += '
     , MAX(CASE WHEN SC.[Priority] = ' + CAST([Priority] AS VARCHAR(255)) + ' THEN C.ConID END) [ConID' + CAST([Priority] AS VARCHAR(255)) + ']
     , MAX(CASE WHEN SC.[Priority] = ' + CAST([Priority] AS VARCHAR(255)) + ' THEN SC.StuConType END) [StuConType' + CAST([Priority] AS VARCHAR(255)) + ']
     , MAX(CASE WHEN SC.[Priority] = ' + CAST([Priority] AS VARCHAR(255)) + ' THEN C.ConName END) [ConName' + CAST([Priority] AS VARCHAR(255)) + ']
     , MAX(CASE WHEN SC.[Priority] = ' + CAST([Priority] AS VARCHAR(255)) + ' THEN C.ConPhn END) [ConPhone' + CAST([Priority] AS VARCHAR(255)) + ']'
FROM StuCon
GROUP BY [Priority]
ORDER BY [Priority];

SET @SQL = 'SELECT StuID' + @selects + ' FROM StuCon SC LEFT JOIN Contacts C ON C.ConID = SC.ConID GROUP BY StuID;';
EXEC(@SQL);

注意:它可能应该是联系人上的正常
连接
,而不是
左连接
,但这里是左连接,以防表之间存在一些不一致。
Students
表没有加入,因为它不是必需的。

这里有一种动态加入的方法:

DECLARE @selects VARCHAR(MAX) = '', @SQL VARCHAR(MAX) = '';
SELECT @selects += '
     , MAX(CASE WHEN SC.[Priority] = ' + CAST([Priority] AS VARCHAR(255)) + ' THEN C.ConID END) [ConID' + CAST([Priority] AS VARCHAR(255)) + ']
     , MAX(CASE WHEN SC.[Priority] = ' + CAST([Priority] AS VARCHAR(255)) + ' THEN SC.StuConType END) [StuConType' + CAST([Priority] AS VARCHAR(255)) + ']
     , MAX(CASE WHEN SC.[Priority] = ' + CAST([Priority] AS VARCHAR(255)) + ' THEN C.ConName END) [ConName' + CAST([Priority] AS VARCHAR(255)) + ']
     , MAX(CASE WHEN SC.[Priority] = ' + CAST([Priority] AS VARCHAR(255)) + ' THEN C.ConPhn END) [ConPhone' + CAST([Priority] AS VARCHAR(255)) + ']'
FROM StuCon
GROUP BY [Priority]
ORDER BY [Priority];

SET @SQL = 'SELECT StuID' + @selects + ' FROM StuCon SC LEFT JOIN Contacts C ON C.ConID = SC.ConID GROUP BY StuID;';
EXEC(@SQL);

注意:它可能应该是联系人上的正常
连接
,而不是
左连接
,但这里是左连接,以防表之间存在一些不一致。
Students
表没有被加入,因为它不是必需的。

google Dynamic Pivot…………我认为这里不需要Pivot。第一个联系人集上的一个连接优先级为1,第二个联系人集上的一个左连接优先级为2。google Dynamic Pivot…………我认为这里不需要Pivot。第一个联系人集中的一个连接优先级为1,第二个联系人集中的一个左连接优先级为2。此处不需要动态sql。@shawnt00您不需要动态sql,但考虑到每个学生最多可以有十个联系人(假设这不是限制),这比为十个联系人写几行要容易(假设这是最大值)…我忽略了提到10个联系人。虽然这种方法有一定的经济性,但动态sql有很多缺点,因为结果中的列数突然变化。@shawnt00结果中的列数将根据联系人的最大数量而变化。如果10是绝对限值,您不想使用d动态SQL出于这样或那样的原因,那么是的,您可以在不使用动态SQL的情况下执行此操作。如果最大数量发生变化,则可能会丢失数据。但是,是的,动态SQL可能会出现问题,这取决于您输出数据的方式。如果出于某种原因需要使用静态方法,OP可以始终
PRINT@SQL
。此处不需要动态sql。@shawnt00您不需要动态sql,但考虑到每个学生最多可以有十个联系人(假设这不是限制),这比为十个联系人写几行要容易(假设这是最大值)…我忽略了提到10个联系人。虽然这种方法有一定的经济性,但动态sql有很多缺点,因为结果中的列数突然变化。@shawnt00结果中的列数将根据联系人的最大数量而变化。如果10是绝对限值,您不想使用d动态SQL出于这样或那样的原因,那么是的,您可以在不使用动态SQL的情况下执行此操作。如果最大数量发生变化,则可能会丢失数据。但是,是的,动态SQL可能会出现问题,这取决于您输出数据的方式。如果出于某种原因需要使用静态方法,OP可以始终
PRINT@SQL
.