【问题标题】:First record which meets GROUP BY and HAVING clauses第一条满足 GROUP BY 和 HAVING 子句的记录
【发布时间】:2016-06-29 14:00:38
【问题描述】:

我有一个 SQL Server 查询,它使用链接服务器连接从 Oracle 8i 服务器获取数据。我的问题完全是关于 Oracle SQL 的。

有一个 StyleSizes 表。一种样式可以有一个或多个与其相关的尺寸。我需要找到任何一张 Style_CD 有多个 Size_CD。这可以通过 GROUP BY 和 HAVING 来实现。但我只需要一种这样的风格。表的体积太大了,我等不及查询执行完成——所以我只需要一种样式。

Oracle 中应用 GROUP BY 和 HAVING 子句后如何快速只获取一条记录?

SELECT STYLE_CD
FROM OPENQUERY(LinkedORAServer,  
   'SELECT STYLE_CD
   FROM DA.StyleSize M  
   GROUP BY STYLE_CD
   HAVING COUNT(SIZE_CD) > 1
    ')  

进一步阅读

  1. Ask Tom - On ROWNUM and Limiting Results
  2. Limit - Comparison of different SQL implementations
  3. How do I limit the number of rows returned by an Oracle query after ordering?
  4. Row Limiting Clause for Top-N Queries in Oracle Database 12c Release 1 (12.1)
  5. SQL Server - Pagination with OFFSET / FETCH : A better way

【问题讨论】:

  • 你可以选择前 1 名吗?
  • @Veljko89 你的意思是 SQL Server 还是 Oracle 中的 TOP 1?在 SQL Server 中这样做是没有用的,因为它是一个 OPENQUERY。
  • 你想得到什么?一种样式有多种尺寸?

标签: sql oracle


【解决方案1】:

你应该使用类似于 MySQL 限制和 SQL-SERVER 顶部的 ROWNUM :

SELECT STYLE_CD
FROM OPENQUERY(LinkedORAServer,  
   'SELECT STYLE_CD FROM(SELECT STYLE_CD
                         FROM DA.StyleSize M  
                         GROUP BY STYLE_CD
                         HAVING COUNT(SIZE_CD) > 1)
    WHERE rownum = 1
    ') 

【讨论】:

    【解决方案2】:
    SELECT * FROM (SELECT SIZE_CD, COUNT(STYLE_CD) OVER (PARTITION BY STYLE_CD) CNT FROM STYLESIZE) WHERE CNT > 1
    

    【讨论】:

    • 我确定 Oracle 8i 没有分析功能。
    【解决方案3】:

    如果您想要一种样式具有多个尺寸,那么您可以使用exists

    select m.*
    from da.stylesize m
    where exists (select 1 from da.stylesize m2 where m2.style_cd = m.style_cd and m2.size_cd <> m.size_cd) and
          rownum = 1;
    

    然后,您要确保在da.stylesize(style_cd, size_cd) 上有一个索引。

    使用此查询,您甚至不需要进行聚合,这应该是一个很大的节省。

    【讨论】:

    • 谢谢,这行得通。但是在 SQL Server 中,我可以使用 GROUP BY 在查询中应用 TOP 1(并且它使用不同且高效的查询计划)。为什么 Oracle 不允许 GROUP BY 上的 TOP 1? [您的建议运行得足够快 - 但与 GROUP BY 方法相比,当涉及更多表时,它很难阅读]。
    • @Lijo 。 . . Oracle 不支持任何查询中的TOP
    • 同意 - 我已经知道了。我指的是这种方法。我认为whereTop 1 中的rownum = 1 在逻辑上是相同的。 SQL Server 与 TOP 1 和 GROUP BY 一起工作得很快 - 但 Oracle 与 GROUP BYrownum 一起工作得不快。是不是Oracle的缺点?
    • @Lijo 。 . .它们并不完全等同。 TOP ORDER BY 之后评估。 WHEREORDER BY 之前评估。
    • @Lijo 。 . . Oracle 12c 支持fetch 子句,它与TOP 等效(实际上更好,因为它还允许偏移)。
    【解决方案4】:
    SELECT STYLE_CD
    FROM OPENQUERY(LinkedORAServer,  
       'select VAL from (
    select VAL,COUNT(*) from SANDEEP24FEB2016_2 group by VAL having COUNT(*)>1 
    ) where rownum=1
        ') ;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-08-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-17
      相关资源
      最近更新 更多