3

次のテーブルと行がSQLFiddleで定義されています

start_date2 つの行の 差が 1 である製品テーブルから行を選択する必要がありnvl(return_date,end_date)ます。つまりstart_date、現在の行とnvl(return_date,end_date)前の行は 1 である必要があります

例えば

PRODUCT_NO TSH098PRODUCT_REG_NO FLDG2012 年 8 月 15 日で、 と は2012 年END_DATE8月 16日なので、違いは 1 日だけです。PRODUCT_NO TSH128PRODUCT_REG_NO FLDG start_date

SQLを使用して目的の出力を取得するにはどうすればよいですか.

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

ありがとう

4

5 に答える 5

2

製品の登録に一致するものがない場合は、一致する日付を1日だけ変更する必要があるという印象を受けています。だから私はそれを単に結合し、これがあなたが望むものだと思います

select p1.product_reg_no,
       p1.product_no product_no_1,
       p2.product_no product_no_2,
       p1.start_date start_date_1,
       nvl(p2.return_date,p2.end_date) return_or_end_date_2
  from products p1
  join products p2 on (p1.product_reg_no = p2.product_reg_no)
where  p1.start_date-1 = nvl(p2.return_date,p2.end_date)

SQLフィドル

グループ化が間違っていた場合は、結合条件をそのままにして、指定された例の製品テーブルで同じ結果が得られるようにします。

select p1.product_reg_no,
       p1.product_no product_no_1,
       p2.product_no product_no_2,
       p1.start_date start_date_1,
       nvl(p2.return_date,p2.end_date) return_or_end_date_2
  from products p1, products p2
where  p1.start_date-1 = nvl(p2.return_date,p2.end_date)

SQLフィドル2

今、あなたは違いが1日であると言います。start_dateはnvl(return_date、end_date)より1日高いと自動的に想定しました。また、日付は常に真夜中だと思いました。しかし、それらもすべて除外するには、truncを使用して、双方向に進むことができます。

select p1.product_reg_no,
       p1.product_no product_no_1,
       p2.product_no product_no_2,
       p1.start_date start_date_1,
       nvl(p2.return_date,p2.end_date) return_or_end_date_2
  from products p1, products p2
where  trunc(p1.start_date)-1 = trunc(nvl(p2.return_date,p2.end_date))
    or trunc(p1.start_date)+1 = trunc(nvl(p2.return_date,p2.end_date))

SQLフィドル3

日付(タイムスタンプではない)は加算と減算によって計算できるため、これはすべて機能します。

編集:あなたのコメントに続いて、return_date orend_dateを比較し、同じ日付も必要です:

select p1.product_reg_no,
       p1.product_no product_no_1,
       p2.product_no product_no_2,
       p1.start_date start_date_1,
       p2.return_date return_date_2,
       p2.end_date end_date_2
  from products p1, products p2
where  trunc(p1.start_date)   = trunc(p2.return_date)
    or trunc(p1.start_date)-1 = trunc(p2.return_date)
    or trunc(p1.start_date)+1 = trunc(p2.return_date)
    or trunc(p1.start_date)   = trunc(p2.end_date)
    or trunc(p1.start_date)-1 = trunc(p2.end_date)
    or trunc(p1.start_date)+1 = trunc(p2.end_date)

SQLフィドル4

于 2012-09-16T11:43:02.383 に答える
2

SQL ではdate + X、日付に X 日を追加します。だからあなたはできる:

select  * 
from    products
where   start_date + 1 = nvl(end_date, return_date)

日付に時刻の部分が含まれる可能性がある場合は、次を使用truncして時刻の部分を削除します。

select  * 
from    products
where   trunc(start_date) + 1 = trunc(nvl(end_date, return_date))

SQL Fiddle での実例。

于 2012-09-16T08:27:48.837 に答える
2

現在の行を前の行と比較する方法は、LAG() 関数を使用することです。このようなもの:

select * from 
(
select p.* 
       , lag (end_date) over 
         (order by start_date )
         as prev_end_date
       , lag (return_date) over 
         (order by start_date )
         as prev_return_date
from products p
)
where (trunc(start_date) - 1) = trunc(nvl(prev_return_date, prev_end_date))
order by 2,1 desc

ただし、ソート順を定義するメカニズムが定義されていないため、これは希望する結果を返しません。また、ソート順がなければ、「前の行」の概念は無意味です。

ただし、できることは次のとおりです。

select p1.* 
       , p2.*
from products p1 cross join products p2
where (trunc(p2.start_date) - 1) = trunc(nvl(p1.return_date, p1.end_date))
order by 2, 1 desc

この SQL は、日付に基づいてフィルタリングして、テーブルを 2 回クエリします。結果セットの各行には、各テーブルのレコードが含まれています。特定の start_date が複数の end_date と一致する場合、またはその逆の場合、複数のヒットのレコードが取得されます。

于 2012-09-16T10:43:21.490 に答える
2

分析関数を使用lagして、現在の位置より前の特定の物理オフセットにある行にアクセスできます。並べ替え順によると、次のようになります (それほどエレガントではありません)。

select *
  from products p
  join (select *
         from(select p.Product_no
                   , p.Product_Reg_No
                   , case 
                       when (lag(start_date, 1, start_date) over(order by product_reg_no)-
                            nvl(return_date, end_date)) = 1 
                            then lag(start_date, 1, start_date) 
                                   over(order by product_reg_no) 
                        end start_date
                   , End_Date
                   , Return_Date
               from products p 
              order by 2,1 desc
              )
        where start_date is not null
       ) s
    on (p.start_date = s.start_date or p.end_date = s.end_date)
 order by 2, 1 desc

SQL フィドルのデモ

于 2012-09-16T10:23:47.180 に答える
2

こんな感じですか?

SELECT T2.*
FROM PRODUCTS T1
    JOIN PRODUCTS T2 ON (
        nvl(T1.end_date, T1.return_date) + 1 = T2.start_date
    );

SQL Fiddle の例では、次のように返されます。

PRODUCT_NO    PRODUCT_REG_NO    START_DATE                          END_DATE                            RETURN_DATE
TSH128        FLDG              August, 16 2012 00:00:00-0400       September, 15 2012 00:00:00-0400    (null)
TSH125        SCRW              August, 08 2012 00:00:00-0400       September, 07 2012 00:00:00-0400    (null)
TSH137        SCRW              September, 08 2012 00:00:00-0400    October, 07 2012 00:00:00-0400      (null)
  • TSH128 は、既に説明した理由で返されます。
  • TSH116 はend_date2012 年 8 月 7 日であるため、TSH125 が返されます。
  • TSH125 はend_date2012 年 9 月 7 日であるため、TSH137 が返されます。

同じ 内の行のみを比較したい場合はproduct_reg_no、それを JOIN 条件に追加するのは簡単です。1 日差の両方の「方向」が必要な場合は、それも簡単に追加できます。

于 2012-09-16T14:06:41.827 に答える