【问题标题】:tsql UNION without nullstsql UNION 没有空值
【发布时间】:2013-07-20 00:25:54
【问题描述】:

我有以下问题

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

【问题讨论】:

  • 看起来您需要的是 JOIN,而不是 UNION。
  • @RobertHarvey 我不同意,在这里可以很容易地使用 union,join 可能会导致计数为 0 的月份出现一些问题,尽管在此示例中不太可能发生

标签: sql-server tsql union union-all


【解决方案1】:

您可以使用带有 CASE 或 JOIN on month 的单个语句而不是 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 方法将不起作用,但 join 方法仍然可以正常工作。

【讨论】:

    【解决方案2】:

    使用您的列:

    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
    

    【讨论】:

      猜你喜欢
      • 2012-09-16
      • 1970-01-01
      • 2021-10-10
      • 1970-01-01
      • 1970-01-01
      • 2014-10-07
      • 2012-06-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多