如何在不同条件下计算 SQL 中的不同值?

How to count distinct values in SQL under different conditions?

我有一个如下所示的数据。我想计算产品总数并创建一个 table 来总结不同日期范围的计数。请参见下图作为示例。这是我的码头:

SELECT( 
SELECT Count(DISTINCT Product) FROM Table1 WHERE  Date BETWEEN '01/01/2017 AND 
'01/15/2017,
SELECT Count(DISTINCT Product) FROM Table1 WHERE  Date BETWEEN '01/16/2017 AND 
'01/31/2017,    
);

但是我得到一个错误:

Incorrect syntax near ','

这会起作用

SELECT  
(SELECT Count(DISTINCT Product) FROM Table1 WHERE  Date BETWEEN '01/01/2017' AND 
'01/15/2017'),
(SELECT Count(DISTINCT Product) FROM Table1 WHERE  Date BETWEEN '01/16/2017' AND 
'01/31/2017')    
;

您的 SQL:

中存在一些语法错误
  • 使用 BETWEEN 语句时,只能用引号引起来 每个日期。不要在引号中包含 AND。
  • 您需要将每个内部 SELECTS 括起来。
  • 末尾(右括号前)多了一个逗号

但是,此查询不会 return 值 5 和 2,因为您在每个 SELECT 中都指定了 DISTINCT。这只会给你 3 和 2,因为 Product (A/D/E) returned 从第一个查询中只有 3 个不同的值。如果您想要行数,请删除不同的。

最后,我建议您在 SQL 中使用日期文字时使用 YYYY-MM-DD 语法。这消除了关于日期和月份的任何歧义。例如,1/4/2017 可能是 1 月 4 日或 4 月 1 日,具体取决于 SQL 服务器的配置方式。如果您指定 2017-04-01,那么这将始终被解释为 4 月 1 日,而 2017-01-04 将始终是 1 月 4 日。

简单:

    SELECT 
     (SELECT COUNT(DISTINCT Product) FROM yourtable T1 WHERE Date BETWEEN '01/01/2017' AND '01/15/2017') C1,
     (SELECT COUNT(DISTINCT Product) FROM yourtable T2 WHERE Date BETWEEN '01/16/2017' AND '01/31/201') C2

输出:3 | 2

SELECT 
 (SELECT COUNT(*) FROM yourtable T1 WHERE Date BETWEEN '01/01/2017' AND '01/15/2017') C1,
 (SELECT COUNT(*) FROM yourtable T2 WHERE Date BETWEEN '01/16/2017' AND '01/31/201') C2

输出:5 | 2

如果最后的代码不起作用,您需要使用 Convert and Cast:

Declare @tb table(product  varchar(50),[Date] date)
insert into @tb

select 'A' as Product, cast(substring(CONVERT(VARCHAR(10), cast('1/1/2017' as date),110),7,4) + '-' +
substring(CONVERT(VARCHAR(10), cast('1/1/2017' as date),110),1,2) + '-' +
substring(CONVERT(VARCHAR(10), cast('1/1/2017' as date),110),4,2) as date) as [Date] union all

select 'A' as Product, cast(substring(CONVERT(VARCHAR(10), cast('1/1/2017' as date),110),7,4) + '-' +
substring(CONVERT(VARCHAR(10), cast('1/1/2017' as date),110),1,2) + '-' +
substring(CONVERT(VARCHAR(10), cast('1/1/2017' as date),110),4,2)as date) as [Date] union all

select 'D' as Product, cast(substring(CONVERT(VARCHAR(10), cast('1/5/2017' as date),110),7,4) + '-' +
substring(CONVERT(VARCHAR(10), cast('1/5/2017' as date),110),1,2) + '-' +
substring(CONVERT(VARCHAR(10), cast('1/5/2017' as date),110),4,2) as date) as [Date] union all

select 'E' as Product, cast(substring(CONVERT(VARCHAR(10), cast('1/6/2017' as date),110),7,4) + '-' +
substring(CONVERT(VARCHAR(10), cast('1/6/2017' as date),110),1,2) + '-' +
substring(CONVERT(VARCHAR(10), cast('1/6/2017' as date),110),4,2)as date) as [Date] union all


select 'E' as Product, cast(substring(CONVERT(VARCHAR(10), cast('1/10/2017' as date),110),7,4) + '-' +
substring(CONVERT(VARCHAR(10), cast('1/10/2017' as date),110),1,2) + '-' +
substring(CONVERT(VARCHAR(10), cast('1/10/2017' as date),110),4,2)as date) as [Date] union all


select 'D' as Product, cast(substring(CONVERT(VARCHAR(10), cast('1/25/2017' as date),110),7,4) + '-' +
substring(CONVERT(VARCHAR(10), cast('1/25/2017' as date),110),1,2) + '-' +
substring(CONVERT(VARCHAR(10), cast('1/25/2017' as date),110),4,2)as date) as [Date] union all


select 'A' as Product, cast(substring(CONVERT(VARCHAR(10), cast('1/30/2017' as date),110),7,4) + '-' +
substring(CONVERT(VARCHAR(10), cast('1/30/2017' as date),110),1,2) + '-' +
substring(CONVERT(VARCHAR(10), cast('1/30/2017' as date),110),4,2)as date) as [Date]

--Copy from here
select acnt as 'Count(01/01/2017-01/15/2017)',bcnt as 'Count(01/16/2017-01/31/2017)' from
(select count(1)   as acnt from @tb where [Date] BETWEEN '01/01/2017' AND '01/15/2017') as a
left join
(select count(1)   as bcnt from @tb where [Date]  BETWEEN '01/16/2017' AND '01/31/2017') as b
On a.acnt != b.bcnt or a.acnt = b.bcnt
;WITH CTE(Product ,[Date])
As
(
SELECT 'A','1/1/2017'  Union all
SELECT 'A','1/1/2017'  Union all
SELECT 'D','1/5/2017'  Union all
SELECT 'E','1/6/2017'  Union all
SELECT 'E','1/10/2017' Union all
SELECT 'D','1/25/2017' Union all
SELECT 'A','1/30/2017'
)
SELECT SUM([Count Of between '1/1/2017' AND '1/15/2017']) AS [Count Of between (1/1/2017 AND 1/15/2017)]
    ,SUM([Count Of between '1/16/2017' AND '1/31/2017']) AS [Count Of between (1/16/2017     AND 1/31/2017)]
FROM (
    SELECT COUNT(Product) OVER (
            PARTITION BY [Date] ORDER BY Product
            ) AS [Count Of between '1/1/2017' AND '1/15/2017']
        ,ISNULL(NULL, '') AS [Count Of between '1/16/2017' AND '1/31/2017']
    FROM cte
    WHERE [Date] BETWEEN '1/1/2017'
            AND '1/15/2017'

    UNION ALL

    SELECT ISNULL(NULL, '')
        ,COUNT(Product) OVER (
            PARTITION BY [Date] ORDER BY Product
            ) AS [Count Of between '1/16/2017' AND '1/31/2017']
    FROM cte
    WHERE [Date] BETWEEN '1/16/2017'
            AND '1/31/2017'
    ) Dt

输出

  Count Of between (1/1/2017 AND 1/15/2017) |   Count Of between (1/16/2017  AND 1/31/2017)
--------------------------------------------------------------------------------
    5                                             2