5

このSQLテーブルとSQL Fiddleで定義された行があります

SUPPLIER_DETAILSテーブルには、NULL または「Y」のいずれかの値を持つ IS_PAYABLE というフィールドがあります

の場合、 PRODUCT_REGごとに異なる PRODUCT_NO を持つ1IS_PAYABLE='Y'つ以上のレコードが存在する可能性があります。たとえば、 の 2 つのレコードがあります。PRODUCT_REG = 'HP_C20'IS_PAYABLE='Y'

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

私が望むのは、1 つのPRODUCT_REGIS_PAYABLE='Y'に複数のレコードがある場合、レコードのいずれか 1 つだけが必要で、すべてのレコードが.IS_PAYABLE is null

どうすればこれを達成できますか?私の要件が理解できない場合は、さらに説明します。

どんな助けも非常に高く評価されます。

ありがとう

4

4 に答える 4

5
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(最初にランク付けされた)ごとに1つの製品と、すべての非支払い製品があります。

于 2012-09-19T12:25:03.213 に答える
3

これを試して:

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

于 2012-09-19T12:29:05.843 に答える
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

デモ#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

デモ#2

于 2012-09-19T12:30:03.083 に答える
2

これに使用できます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 を参照してください

于 2012-09-19T13:03:18.463 に答える