- 締切済み
OracleSQL 組み合わせチェック
いつもお世話になっております。 OracleSQL 組み合わせチェックについて、 どのようにしたらチェックができるのかお知恵をお貸しください。 ◆データテーブル 連番 データ ------------- 1 01 1 10 2 02 2 20 3 10 3 01 4 03 4 30 5 01 5 20 <やりたいこと> 連番は必ず2組みずつ入っていて、 データの組み合わせが(01,10)(02,20)(03,30)のどれかになっています。 ※組み合わせなので、(10,01)等の場合もあります。 正しくない組み合わせを抽出したいです。 結果としては、下記の出したいです。 連番 データ ------------- 5 01 5 20 どのようにSQLを組めばこのようなチェックができるでしょうか? よろしくお願いします。
- みんなの回答 (4)
- 専門家の回答
みんなの回答
- Chronos198
- ベストアンサー率30% (105/349)
今更だけどスマートなの書いてみました。 Select T1.連番, T1.データ From データテーブル T1 Inner Join データテーブル T2 -- 自分と自分を結合する On T1.連番 = T2.連番 -- 連番が同じ And T1.RowId != T2.RowId -- 自分自身のレコードじゃない And T2.データ != Decode( T1.データ, 01, 10, 10, 01, 02, 20, 20, 02, 03, 30, 30, 03, Null ) -- データが組み合わせ通りじゃない Order By T1.連番, T1.データ;
- Siegrune
- ベストアンサー率35% (316/895)
select No,minData,maxData from (select "連番" No,min("データ") minData from "テーブル" group by "連番") tbl1, (select "連番" No,min("データ") maxData from "テーブル" group by "連番") tbl2 where tbl1.No = tbl2.No and (minData,maxData) not in (select 01,10 from dual union select 02,20 from dual union select 03,30 from dual ) order by No でいいと思うけど(未検証) 簡単に説明すると (select "連番" No,min("データ") minData from "テーブル" group by "連番") tbl1, で最小値、 (select "連番" No,min("データ") maxData from "テーブル" group by "連番") tbl2 で最大値を求める(必ず2つなので、最小値に小さいほう、最大値に大きいほうがはいる) "連番"で結合すると、 1,01,10 2,02,20 ・・・ 5,01,20 となり、 (minData,maxData) not in ・・・ の条件で No,minData,maxData ------------------ 5,01,20 とでてくる。 質問のように 連番 データ ------------- 5 01 5 20 と出したければ、 select No "連番",mindata "データ" from (上記select文でorder by句抜き) union select No "連番",maxdata "データ" from (上記select文でorder by句抜き) order by no とすればいいと思いますが、あえてそうする必要があるのかどうか?
- 原沢 信道(@nharasawa)
- ベストアンサー率53% (90/168)
select * from データテーブル a where not( データ='01' and exists(select 0 from データテーブル b where データ='10' and a.連番=b.連番) or データ='02' and exists(select 0 from データテーブル b where データ='20' and a.連番=b.連番) or データ='03' and exists(select 0 from データテーブル b where データ='30' and a.連番=b.連番) or データ='10' and exists(select 0 from データテーブル b where データ='01' and a.連番=b.連番) or データ='20' and exists(select 0 from データテーブル b where データ='02' and a.連番=b.連番) or データ='30' and exists(select 0 from データテーブル b where データ='03' and a.連番=b.連番)) です。
- anmochi
- ベストアンサー率65% (1332/2045)
与えられた条件をまとめると、 ・連番は数字(正確には質問の中で言及されていないがとりあえずこうしておく)。 ・データはvarchar2(2)またはnvarchar2(2)であり、必ず2文字入っている。 ・1つの連番につきデータは必ず2件のみであり、1件または3件以上ある場合はない。 ・1つの連番につきデータはX0と0Yのみで、XXやXYなど(例えば11)はない。 という前提で、 select * from データテーブル where データ like '%0' とすると連番と10、20、30のデータのものが抽出され、 select * from データテーブル where データ like '0%' とすると連番と01、02、03のデータのものが抽出される。 そこでその2つのselect結果をインラインビュー(サブクエリー)としてinner joinで「正しくない」条件で結合してやればよい。 select d1.連番, d1.データ, d2.データ from (select * from データテーブル where データ like '%0') d1 inner join (select * from データテーブル where データ like '0%') d2 on ? order by d1.連番 asc この?の部分を考えていただきたい。 ヒント:同じ連番の中でd1のデータの1文字目とd2のデータの2文字目が・・・・? さらに > 結果としては、下記の出したいです。 には、 select * from データテーブル where 連番 in ( select d1.連番 from (select * from データテーブル where データ like '%0') d1 inner join (select * from データテーブル where データ like '0%') d2 on ? ) order by 連番 asc, データ asc とさらにサブクエリにする事で対応できそうだね。