Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/25.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数据透视列到行中使用零或现有值填充NULL_Sql_Sql Server_Pivot - Fatal编程技术网

Sql Server数据透视列到行中使用零或现有值填充NULL

Sql Server数据透视列到行中使用零或现有值填充NULL,sql,sql-server,pivot,Sql,Sql Server,Pivot,我现在在SQL Server中有一个临时表,如下所示: IF OBJECT_ID('tempdb..#Period') IS NOT NULL DROP TABLE #Period IF OBJECT_ID('tempdb..#Account') IS NOT NULL DROP TABLE #account IF OBJECT_ID('tempdb..#BudgetDetail') IS NOT NULL DROP TABLE #BudgetDetail create table #Peri

我现在在SQL Server中有一个临时表,如下所示:

IF OBJECT_ID('tempdb..#Period') IS NOT NULL DROP TABLE #Period
IF OBJECT_ID('tempdb..#Account') IS NOT NULL DROP TABLE #account
IF OBJECT_ID('tempdb..#BudgetDetail') IS NOT NULL DROP TABLE #BudgetDetail

create table #Period([PeriodId] int,[PeriodName] varchar(50),CompanyID int)
insert into #Period values(1,'P1',100171)
insert into #Period values(2,'P2',100171)
insert into #Period values(3,'P3',100171)
select * from #Period

create table #account([AccountId] int,CompanyID int)
insert into #account values(1,100171)
insert into #account values(2,100171)
insert into #account values(3,100171)
select * from #account


create table #BudgetDetail([PeriodId] int,[AccountId] int,[Amount] money,CompanyID int)
insert into #BudgetDetail values(1,1,101,100171)
insert into #BudgetDetail values(1,2,100,100171)
insert into #BudgetDetail values(1,3,160,100171)
insert into #BudgetDetail values(2,1,110,100171)
insert into #BudgetDetail values(2,2,170,100171)
insert into #BudgetDetail values(2,3,0,100171)
insert into #BudgetDetail values(3,1,120,100171)
insert into #BudgetDetail values(3,2,180,100171)
insert into #BudgetDetail values(3,3,0,100171)

select * from #BudgetDetail

Below is my query :
    DECLARE @cols AS NVARCHAR(MAX), @query  AS NVARCHAR(MAX), @CompanyID int = 100171

 SELECT 
  @cols = STUFF((SELECT ',' + QUOTENAME([PeriodName] + ';' + 
  CONVERT(VARCHAR,[PeriodId]))
  FROM 
  #Period       
    FOR XML PATH(''), TYPE  
    ).value('.', 'NVARCHAR(MAX)'),1,1,'')  

 SET @query = 'SELECT *  FROM   
     (SELECT bd.AccountId, PeriodName, Amount    
      FROM          
     #Account acc LEFT JOIN
     #Period pr ON acc.CompanyID = pr.CompanyID LEFT JOIN
     #BudgetDetail bd ON acc.AccountId = bd.AccountID AND acc.CompanyID = 
      bd.CompanyID AND 
     pr.PeriodId = bd.PeriodId AND 
     pr.CompanyID = bd.CompanyID
    ) x  
    PIVOT
    (  
       SUM(Amount)
     FOR PeriodName IN (' + @cols + ')  
    ) p '
  print @query
  EXECUTE(@query);
当我运行上述查询时,我得到以下输出: 这是我的输出

帐户ID P1;1. P2;2. P3;3. 1. 无效的 无效的 无效的 2. 无效的 无效的 无效的 3. 无效的 无效的 无效的
您的问题是如何将PeriodId和PeriodName组合为要在pivot中检查的值

您的@cols显示为[P1;1]、[P2;2]、[P3;3] 但是您的pivot仅使用PeriodName来检查这些值

PeriodName IN (' + @cols + ')
假设您将期间名称和id组合用于特定目的,您应该做的是在select中创建相同的值

acc.AccountId, Amount, PeriodName + ';' + CONVERT(VARCHAR(10),pr.PeriodId) as PeriodKey
然后在轴中使用此组合柱

FOR PeriodKey IN (' + @cols + ') 
结果是动态sql

SET @query = '
   SELECT
       * 
   FROM   
       (SELECT
           acc.AccountId, Amount, PeriodName + '';'' + CONVERT(VARCHAR(10),pr.PeriodId) as PeriodKey
        FROM          
           #Account acc
           LEFT JOIN #Period pr ON
               acc.CompanyID = pr.CompanyID
           LEFT JOIN #BudgetDetail bd ON
               acc.AccountId = bd.AccountID
           AND acc.CompanyID = bd.CompanyID
           AND pr.PeriodId = bd.PeriodId
           AND pr.CompanyID = bd.CompanyID
       ) x  
       PIVOT
       (  
           SUM(Amount)
           FOR PeriodKey IN (' + @cols + ')  
       ) p '

