KVA wrote:Есть задачка и что-то никак не вырисовывается простое и быстрое решение.
Для каждого order (ord_id) в таблице может содержаться 0 или более записей с разным IOI (ioi_id). Надо написать SQL который определяет являются ли два данных order-а разными.
Orders считаются разными если
1. у них разное количество IOI (for example ord_id=200 and ord_id=400)
2. если количество IOI одинаковое (ord_id=200,ord_id=300 или ord_id=400,ord_id=500), но разная информация ioi_amt и price не совпадают
Code: Select all
ioi_id ord_id | ioi_amt price
1 200 | 1 90
2 200 | 2 80
3 200 | 3 70
4 300 | 1 90
5 300 | 2 0
6 300 | 3 70
7 400 | 125 10
8 500 | 200 50
9 600 | 100 10
10 700 | 100 10
Понятно что со случаем 1 проблем нет. Так же нет проблем если количество IOI = 1. А вот как сравнить в случае нескольких IOI (ord_id=200,ord_id=300)? Может кто подскажет как это сделать. Вопрос еще упирается в то что этот SQL будет частью большой и медленной stored procedure которую замедлять уже дальше просто нельзя.
If you want to do it in one SQL statement, then one way might be (under MS SQL 2k):
Code: Select all
Given:
drop table t1;
create table t1(
ioi_id int,
ord_id int,
ioi_amt int,
price int
);
insert into t1 values( 1,200,1,90 );
insert into t1 values( 2,200,0,80 );
insert into t1 values( 3,200,3,70 );
insert into t1 values( 4,300,1,90 );
insert into t1 values( 5,300,2,80 );
insert into t1 values( 6,300,3,70 );
insert into t1 values( 7,400, 125,10 );
insert into t1 values( 8,500, 200,50 );
insert into t1 values( 9,600, 100,10 );
insert into t1 values( 10,700, 100,10);
select a.ord_id, b.ord_id, 'not eq'
from t1 a join t1 b on a.ioi_amt!=b.ioi_amt and a.price!=b.price and a.ord_id < b.ord_id
group by a.ord_id, b.ord_id
union all
select a_ord_id, b_ord_id, 'eq' from
(select a.ord_id a_ord_id, b.ord_id b_ord_id, count(*) cnt
from t1 a join t1 b on a.ioi_amt=b.ioi_amt and a.price=b.price and a.ord_id < b.ord_id
group by a.ord_id, b.ord_id
) x
join
(select ord_id, count(*) cnt
from t1 group by ord_id
) y
on x.a_ord_id=y.ord_id
where x.cnt=y.cnt
200 300 not eq
200 400 not eq
200 500 not eq
200 600 not eq
200 700 not eq
300 400 not eq
300 500 not eq
300 600 not eq
300 700 not eq
400 500 not eq
500 600 not eq
500 700 not eq
600 700 eq
.. or another:
Code: Select all
select
a.ord_id,
b.ord_id,
case when
(select count(*) from t1
where ord_id=a.ord_id)
!=
(select count(*)
from t1 aa join t1 bb on aa.ioi_amt=bb.ioi_amt and aa.price=bb.price
where aa.ord_id = a.ord_id and bb.ord_id=b.ord_id)
then 'not eq' else 'eq' end
from (select distinct ord_id from t1) a join (select distinct ord_id from t1) b on a.ord_id < b.ord_id
Rgds.
<added>
Sorry, I goofed with the first query. It should be like this:
Code: Select all
select a.ord_id, b.ord_id, 'not eq'
from (select distinct ord_id from t1) a join (select distinct ord_id from t1) b on a.ord_id < b.ord_id
left join (
select a_ord_id, b_ord_id from
(select a.ord_id a_ord_id, b.ord_id b_ord_id, count(*) cnt
from t1 a join t1 b on a.ioi_amt=b.ioi_amt and a.price=b.price and a.ord_id < b.ord_id
group by a.ord_id, b.ord_id
) x
join
(select ord_id, count(*) cnt
from t1 group by ord_id
) y
on x.a_ord_id=y.ord_id
where x.cnt=y.cnt) c on a.ord_id=c.a_ord_id and b.ord_id=c.b_ord_id where c.a_ord_id is null
union all
select a_ord_id, b_ord_id, 'eq' from
(select a.ord_id a_ord_id, b.ord_id b_ord_id, count(*) cnt
from t1 a join t1 b on a.ioi_amt=b.ioi_amt and a.price=b.price and a.ord_id < b.ord_id
group by a.ord_id, b.ord_id
) x
join
(select ord_id, count(*) cnt
from t1 group by ord_id
) y
on x.a_ord_id=y.ord_id
where x.cnt=y.cnt
</added>