【问题标题】:Select either one of the row with condition选择任一有条件的行
【发布时间】:2012-09-11 17:58:52
【问题描述】:

我在SQL Fiddle中定义了这个sql表和行

SUPPLIER_DETAILS 表中有一个名为 IS_PAYABLE 的字段,其值为 null 或 'Y'。

如果是IS_PAYABLE='Y',则每个 PRODUCT_REG 可能有一个或多个记录,并且具有不同的 PRODUCT_NO。 例如。 PRODUCT_REG = 'HP_C20' 有两条记录为 IS_PAYABLE='Y'

HP_C20  FR-A    GB-A128     Y
HP_C20  FR-A    GB-A098     Y

我想要的是如果IS_PAYABLE='Y' 并且如果一个 PRODUCT_REG 有多个记录,那么我只想要其中一个记录,并且我想要所有带有 @987654327 的记录@。

我怎样才能做到这一点?如果我没有使我的要求易于理解,我会进一步解释。

任何帮助都是非常值得赞赏的。

谢谢

【问题讨论】:

    标签: sql database oracle oracle10g


    【解决方案1】:
    select * from 
       (select a.*, 
             row_number() over (partition by product_reg order by product_no) as rnk 
       from SUPPLIER_DETAILS a
       order by PRODUCT_REG)
    where is_payable is null or rnk = 1;
    

    SQLFIDDLE

    在内部查询中,我对具有相同 product_reg 的产品进行了排名。

    在外部查询中,每个 product_reg(排名第一)只有一个产品和所有非应付产品。

    【讨论】:

    • @FlorinGhita 非常感谢,这就像一个魅力。如果我在记录方面遇到任何问题,我会回复您。非常感谢。
    【解决方案2】:

    试试这个:

    SELECT s.* 
    FROM   supplier_details s 
    WHERE  NOT EXISTS(SELECT s1.* 
                      FROM   supplier_details s1 
                      WHERE  s.is_payable = 'Y' 
                             AND s1.is_payable = 'Y' 
                             AND s.product_reg = s1.product_reg 
                             AND s.product_no < s1.product_no) 
    UNION 
    SELECT * 
    FROM   supplier_details 
    WHERE  is_payable IS NULL 
    

    http://sqlfiddle.com/#!4/25c52/2/0

    编辑:下面的代码也应该可以工作(联合是多余的)

    SELECT s.* 
    FROM   supplier_details s 
    WHERE  NOT EXISTS(SELECT s1.* 
                      FROM   supplier_details s1 
                      WHERE  s.is_payable = 'Y' 
                             AND s1.is_payable = 'Y' 
                             AND s.product_reg = s1.product_reg 
                             AND s.product_no < s1.product_no) 
    

    http://sqlfiddle.com/#!4/5e69b/1/0

    【讨论】:

      【解决方案3】:

      在这种情况下row_number()解析功能会派上用场。

         select product_reg
              , product_supplier_code
              , product_no
              , is_payable
           from (select t.*
                      , row_number() over (partition by product_reg order by product_no) m
                   from SUPPLIER_DETAILS t
                )
          where m = 1
             or is_payable is null
          order by product_reg
      

      Demo#1

      另外

      似乎是重复的。为了在此处稍微区分答案,您可以使用另一种方法来获得所需的结果

      select product_reg
          , max(PRODUCT_SUPPLIER_CODE) KEEP (DENSE_RANK FIRST ORDER BY product_reg) PRODUCT_SUPPLIER_CODE
          , max(PRODUCT_NO) KEEP (DENSE_RANK FIRST ORDER BY product_reg) PRODUCT_NO
          , max(IS_PAYABLE) KEEP (DENSE_RANK FIRST ORDER BY product_reg) IS_PAYABLE
      from SUPPLIER_DETAILS t
      group by product_reg 
      order by product_reg
      

      Demo#2

      【讨论】:

        【解决方案4】:

        您可以为此使用UNION ALL,但在返回记录where IS_PAYABLE = 'Y' 时,使用聚合始终返回MAX()MIN()

        select PRODUCT_REG, PRODUCT_SUPPLIER_CODE, max(PRODUCT_NO) PRODUCT_NO, IS_PAYABLE
        from SUPPLIER_DETAILS
        where IS_PAYABLE = 'Y'
        group by  PRODUCT_REG, PRODUCT_SUPPLIER_CODE, IS_PAYABLE
        union all 
        select PRODUCT_REG, PRODUCT_SUPPLIER_CODE, PRODUCT_NO, IS_PAYABLE
        from SUPPLIER_DETAILS
        where IS_PAYABLE is null
        order by PRODUCT_REG
        

        SQL Fiddle with Demo

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-06-24
          • 1970-01-01
          • 1970-01-01
          • 2021-05-30
          相关资源
          最近更新 更多