避免在datediff中使用for列的group by?

时间:2019-03-30 16:30:37

标签: sql sql-server

由于当前正在构建数据库,因此我只能在datediff函数中使用某个表的Date Field,该datediff函数也是计数聚合的一部分(不是date字段,但该实体中的date字段不为null最终,by by会弄乱计数,因为一个条目是按自己的/作为自己的组来计数的。

详细说明: 我们的主要招聘人员想要一份能够显示申请总数的报告,并在每次开业时进行面试。到目前为止没有问题。此外,他喜欢查看每个职位空缺的总时间,从公开发布到每个职位新雇员的签到,只有在职位空缺已被填补的情况下,才有原因。 我有4张桌子要加入:  表1保存开场数据  表2具有单个应用程序  表3列出了申请的面试数据  表4包含有关公开发布的数据(以公开公开某个公开发布的日期为准)

问题是持续时间要求。表4是起点,表2中有一个(或没有一个)申请人每次开放都有一个日期字段,该字段填充了他返回已签署合同的时间,因此,开放的数量已填满。当我在datediff中使用该字段时,我也被迫将该列放入group by子句中,并且每次打开导致2行。第一行有所有想要的数字,第二行中总是有一个在该日期字段中有条目的人...

到目前为止,除了向同事解释说他在另一份报告中得到了自己的空缺时间号码外,我还没有想过一种避免该问题的方法。

SELECT
table1.col1 as NameOfProject,
table1.col2 as Company,
table1.col3 as OpeningType,
table1.col4 as ReasonForOpening,
count (table2.col2) as NumberOfApplications,
sum (case when table2.colSTATUS = 'withdrawn' then 1 else 0 end) as   mberOfApplicantsWhoWithdraw,
sum (case when table3.colTypeInterview = 'PhoneInterview' then 1 else 0 end) as NumberOfPhoneInterview,

...更多求和列...,

table1.finished,   // shows „1“ if opening is occupied
DATEDIFF(day, table4.colValidFrom,  **table2.colContractReceived**) as DaysToCompletion

FROM
table2 left join table3 on table2.REF_NR = table3.REF_NR
join table1 on table2.PROJEKT = table1.KBEZ
left join table4 on table1.REFNR = table4.PRJ_REFNR

GROUP BY
**table2.colContractReceived**

以及除汇总(求和和计数)功能中的列以外的所有其他列都在GROUP BY部分中

ORDER BY table1.NameOfProject

这里是对外观的简短重建。首先是没有填充开口的行,并且所有聚合根据需要排成一行。下一个项目/开头显示为double,因为datediff中使用的字段是独立分组的。

project     company;    no_of_applications; no_of_phoneinterview;   no_of_personalinterview;    ... ;   time_to_fill_in_days;   filled?
2018_312    comp a      27                  4                       2                                   null                    0
2018_313    comp b      54                  7                       4                                   null                    0
2018_313    comp b      1                   1                       1                                   42                      1

我很高兴知道如何解决这个问题。感谢您考虑我的要求!

(在“翻译”所有特定列和表名的过程中,我可能会在此处和那里出现语法错误,但是对于每个填充的空缺不必要的额外聚合,查询效果很好)

1 个答案:

答案 0 :(得分:0)

如果我正确理解了您的要求,我认为您遇到的问题是,您需要显示起点和申请人对职位的回应时间之间的日期,但是,此日期只能显示一个根据是否已填补该职位(如果该职位已填补,则显示该行,否则,则显示该行)。

我已经通过假设您使用“已收缩合同”列计算了一个已填补的头寸来实现此结果。这可能是错误的,但是原理仍然可以满足您的需求。

我基本上已经将您的查询包装到一个子查询中,通过Contractsfilled列进行降序并按项目进行分区,从而进行排名。然后在外部查询中,我对该排名的第一个实例进行过滤。

即使我对列结构和数据类型的假设是错误的,这也应该为您提供一个可以使用的模型。

此排名解决方案可能唯一的问题是,如果您想汇总一个项目中的两行(因此,请为每个项目的职位空缺和职位空缺的行都包括所有汇总列)。如果是这种情况,请告诉我,我们可以解决此问题。

如有任何疑问,请告诉我。

declare @table1 table (
    REFNR int,
    NameOfProject nvarchar(20),
    Company nvarchar(20),
    OpeningType nvarchar(20),
    ReasonForOpening nvarchar(20),
    KBEZ int
);

declare @table2 table (
    NumberOfApplications int,
    Status nvarchar(15),
    REF_NR int,
    ReturnedApplicationDate datetime,
    ContractsReceived bit,
    PROJEKT int
);

declare @table3 table (
    TypeInterview nvarchar(25),
    REF_NR int
);

declare @table4 table (
    PRJ_REFNR int,
    StartingPoint datetime
);

insert into @table1 (REFNR, NameOfProject, Company, OpeningType, ReasonForOpening, KBEZ)
values (1, '2018_312',    'comp a' ,'Permanent', 'Business growth', 1),
       (2, '2018_313',    'comp a', 'Permanent', 'Business growth', 2),
       (3, '2018_313',    'comp a', 'Permanent', 'Business growth', 3);

insert into @table2 (NumberOfApplications, Status, REF_NR, ReturnedApplicationDate, ContractsReceived, PROJEKT)
values (27, 'Processed', 4, '2018-04-01 08:00', 0, 1),
       (54, 'Withdrawn', 5, '2018-04-02 10:12', 0, 2),
       (1, 'Processed', 6, '2018-04-15 15:00', 1, 3);

insert into @table3 (TypeInterview, REF_NR)
values ('Phone', 4),
       ('Phone', 5),
       ('Personal', 6);

insert into @table4 (PRJ_REFNR, StartingPoint)
values (1, '2018-02-25 08:00'),
       (2, '2018-03-04 15:00'),
       (3, '2018-03-04 15:00');



       select * from
       (
       SELECT
        RANK()OVER(Partition by NameOfProject, Company order by ContractsReceived desc) as rowno,
        table1. NameOfProject,
        table1.Company,
        table1.OpeningType,
        table1.ReasonForOpening,
        case when ContractsReceived >0 then datediff(DAY, StartingPoint, ReturnedApplicationDate) else null end as TimeToFillInDays,
        ContractsReceived Filled 


        FROM
        @table2 table2 left join @table3 table3 on table2.REF_NR = table3.REF_NR
        join @table1 table1 on table2.PROJEKT = table1.KBEZ
        left join @table4 table4 on table1.REFNR = table4.PRJ_REFNR

        group by NameOfProject, Company, OpeningType, ReasonForOpening, ContractsReceived, 
        StartingPoint, ReturnedApplicationDate
        ) x where rowno=1