没有空值的tsql UNION

时间:2013-07-20 00:25:54

标签: sql-server tsql union union-all

我有以下查询

SELECT MONTH, COUNT(DISTINCT VISITS) AS BRAND_VISITS, NULL AS NONB_VISITS
FROM Table1
WHERE KEYWORD_TYPE = BRAND(
AND DATE >= '2013-01-01'
GROUP BY MONTH

UNION ALL

SELECT MONTH, NULL, COUNT(DISTINCT VISITS) AS NONB_VSTS 
FROM Table1
WHERE KEYWORD_TYPE = NON-BRAND
AND DATE >= '2013-01-01'
GROUP BY MONTH

我得到以下结果:

1   352540  NULL
2   309834  NULL
3   228764  NULL
4   236054  NULL
5   218096  NULL
6   172527  NULL
1   NULL    5337
2   NULL    14120
3   NULL    9954
4   NULL    23755
5   NULL    19771
6   NULL    30797

但是,我想要的是没有NULLS的内联结果

1   352540  5337
2   309834  14120
3   228764  9954
4   236054  23755
5   218096  19771
6   172527  30797

2 个答案:

答案 0 :(得分:0)

您可以使用带CASE的单个语句或月份的JOIN而不是UNION来执行此操作。如果采用连接方法,则可能需要考虑空值(一个月内没有关键字的访问者)。您需要对它们进行分析,以查看哪种数据和表结构更快。它实际上是关于索引和需要聚合的数据量。

假设您不必担心基于示例中的计数的空值,这就是您想要的。

SELECT brand.month, brand.brand_visits,nonbrand.non_brand_visits
FROM (SELECT month, COUNT(visits) AS brand_visits
      FROM Table1
      WHERE keyword_type = 'BRAND'
      AND date >= '2013-01-01'
      GROUP BY month) brand
INNER JOIN
      (SELECT month, COUNT(visits) AS non_brand_visits 
       FROM Table1
       WHERE keyword_type = 'NON-BRAND'
       AND date >= '2013-01-01'
       GROUP BY month) nonbrand 
ON brand.month=nonbrand.month

以下是CASE方法。您应该根据您正在聚合的实际数据和索引进行分析,以查看哪种方法更快。

SELECT month, 
SUM(CASE WHEN keyword_type = 'BRAND' THEN 1 ELSE 0 END) AS brand_visits, 
SUM(CASE WHEN keyword_type = 'NON-BRAND' THEN 1 ELSE 0 END) AS non_brand_visits 
FROM Table1
WHERE date >= '2013-01-01'
GROUP BY month

最后,您没有提供表格结构或示例数据,因此我做了一些假设。我坚信您在原始陈述中不需要COUNT(DISTINCT。我已删除它并验证上面的两个声明产生相同的结果。如果需要COUNT(DISTINCT,那么CASE方法将无效,但加入方法仍然可以正常工作。

答案 1 :(得分:0)

使用您的专栏:

SELECT month, 
count(distinct CASE WHEN keyword_type = 'BRAND' THEN visits END) AS BRAND_VISITS, 
count(distinct CASE WHEN keyword_type = 'NON-BRAND' THEN visits END) AS NONB_VSTS  
FROM Table1
WHERE date >= '2013-01-01'
and keyword_type in ('BRAND','NON-BRAND')
GROUP BY month

我很想相信这个月只是日期栏的月份,我更倾向于这个解决方案,它涵盖的时间超过1年,同样的查询在2014年仍然有效

SELECT cast(dateadd(month, datediff(month, 0, date), 0) as date) month, 
count(distinct CASE WHEN keyword_type = 'BRAND' THEN visits END) AS BRAND_VISITS, 
count(distinct CASE WHEN keyword_type = 'NON-BRAND' THEN visits END) AS NONB_VSTS 
FROM Table1
WHERE date >= '2013-01-01'
and keyword_type in ('BRAND','NON-BRAND')
GROUP BY datediff(month, 0, date)

如果您想坚持使用旧脚本,可以这样修复:

SELECT MONTH, max(BRAND_VISITS) BRAND_VISITS, max(NONB_VISITS) NONB_VISITS 
FROM
(
SELECT MONTH, COUNT(DISTINCT VISITS) AS BRAND_VISITS, NULL AS NONB_VISITS
FROM Table1
WHERE KEYWORD_TYPE = 'BRAND'
AND DATE >= '2013-01-01'
GROUP BY MONTH
UNION ALL
SELECT MONTH, NULL, COUNT(DISTINCT VISITS) AS NONB_VSTS 
FROM Table1
WHERE KEYWORD_TYPE = 'NON-BRAND'
AND DATE >= '2013-01-01'
GROUP BY MONTH
) a
GROUP BY MONTH