【问题标题】:Refer to a Derived Table in a SELECT Subquery在 SELECT 子查询中引用派生表
【发布时间】:2016-08-05 06:53:48
【问题描述】:

在下面的代码中,产生的错误是“object t 不存在”。 T 是 FROM 中定义的派生表。我不想在 SELECT 子查询中重新过滤,而是想使用派生表来节省处理时间。由于FROM是按操作顺序先处理的,我觉得应该有办法让我在SELECT中引用“t”。

(我在 Teradata 以防万一)

SELECT (100000/(SELECT COUNT(DISTINCT EXTRACT(DAY FROM t.saledate))
        FROM t
        WHERE EXTRACT(MONTH FROM t.saledate) = 11)) as "NOVEMBER"
FROM (SELECT sprice, quantity, sku, store, saledate
        FROM trnsact
        WHERE (saledate BETWEEN '2004-11-01' AND '2004-12-31')
            ) as t

【问题讨论】:

  • 请用您正在使用的数据库标记您的问题。

标签: sql teradata scratchpad


【解决方案1】:

我们可以使用内联视图或公用表表达式来实现结果(看起来就像您想要的那样)。作为使用内联视图的示例:

SELECT ( 100000
       / COUNT(DISTINCT
           CASE WHEN EXTRACT(MONTH FROM t.saledate) = 11 
                THEN EXTRACT(DAY FROM t.saledate)
                ELSE NULL
           END
         )
       ) AS "NOVEMBER"
FROM ( SELECT r.sprice
            , r.quantity
            , r.sku
            , r.store
            , r.saledate
         FROM trnsact r
        WHERE r.saledate BETWEEN '2004-11-01' AND '2004-12-31'
     ) t

我还想避免任何潜在的“除以零”错误,因此我将 COUNT() 表达式包装在 NULLIFZERO 函数中。


我们会注意到,对于该结果集,我们实际上不需要内联视图或 CTE。可以通过更简单的查询来实现:

SELECT ( 100000
       / NULLIFZERO(COUNT(DISTINCT EXTRACT(DAY FROM t.saledate)))
       ) AS "NOVEMBER"
  FROM trnsact t
 WHERE t.saledate >= '2004-11-01'
   AND t.saledate <  '2004-12-01'

【讨论】:

  • 谢谢!那个最好的例子有很大帮助。我很好奇为什么我需要 NULLIFZERO (你是对的,除以零错误确实发生在我身上) - 只有当 COUNT(聚合中)结果为零时才会出现问题?但既然实际计数不为零,为什么我会看到问题?
  • SELECT 列表中的表达式正在执行一个不稳定的除法运算。如果 trnsact 表中有 saledate 在 12 月的行,但没有在 11 月,则示例查询中的 COUNT() 表达式将返回 0。查询有点奇怪。内联视图(派生表)查询中的谓词指定销售日期为 11 月和 12 月。外部查询中的 CASE 表达式仅在 11 月的 saledate 中返回非 NULL 值,这使得 COUNT() 聚合返回 0 成为可能。(当被计数的表达式计算为 NULL 时,COUNT 不会增加。 )
【解决方案2】:

如果您使用的是 SQL Server,您会这样做:

;WITH t as
SELECT sprice, quantity, sku, store, saledate
        FROM trnsact
        WHERE (saledate BETWEEN '2004-11-01' AND '2004-12-31')
SELECT (100000/(SELECT COUNT(DISTINCT EXTRACT(DAY FROM t.saledate))
        FROM t
        WHERE EXTRACT(MONTH FROM t.saledate) = 11)) as "NOVEMBER"

我认为可以对查询进行更多改进,但这是一个好的开始。

【讨论】:

  • 感谢您的评论和格式。我实际上需要将“t”作为表格,因为我将派生结果加入到其他事物中(删除了所有额外的代码来关注这个问题)。我现在正在阅读“WITH”以了解这是否适合我。
猜你喜欢
  • 2017-03-05
  • 1970-01-01
  • 2017-03-29
  • 2011-07-16
  • 2021-11-03
  • 2018-01-10
  • 2012-08-06
  • 1970-01-01
相关资源
最近更新 更多