T-SQL Query用于计算表中不同条件的出现次数

时间:2014-07-11 12:15:27

标签: sql sql-server sql-server-2008 tsql

DBMS:SQL Server 2008

我有一个包含以下结构的表格,表示不同公司的特定供应商的投标申请及其申请状态。决定R =拒绝,A =接受。

---------------------------------------------------------------
| ID | Company    | ApplicationDate | Decision | DecisionDate |
---------------------------------------------------------------
| 1  | ABC        | 15/03/2011      | A        | 17/04/2011   |
| 2  | ABC        | 23/05/2012      | R        | 01/03/2014   |
| 3  | XYZ        | 14/07/2012      | R        | 20/07/2012   |
| 4  | ABC        | 18/01/2013      | A        | 24/02/2013   |
| 5  | XYZ        | 12/08/2013      | R        | 11/09/2013   |
| 6  | ABC        | 30/09/2013      | R        | 14/10/2013   |
| 7  | ABC        | 08/01/2014      | A        | 08/06/2014   |
| 8  | ABC        | 10/05/2014      | A        | 19/05/2014   |
---------------------------------------------------------------

*日期采用时间戳格式。示例表中的日期(dd / mm / yyyy)仅用于表示。

我需要从这个简单的数据库中挖掘出来,

  1. 过去12个月内的投标数量 - 假设2014年7月11日为当前日期。
  2. 过去12个月内被拒绝的投标数量。
  3. 自上次投标申请以来的数月内的时间。
  4. 自上次投标拒绝以来的几个月的时间。
  5. 过去12个月在ABC中使用的投标数量。
  6. 过去12个月ABC拒绝的投标数量。
  7. 自上次向ABC提交投标书以来的几个月。
  8. 自ABC上次拒绝投票以来的几个月。
  9. 因此,基于给定的表数据,统计信息将是

    1. 四个。 (身份证号码5,6,7和8的申请日期为今天的12个月)
    2. 三个(ID 2,5和6的决定日期为12个月,决定为R)
    3. 两个(2014年10月10日至今)
    4. 四(ID 2被拒绝于2014年1月3日)
    5. 三(ID 6,7和8)
    6. 两个(ID 2和6)
    7. 两个(2014年10月10日至今)
    8. 四(ID 2被拒绝于2014年1月3日)
    9. 有没有办法在表格上使用单个查询来获取这些统计信息(可能使用Sum with case)?

      到目前为止我的内容如下:

      SELECT
        SUM(CASE WHEN DATEDIFF(MM, ApplicationDate, GETDATE()) <= 12 THEN 1 ELSE 0 END) 'Total Tenders',
        SUM(CASE WHEN DATEDIFF(MM, DecisionDate, GETDATE()) <= 12 AND DECISION = R THEN 1 ELSE 0 END) 'Total Rejects'
        SUM(CASE WHEN DATEDIFF(MM, ApplicationDate, GETDATE()) <= 12 AND Company = 'ABC' THEN 1 ELSE 0 END) 'Total Tenders To ABC',
        SUM(CASE WHEN DATEDIFF(MM, DecisionDate, GETDATE()) <= 12 AND DECISION = R AND Company = 'ABC' THEN 1 ELSE 0 END) 'Total Rejects By ABC'
      FROM TenderTable;
      

      这给了我1,2,5和6所需的统计数据。

2 个答案:

答案 0 :(得分:1)

您可以使用WITH ROLLUP

SET DATEFORMAT 'dmy'

DECLARE @tbl TABLE (ID INT, Company VARCHAR(3), ApplicationDate DATE, Decision CHAR(1), DecisionDate DATE)

INSERT INTO @tbl 
    (ID, Company, ApplicationDate, Decision, DecisionDate)