您的问题是如何将PeriodId和PeriodName组合为要在pivot中检查的值

您的@cols显示为[P1;1]、[P2;2]、[P3;3] 但是您的pivot仅使用PeriodName来检查这些值

PeriodName IN (' + @cols + ')
假设您将期间名称和id组合用于特定目的,您应该做的是在select中创建相同的值

acc.AccountId, Amount, PeriodName + ';' + CONVERT(VARCHAR(10),pr.PeriodId) as PeriodKey
然后在轴中使用此组合柱

FOR PeriodKey IN (' + @cols + ') 
结果是动态sql

SET @query = '
   SELECT
       * 
   FROM   
       (SELECT
           acc.AccountId, Amount, PeriodName + '';'' + CONVERT(VARCHAR(10),pr.PeriodId) as PeriodKey
        FROM          
           #Account acc
           LEFT JOIN #Period pr ON
               acc.CompanyID = pr.CompanyID
           LEFT JOIN #BudgetDetail bd ON
               acc.AccountId = bd.AccountID
           AND acc.CompanyID = bd.CompanyID
           AND pr.PeriodId = bd.PeriodId
           AND pr.CompanyID = bd.CompanyID
       ) x  
       PIVOT
       (  
           SUM(Amount)
           FOR PeriodKey IN (' + @cols + ')  
       ) p '


[PeriodName]couln在期间中不可用Table@Srini131谢谢你的回复。让我来纠正一下。CompanyID似乎也遗漏了它现在你可以检查你的更新脚本了,为了将来的参考,这些类型的问题可以通过DBFIDLE链接变得更容易[PeriodName]couln在Period中不可用Table@Srini131谢谢你的回复。让我来纠正一下。CompanyID似乎也遗漏了它现在你可以检查你的更新脚本了,为了将来的参考,这些类型的问题可以通过DBFIDLE链接变得更容易谢谢你。你做得很好。你帮我节省了很多时间。再次感谢。您好,我需要您的帮助,当我放置筛选条件时,lats说我有IDIT列,我有这样的条件,Id='+convertvarchar,@Id+'或'+convertvarchar,@Id+'=0。它只返回一行空值,而不是我希望行数等于AccountId。嗨,首先,您应该避免将参数连接到动态sql中。请参阅这篇关于如何使用参数执行动态sql的文章。第二,你的意图或你在这种情况下想要达到的目标并不清楚。我建议发布一个单独的问题,解释您试图实现的结果,您尝试了哪些语句,以及可能的dbfiddle链接,以便我们能够理解您的问题并帮助您。您好@henrylu,我在BudgetDetail中的查询中有筛选条件is Id param。当我使用Id param运行查询时,它将不会生成预期的结果。您可以使用dbfiddle很好地检查它:pivot不返回帐户ID的原因是您的select查询使用的是bd.AccountId而不是acc.AccountId。由于您的BudgetId筛选器是44,并且只有33的数据可用,bd将不返回任何行,因此bd.AccountId始终为空。我已经更新了答案,以反映您将需要的更改,以便帐户id来自acc而不是bd。非常感谢。你做得很好。你帮我节省了很多时间。再次感谢。您好,我需要您的帮助,当我放置筛选条件时,lats说我有IDIT列,我有这样的条件,Id='+convertvarchar,@Id+'或'+convertvarchar,@Id+'=0。它只返回一行空值,而不是我希望行数等于AccountId。嗨,首先,您应该避免将参数连接到动态sql中。请参阅这篇关于如何使用参数执行动态sql的文章。第二,你的意图或你在这种情况下想要达到的目标并不清楚。我建议发布一个单独的问题,解释您试图实现的结果,您尝试了哪些语句,以及可能的dbfiddle链接,以便我们能够理解您的问题并帮助您。您好@henrylu,我在BudgetDetail中的查询中有筛选条件is Id param。当我使用Id param运行查询时,它将不会生成预期的结果。您可以使用dbfiddle很好地检查它:pivot不返回帐户ID的原因是您的select查询使用的是bd.AccountId而不是acc.AccountId。由于您的BudgetId筛选器是44,并且只有33的数据可用,bd将不返回任何行,因此bd.AccountId始终为空。我已经更新了答案,以反映您将需要的更改,以便帐户id来自acc而不是bd。