努力获取结果(视图,变量,存储过程)

时间:2019-04-30 13:16:50

标签: sql sql-server

据我了解,您无法使用变量创建视图。困境是我必须对值做一些datediff。我们的第三方报告软件只能对表格或视图执行基本选择。我无法调用任何存储过程或在那里设置变量。

我的原始源数据看起来select * from tblquotestatuschangelog 结果,我希望看到这些结果

Quotenumber   UpdatedOn    Status    UpdatedBy
----------------------------------------------
100001     04102019     Open      domain/user
100001     04132019     Closed    domain/user

我已经对该数据进行了处理,以通过此查询以所需的格式获取结果。 (状态类型比本示例中的更多,可以通过我们使用的CRM添加更多状态类型)(Q1

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX);

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(T1.STATUS) 
            FROM tblCglQuoteStatusChangeLog as T1
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT quotenumber, ' + @cols + ' from 
            (
                select quotenumber, status, updatedon, updatedby
                from tblcglquotestatuschangelog
                where updatedon > 2019-04-01
           ) x
            pivot 
            (
                 max(updatedon)
                for status in (' + @cols + ')
            ) p '

execute @query 

要获得这些结果

Quotenumber   Open    Closed       
----------------------------------------------
100001     04102019     04132019

我想调用(Q1作为视图来执行

     Select
         QuoteNumber, 
         case when datediff(day,Open, Closed) = 0 then Cast('SAMEDAY' AS NVARCHAR(20)) else cast(datediff(day,openedon,updatedon) as NVarCHAR(20)) end as TotalAge,
         datediff(day,Open,SentToCustomer) as Stage1,
         datediff(day,SentToCustomer,) as Stage2,
     From V1

任何帮助或其他方向取得成果的人将不胜感激。

1 个答案:

答案 0 :(得分:0)

您可以使用条件聚合来获得结果-只要您要依赖于有关数据形状的假设即可。这些就是您对我的问题的答案-元组是唯一的,并且只有两个状态值。如果您有更多状态值(闻起来像您一样),则可以扩展逻辑

use tempdb; 
set nocount on;
go

if object_id('v1') is not null 
drop view v1;
if object_id('chglog') is not null
drop table chglog;
go


create table chglog (IdNumber int not null, UpdatedOn date not null, Status varchar(10) not null, UpdatedBy varchar(20) not null
constraint chg_unique unique (IdNumber, Status),
constraint chg_check check (Status in ('Open', 'Closed')) 
); 

insert chglog(IdNumber, UpdatedOn, Status, UpdatedBy) 
values (100001, '20190410', 'Open', 'domain/user'), (100001, '20190413', 'Closed', 'domain/user'), 
(9999, '20190401', 'Open', 'zork'),
(99001, '20190402', 'Open', 'bob'),
(99001, '20190402', 'Closed', 'alice')
;
go

-- setup complete, now create a view to do a hard-coded pivot
create view v1 as 
select IdNumber, 
max(case Status when 'Open' then UpdatedOn else null end) as 'Open', 
max(case Status when 'Closed' then UpdatedOn else null end) as 'Closed'  
from chglog
group by IdNumber;
go

-- test the view
select * from v1 
order by IdNumber;

-- now the query that you wanted to write/use 
Select
IdNumber, 
case when datediff(day, [Open], Closed) = 0 then N'SAMEDAY' else cast(datediff(day, [Open], Closed) as nvarchar(20)) end as TotalAge
--         datediff(day,Open,SentToCustomer) as Stage1,
--         datediff(day,SentToCustomer,) as Stage2,
from v1
order by IdNumber; 

我将指出您的“表”包含IdNumber,但您的上一个查询引用了QuoteNumber(以及您未提及的其他列)。我只是忽略了一些而猜测了一些。这只是基于硬编码值的旧式数据透视。只要您提前知道在进行数据透视时需要考虑的值,并且知道域不变(或不在乎其他值),这就是您要的。

您应该考虑的问题是,在创建此视图之后,是否应该关心通过CRM添加的其他状态值。但是无论如何,您还是有点迷上了第三方报告软件。只能使用表或视图作为数据源的报表工具似乎是原始的(至少可以说)。