Home » SQL & PL/SQL » SQL & PL/SQL » Perhaps a stupid query (11.2.0.3)
Perhaps a stupid query [message #628380] Mon, 24 November 2014 12:08 Go to next message
Amine
Messages: 375
Registered: March 2010
Senior Member

Hi all,

create table test
(
  id  int ,
  x   int
);

insert into test values (1,1);
insert into test values (1,2);
insert into test values (1,3);
insert into test values (1,4);

insert into test values (2,1);
insert into test values (2,2);
insert into test values (2,3);

insert into test values (3,1);
insert into test values (3,2);


I want to get all id that have exactly x in (1,2,3).
In my case the query must return id 2 only.

for all id that have exactly x in (1,2), the query must return id 3 only.

Thanks in advance,

Amine
Re: Perhaps a stupid query [message #628381 is a reply to message #628380] Mon, 24 November 2014 12:56 Go to previous messageGo to next message
Mahesh Rajendran
Messages: 10707
Registered: March 2002
Location: oracleDocoVille
Senior Member
Account Moderator
Will not work if you change the order Smile. The sql gurus should give a better solution.
SQL>   1  select id from
  2  (
  3  select id,listagg(x,',')  within group (order by x) as list from test group by id
  4  )
  5* where list =('1,2')
SQL> /

	ID
----------
	 3

Re: Perhaps a stupid query [message #628382 is a reply to message #628381] Mon, 24 November 2014 13:00 Go to previous messageGo to next message
Amine
Messages: 375
Registered: March 2010
Senior Member

I am looking for a generic solution; I do not know if :

select id from test where x = all (select level from dual connect by level <= 2);


I have no test environment.
Re: Perhaps a stupid query [message #628386 is a reply to message #628380] Mon, 24 November 2014 13:14 Go to previous messageGo to next message
Michel Cadot
Messages: 68645
Registered: March 2007
Location: Nanterre, France, http://...
Senior Member
Account Moderator

SQL> def list=1,2,3
SQL> select id
  2  from test
  3  group by id
  4  having count(distinct x)=(select count(*) from table(sys.odcinumberlist(&list)))
  5  /
        ID
----------
         2

1 row selected.

SQL> def list=1,2
SQL> /
        ID
----------
         3

1 row selected.

Re: Perhaps a stupid query [message #628392 is a reply to message #628386] Mon, 24 November 2014 14:20 Go to previous messageGo to next message
Amine
Messages: 375
Registered: March 2010
Senior Member

So, we can't get the requirement without introducing the concept of cardinality (count(distinct x) in this case ), Right Michel ?
There's no other way I mean ?
Re: Perhaps a stupid query [message #628393 is a reply to message #628392] Mon, 24 November 2014 14:26 Go to previous messageGo to next message
Michel Cadot
Messages: 68645
Registered: March 2007
Location: Nanterre, France, http://...
Senior Member
Account Moderator

Raj solution does not introduce any count.

Re: Perhaps a stupid query [message #629369 is a reply to message #628393] Mon, 08 December 2014 03:59 Go to previous messageGo to next message
Amine
Messages: 375
Registered: March 2010
Senior Member

Finally, Tom Kyte did it again !
Re: Perhaps a stupid query [message #629372 is a reply to message #629369] Mon, 08 December 2014 04:12 Go to previous messageGo to next message
Michel Cadot
Messages: 68645
Registered: March 2007
Location: Nanterre, France, http://...
Senior Member
Account Moderator

Did what?
Tom's solution use count as I did. There is not so much difference between our solutions.
Re: Perhaps a stupid query [message #629391 is a reply to message #628382] Mon, 08 December 2014 07:01 Go to previous messageGo to next message
EdStevens
Messages: 1376
Registered: September 2013
Senior Member
Amine wrote on Mon, 24 November 2014 13:00

I have no test environment.


Why not? At the simplest, why can't you just create a test schema in the environment you DO have?
Or better, what stops you from creating your own private test database?
============================================================================
Every oracle professional (or student) should have their own private computer lab. I'm assuming in this day and age anyone in this category already has their own computer. Starting from there, you should do the following:

1 - Go to oracle.com and download Virtual Box. Oracle freely distributes this so your cost so far is zero.
1a - Install Virtual Box

2 - Go to oracle.com and download Oracle Linux. Oracle freely distributes this, only charging if you want a support contract. As they also provide a free public yum server for distribution of most packages, even a support contract is not needed for your personal use.
2a - using Virtual Box and your downloaded linux, create a virtual linux machine.

3 - Go to oracle.com and download whatever db or related product you want. The terms of the oracle license agreement allow you the full use of any product for personal study.

By doing the above I have a full computer lab running on my Windows 7 Home laptop, for a total cost of US$0.00.
============================================================================
Re: Perhaps a stupid query [message #629395 is a reply to message #629391] Mon, 08 December 2014 08:04 Go to previous messageGo to next message
Bill B
Messages: 1971
Registered: December 2004
Senior Member
or if you have a windows machine, simply load oracle express which is free and your all set. It does have some limitations but it runs on a windows machine very easily.

http://www.oracle.com/technetwork/database/database-technologies/express-edition/downloads/index.html
Re: Perhaps a stupid query [message #629397 is a reply to message #629395] Mon, 08 December 2014 08:28 Go to previous messageGo to next message
Amine
Messages: 375
Registered: March 2010
Senior Member

Thanks Bill and EdStevens. I didn't have a test environement because I wasn't simply at home Smile I wrote my query from a friend of mine that has nothing to do with Oracle !
Re: Perhaps a stupid query [message #629398 is a reply to message #629397] Mon, 08 December 2014 08:30 Go to previous messageGo to next message
Amine
Messages: 375
Registered: March 2010
Senior Member

Now, suppose we add these 2 rows :
insert into test values (4,1);
insert into test values (4,6);

SQL> var txt varchar2(100);
SQL> exec :txt := '1,2';

PL/SQL procedure successfully completed.

SQL> 
SQL> select *
  2  from
  3  (
  4   with data
  5   as
  6   (
  7    select
  8    trim( substr (txt,
  9    instr (txt, ',', 1, level  ) + 1,
 10    instr (txt, ',', 1, level+1)
 11    - instr (txt, ',', 1, level) -1 ) )
 12    as token
 13    from (select ','||:txt||',' txt
 14    from dual)
 15    connect by level <=
 16    length(:txt)-length(replace(:txt,',',''))+1
 17   )
 18   select id
 19   from test
 20   where id in (select id from test where x in (select * from data) )
 21   group by id
 22   having count(distinct x) = (select count(*) from data)
 23  )
 24  /

       ID
---------
        3
        4




id 4 should not appear.
Re: Perhaps a stupid query [message #629410 is a reply to message #629398] Mon, 08 December 2014 13:14 Go to previous message
Solomon Yakobson
Messages: 3273
Registered: January 2010
Location: Connecticut, USA
Senior Member
This time Tom's solution (same as Michel's) isn't correct. Look at:

where id in (select id from test where x in (select * from data) )


It selects any id that has x equal to either 1 or 2. As a result condition

having count(distinct x) = (select count(*) from data)


will be true for all IDs that have x equal to either 1 or 2 and any second value. And if set we are looking for would be 1,2,3 it would return any ID that has 1,2,any or 1,3,any or 2,3,any or 1,any,any or 2,any,any or 3,any,any.

Also Tom's solution doesn't consider NULLs. It will return id even when it has NULL x values in addition set we are looking for.

Anyway, below is collection based solution:

select  id
  from  test
  group by id
  having set(cast(collect(x) as ku$_objnumset)) = ku$_objnumset(1,2)
/

        ID
----------
         3

SQL> 


And if you don't want to ignore NULLs:

select  id
  from  test
  group by id
  having set(cast(collect(x) as ku$_objnumset)) = ku$_objnumset(1,2)
     and count(*) = count(x)
/


SY.
Previous Topic: Parallel DML problems (update)
Next Topic: Materialized view refresh does not work
Goto Forum:
  


Current Time: Thu Apr 25 18:35:45 CDT 2024