Teradata:错误 3504 并在 Select 中生成列的子集

Teradata: Error 3504 and generating subset of column in Select

您好,我正在尝试解决一个 teradata sql 问题,我需要排除 2005 年 8 月的所有销售日期,并计算每个 store/month/year 组合的任何商店的每日收入超过 20 个销售日。

我的想法是在子查询中生成 saledate 列的子集并使用它。这是我的代码。

SELECT Sub.store, Sub.Year_, Sub.Month_, Sub.TotalSaleDate, Sub.Daily_rev, sub.Total_rev
FROM (SELECT (CASE WHEN (NOT (EXTRACT(MONTH from saledate)=8 
             AND EXTRACT(YEAR from saledate)=2005)) THEN saledate END) AS 
             NewSaleDate, COUNT(NewSaleDate) AS TotalSaleDate,
             SUM(amt) AS Total_rev,
             Total_rev/TotalSaleDate AS Daily_rev,
             EXTRACT(MONTH from NewSaleDate) AS Month_,
             EXTRACT(YEAR from NewSaleDate) AS Year_, store
       FROM trnsact
       WHERE stype = 'P' AND saledate = NewSaleDate
       GROUP BY store, Year_, Month_, NewSaleDate) AS Sub
WHERE Sub.TotalSaleDate >= 20
ORDER BY sub.TotalSaledate ASC; 

这是我的输出 My result

这是工作人员的代码

SELECT 
  sub.store, sub.year_num, sub.month_num, sub.num_dates, sub.daily_revenue
FROM (
  SELECT 
  store, 
  EXTRACT (month FROM saledate) AS month_num, 
  EXTRACT (year FROM saledate) AS year_num,
  COUNT (DISTINCT saledate) AS num_dates,
  SUM(amt) AS total_revenue,
  total_revenue/num_dates AS daily_revenue,
  (CASE 
  WHEN (year_num=2005 AND month_num=8) THEN 'cannot' ELSE 'can' 
  END) As can_use_anot
  FROM trnsact
  WHERE stype='p' AND can_use_anot='can'
  GROUP BY store, month_num, year_num
  ) AS sub
HAVING sub.num_dates >=20
GROUP BY sub.store, sub.year_num, sub.month_num, sub.num_dates, sub.daily_revenue
ORDER BY sub.num_dates ASC;

和他的结果 Correct result

显然他的每日收入比我高得多。我想知道是否是因为我没有在子查询中计算 Distinct saledate。但是,我尝试添加 use COUNT(DISTINCT saledate) 并且我根本没有输出,0 行。我理解他的代码是如何工作的,但我对我的代码哪里出了问题感到沮丧。 特别是为什么添加 DISTINCT 给了我 0 行,非常感谢任何可以解释的人...

Select #1 按日期聚合而 #2 按月聚合,只需比较返回的行数。

我不明白为什么这两个查询都使用这种奇怪的方式来排除 2005 年 8 月以来的日期。应该使用简单的 WHERE saledate not between date '2005-08-01' and date '2005-08-31'

而且不需要使用 Derived Table:

SELECT 
   store, 
   EXTRACT (month FROM saledate) AS month_num, 
   EXTRACT (year FROM saledate) AS year_num,
   COUNT (DISTINCT saledate) AS num_dates,
   SUM(amt) AS total_revenue,
   total_revenue/num_dates AS daily_revenue
FROM trnsact
WHERE saledate not between date '2005-08-01' and date '2005-08-31'
  and stype='p'
GROUP BY store, month_num, year_num
HAVING num_dates >=20
ORDER BY sub.num_dates ASC;

但是每个 day/month 可能有大量行,首先避免对所有行进行 EXTRACT 和 COUNT(DISTINCT):

按天聚合可能更有效
SELECT -- now aggregate by month
   store, 
   EXTRACT (month FROM saledate) AS month_num, 
   EXTRACT (year FROM saledate) AS year_num,
   COUNT (*) AS num_dates, -- no need for DISTINCT anymore
   SUM(daily_amt) AS total_revenue,
   total_revenue/num_dates AS daily_revenue
FROM
 (  -- daily sales first
    SELECT 
       store, 
       saledate, 
       SUM(amt) AS daily_amt
    FROM trnsact
    WHERE saledate not between date '2005-08-01' and date '2005-08-31'
      and stype='p'
    GROUP BY store, saledate
 ) as dt
GROUP BY store, year_num, month_num
;