VALUES
    (1,'ABC','15/03/2011','A','17/04/2011'),
    (2,'ABC','23/05/2012','R','01/03/2014'),
    (3,'XYZ','14/07/2012','R','20/07/2012'),
    (4,'ABC','18/01/2013','A','24/02/2013'),
    (5,'XYZ','12/08/2013','R','11/09/2013'),
    (6,'ABC','30/09/2013','R','14/10/2013'),
    (7,'ABC','08/01/2014','A','08/06/2014'),
    (8,'ABC','10/05/2014','A','19/05/2014')

SELECT
    Company                          = CASE WHEN (GROUPING(Company) = 1) THEN 'ALL' ELSE ISNULL(Company, 'UNKNOWN') END,
    TendersApplied                   = SUM(CASE WHEN ApplicationDate >= DATEADD(M, -12, CAST(GETDATE() AS DATE)) THEN 1 END),
    TendersRejected                  = SUM(CASE WHEN DecisionDate >= DATEADD(M, -12, CAST(GETDATE() AS DATE)) AND Decision = 'R' THEN 1 END),
    MonthsSinceLastTenderApplication = DATEDIFF(M, MAX(ApplicationDate), GETDATE()),
    MonthsSinceLastTenderRejection   = DATEDIFF(M, MAX(CASE WHEN Decision = 'R' THEN DecisionDate END), GETDATE())
FROM @tbl
GROUP BY Company
WITH ROLLUP
HAVING GROUPING(Company) = 1
OR Company = 'ABC'
ORDER BY GROUPING(Company), Company

哪个产生

Company TendersApplied TendersRejected MonthsSinceLastTenderApplication MonthsSinceLastTenderRejection
------- -------------- --------------- -------------------------------- ------------------------------
ABC     3              2               2                                4
ALL     4              3               2                                4

发问者编辑: 对上述查询的修改满足要求。

SELECT
    TendersApplied                      = SUM(CASE WHEN ApplicationDate >= DATEADD(M, -12, CAST(GETDATE() AS DATE)) THEN 1 END),
    TendersRejected                     = SUM(CASE WHEN DecisionDate >= DATEADD(M, -12, CAST(GETDATE() AS DATE)) AND Decision = 'R' THEN 1 END),
    MonthsSinceLastTenderApplication    = DATEDIFF(M, MAX(ApplicationDate), GETDATE()),
    MonthsSinceLastTenderRejection      = DATEDIFF(M, MAX(CASE WHEN Decision = 'R' THEN DecisionDate END), GETDATE()),
    TendersAppliedABC                   = SUM(CASE WHEN Company = 'ABC' AND ApplicationDate >= DATEADD(M, -12, CAST(GETDATE() AS DATE)) THEN 1 END),
    TendersRejectedABC                  = SUM(CASE WHEN Company = 'ABC' AND DecisionDate >= DATEADD(M, -12, CAST(GETDATE() AS DATE)) AND Decision = 'R' THEN 1 END),
    MonthsSinceLastTenderApplicationABC = DATEDIFF(M, MAX(CASE WHEN Company = 'ABC' THEN ApplicationDate END), GETDATE()),
    MonthsSinceLastTenderRejectionABC   = DATEDIFF(M, MAX(CASE WHEN Company = 'ABC' AND Decision = 'R' THEN DecisionDate END), GETDATE())
FROM @tbl

答案 1 :(得分:0)

如果你以前没见过,你可能会忽略一个不明显的简单方法。

例如,我有一个名为StateCounty的表,其中包含State和County数据

select count(*) as TotalCounties
, (select count(*) from StateCounty where StateCode = 'AK') as AlaskaCounties
, (select count(*) from StateCounty where StateCode = 'TX') as TexasCounties
, (select count(*) from StateCounty where County = 'Marion') as CountiesNamedMarion
, (select count(*) from StateCounty where County = 'Washington') as CountiesNamedWashington
from StateCounty

产生输出

TotalCounties AlaskaCounties TexasCounties CountiesNamedMarion CountiesNamedWashington
------------- -------------- ------------- ------------------- -----------------------
3131          17             254           17                  31

(1行受影响)

我相信你现在可以自己编写查询。