Date 可能使用WHERE子句的多个extract()?

Date 可能使用WHERE子句的多个extract()?,date,Date,到目前为止,我已经得出以下结论: WHERE (extract(month FROM orders)) = (SELECT min(extract(month from orderdate)) FROM orders) 然而,这将导致许多行返回零,在我的情况下,许多行返回零,因为许多订单存在于同一最早(最小)月份,即2月4日、2月9日、2月15日 我知道WHERE子句可以包含多个列,那么为什么下面的语句不起作

到目前为止,我已经得出以下结论:

WHERE (extract(month FROM orders)) = 
                     (SELECT min(extract(month from orderdate))
                     FROM orders)
然而,这将导致许多行返回零,在我的情况下,许多行返回零,因为许多订单存在于同一最早(最小)月份,即2月4日、2月9日、2月15日

我知道
WHERE
子句可以包含多个列,那么为什么下面的语句不起作用呢

WHERE (extract(day FROM orderdate)), (extract(month FROM orderdate)) = 
                     (SELECT min(extract(day from orderdate)), min(extract(month FROM orderdate))
                     FROM orders)
我只得到:
SQL错误:ORA-00920:无效的关系运算符

任何帮助都会很好,谢谢

样本数据: 2012年2月2日 2012年2月14日 2012年12月22日 2013年2月9日 2013年7月18日 2014年1月1日

输出: 2012年2月2日 2012年2月14日

期望输出:
2012年2月2日

with cte1 as (
    select
        extract(month from OrderDate) date_month,
        extract(day from OrderDate) date_day,
        OrderNo
    from tablename
), cte2 as (
    select min(date_month) min_date_month, min(date_day) min_date_day
    from cte1
)
select cte1.*
from cte1
where (date_month, date_day) = (select min_date_month, min_date_day from cte2)
公共表表达式使您能够重新构造数据,然后使用此数据进行选择。第一个cte块(cte1)为每个表行选择月份和日期。Cte2然后选择min(月)和min(日期)。然后,最后一个选择组合两个CTE,从cte1中选择具有所需月份和日期的所有行


可能有一个较短的解决方案,但是我喜欢常用的表表达式,因为它们几乎总是比“最佳、最短”查询更容易理解。

我重新创建了您的表,发现您只是把括号弄乱了一点。以下是我的作品:

where
    (extract(day from OrderDate),extract(month from OrderDate))
    =
    (select
        min(extract(day from OrderDate)),
        min(extract(month from OrderDate))
     from orders
    )

如果这真的是您想要的,尽管看起来很奇怪,那么作为一种不同的方法,您可以忘记提取和对表的子查询以获得最小值,而改用分析方法:

select orderdate
from (
  select o.*,
    row_number() over (order by to_char(orderdate, 'MMDD')) as rn
  from orders o
)
where rn = 1;

ORDERDATE
---------
01-JAN-14 
row\u number()。
rn
值是唯一的,因此将有一行标记为1,这将从最早月份的最早一天开始。如果您在同一天/月有多个订单,比如2013年1月1日和2014年1月1日,那么您仍然只能得到一个
rn=1
,但选择哪一个是不确定的。您需要进一步添加
orderby条件以使其具有确定性,但我不知道您可能想要什么

这是在内部查询中完成的;然后外部查询进行过滤,以便只返回标有
rn=1
的记录;因此,从整个查询中只返回一行

这也避免了最早日数不在最早月数中的情况——例如,如果您只有2014年1月1日和2014年2月2日;分别比较日期和月份将查找2014年2月1日,这是不存在的

(托马斯·茨切尼奇(Thomas Tschernich)的安瓦尔(anwer)也加入其中,对该数据给出了相同的结果)


要根据发票表联接结果,不需要再次联接到orders表,特别是不需要交叉联接,因为交叉联接会扭曲结果。您可以(至少)通过两种方式进行连接:

SELECT 
    o.orderno,
        to_char(o.orderdate, 'DD-MM-YYYY'),
    i.invno
FROM 
  (
    SELECT o.*,
        row_number() over (order by to_char(orderdate, 'MMDD')) as rn
    FROM orders o
  ) o, invoices i
WHERE i.invno = o.invno
AND rn = 1;
或:

第一个看起来需要做更多的工作,但执行计划是相同的


使用pastebin提供的查询返回两行,这两行返回一行。

我不知道多个提取函数,我通常喜欢避免复杂、难以阅读的内容,并用易于理解的内容替换它,尽管它可能更容易编写。我补充了一点解释。如果您需要更多帮助,请提供完整的表结构,我会给您一个最终的查询。谢谢。我不知道你说的全桌结构是什么意思。i、 e.属性名称和指定的数据类型?我不确定还要添加什么,但它只是一个表(称为Orders),有两个属性。OrderNO、OrderDate,分别以数字和日期作为其数据类型。我怀疑您指的是实际的表格数据,但是如果您确实需要,请让我知道。我感谢托马斯的帮助。此外,如果可以的话,我不想使用cte,也许在将来某个时候。我编辑了答案以反映列名。我可以建议另外一种方法。您只需执行
month*100+day
并使用此“虚拟”列对行进行排序。单独获取min-day和month是不正确的。例如,如果您将1月10日和2月3日作为日期,您将得到1月3日作为结果,这显然是错误的。WHERE子句可以包含多个只对子查询有效的列,afaikI不理解您的描述中的要求,您可以发布一组小样本数据以及预期的输出吗?当然,很抱歉搞混了。在OP中添加。(对格式设置感到抱歉…不确定如何处理)不确定我是否仍然遵循。。。如果您与2014年1月1日发生冲突,那么您会在2012年2月2日之前选择该冲突吗?这真的是你想要的吗?我很难理解为什么你不想要最早的日期。@Restricted-cleaning注释很好,但是你已经删除了一个澄清了你的例子的注释;你能修正输出和期望输出,使其显示你想要2014年1月1日作为结果,否则答案就没有意义了吗?您还删除了所有上下文;描述一下你是如何得到这个答案的,对于将来发现这个问题的人来说仍然是有帮助的,特别是你有一些奇怪的规则,因为读到这篇文章的人会认为你仍然想要这一年。谢谢托马斯。但是,对于multiple extract(),我遇到了“未选择行”。我不知道为什么,看起来我不得不换一种方式……请看下面《吃桃子》的评论:“分别取min day和month是不正确的。例如,如果你将1月10日和2月3日作为日期,那么你将得到1月3日,这显然是错误的。”您必须首先选择最小月,然后选择本月的最小日,而不是总的最小月和最小日。但你要求的是不同的,对,我明白了。因此,必须合并多个子查询嵌套,这将使整个语句看起来非常复杂,不是吗?简单地说,我想要
SELECT 
    o.orderno,
        to_char(o.orderdate, 'DD-MM-YYYY'),
    i.invno
FROM 
  (
    SELECT orderno, orderdate, invno
    FROM
      (
        SELECT o.*,
            row_number() over (order by to_char(orderdate, 'MMDD')) as rn
        FROM orders o
      )
    WHERE rn = 1
  ) o, invoices i
WHERE i.invno = o.invno;