我在存储过程中有一个场景,其中将生成具有未知列数(Column1.....ColumnN
)的临时表。其中一列将是其他列中少数几个的总和。
客户要求是显示每列的百分比值与总列
(C1*100)/Total as P1 ,(C2*100)/Total as P2.....
除了使用LINQ在前端执行此操作外,我确实无法找到此问题的解决方案。我想知道是否有任何方法可以在SQL中实现这一点,因为这会给我带来性能上的好处。我想要做的最后一件事是循环遍历C#中的行和列,这将破坏服务器。
答案 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