循环使用N列的临时表中的列值

时间:2014-06-11 00:39:49

标签: sql sql-server stored-procedures dynamic-sql

我在存储过程中有一个场景,其中将生成具有未知列数(Column1.....ColumnN)的临时表。其中一列将是其他列中少数几个的总和。 客户要求是显示每列的百分比值与总列

的比较

(C1*100)/Total as P1 ,(C2*100)/Total as P2.....

除了使用LINQ在前端执行此操作外,我确实无法找到此问题的解决方案。我想知道是否有任何方法可以在SQL中实现这一点,因为这会给我带来性能上的好处。我想要做的最后一件事是循环遍历C#中的行和列,这将破坏服务器。

2 个答案:

答案 0 :(得分:1)

我做过,我只是根据你改变,你可以阅读评论以便更好地理解。我觉得schemaname是dbo,否则就改变它。

-------------1. first step --------------
--create table for exercise
CREATE TABLE [dbo].[tblTest](
    [ID] [int] NULL,
    [isTrue] [bit] NULL
) ON [PRIMARY]

--insert date
insert into tblTest values(1,'true'),(2,'false'),(3,'false'),(4,'true'),(5,'false')
select * from tbltest

-------------2. second step --------------
--now start to get column name one by one
DECLARE @TableName nvarchar(256) = '[dbo].[tblTest]', 
@SearchStr nvarchar(128)='id', @SearchStr2 nvarchar(110) --this is used to get only particular column result, to check remove uncomment in cursor
SET @SearchStr2 = QUOTENAME('%' + @SearchStr + '%','''')

DECLARE @Columnname varchar(100) ,@ColumnIndex int --, @PurchaseQty int -- declare temp variable which you u
CREATE TABLE #Results (ColumnName nvarchar(370), ColumnValue nvarchar(3630), ColIndex int)

DECLARE getItemID CURSOR    
        FOR     
        select column_name, ordinal_position from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME  = PARSENAME(@TableName, 1)

    OPEN getItemID
        FETCH NEXT  FROM getItemID INTO @Columnname, @ColumnIndex 
            WHILE @@FETCH_STATUS = 0
                BEGIN
                    --select @Columnname, @ColumnIndex ;
                     INSERT INTO #Results
                        EXEC
                        (
                            'SELECT ''' + @ColumnName + ''', LEFT(' + @ColumnName + ', 3630) , '+ @ColumnIndex +'
                            FROM ' + @TableName + ' (NOLOCK) ' 
                            --remove this to get only particular column entry
                            --+' WHERE ' + @ColumnName + ' LIKE ' + @SearchStr2 
                        )
                   FETCH NEXT   FROM getItemID INTO @Columnname, @ColumnIndex 
                END

CLOSE getItemID

DEALLOCATE getItemID

select * from #Results 

drop table #Results

答案 1 :(得分:0)

 DECLARE @cols    AS NVARCHAR(max),
        @calCols AS NVARCHAR(max),
        @query   AS NVARCHAR(max)

SELECT *
INTO   #temptable
FROM   (SELECT journeyid,
               notchl,
               Cast(Sum(Datediff(second, starttime, endtime)) AS FLOAT) AS
               Duration
        FROM   (SELECT notchlog.*,
                       CASE
                         WHEN ( Isnumeric(notch) = 1
                                AND notch < 0 ) THEN 'DYN'
                         WHEN notch = 'I' THEN 'IDLE'
                         WHEN notch = 'C' THEN 'COASTING'
                         ELSE 'N' + notch
                       END AS NotchL
                FROM   notchlog)Sub1
        GROUP  BY journeyid,
                  notchl)SUB1

SELECT @cols = Stuff(( SELECT ',' + Quotename(notchl)
                       FROM   #temptable
                       GROUP  BY notchl
                      --order by value
                       FOR XML PATH(''), TYPE                       
                     ).value('.', 'NVARCHAR(MAX)') 
                     , 1, 1, '')

SELECT @calCols = Stuff((SELECT ',' + 'ROUND(' + Quotename(notchl)
                                + '*100/RunningTime,2)  as '
                                + Quotename(notchl)
                         FROM   #temptable
                         GROUP  BY notchl
                        --order by value
                        FOR XML PATH(''), TYPE
                        ).value('.', 'NVARCHAR(MAX)')
                        , 1, 1, '')

SET @query =N'Select * INTO #ResultTable FROM( SELECT Journeyid, '
            + @cols + ' from               (                 select Journeyid, NotchL, Duration                 from #TempTable Group By JourneyId,NotchL,Duration             ) x              pivot              (                 max(x.duration)                 for NotchL in ('
            + @cols
            + ')             ) p ) Sub2                                                            select NL.JourneyId,RunningTime,'
            + @calCols
            + N' from #ResultTable R INNER Join (Select JourneyID,Sum(DateDiff(second,starttime,endtime))             as RunningTime FROM NotchLog Group By JourneyID)NL  ON NL.JourneyID=R.JourneyId             INNER Join Journeys J ON J.JourneysID=R.JourneyID                                       Drop Table #ResultTable '

EXEC Sp_executesql
  @query;

DROP TABLE #temptable  
相关问题