Members   Search      Help    Register    Login    Home
Home » SQL & PL/SQL » SQL & PL/SQL » Dynamic Columns based on Query(Oracle10G 10.2.0.3.0)(Oracle10G 10.2.0.3.0)
Dynamic Columns based on Query(Oracle10G 10.2.0.3.0) [message #540656] Wed, 25 January 2012 03:57 Go to next message
Ramses800
Messages: 12
Registered: January 2012
Location: Sweden
Junior Member
I have a question about how to query a Oracle 10.2 database.
The data is in 2 tables and the the first table contains metadata about the actual data in the second table.
Now, normally this would just be a join of some sorts but the thing is that I need a rotated result with column headers from the first table displaying the data in the second table. To make things even more complicated, its all dynamic and subject to change.

Here is the example data
Table 1 SIGNALS
This table contains information about a dynamic number of signals
SIGNAL_ID 	SIGNAL_NAME
1 	        AAA
2 	        BBB
3 	        CCC
..              ..
and so on 	and so on
165 	        XZYZZ

At any point could new rows in table SIGNALS be added, deleted or modified

Table 2 SIGNAL_DATA
DATETIME 	        SIGNAL_ID 	VALUE
2012-01-01 00:00:00 	1 	        56
2012-01-01 00:00:00 	2 	        871
2012-01-01 00:00:00 	3 	        0.5
2012-01-01 01:00:00 	1 	        57
2012-01-01 01:00:00 	2 	        987
2012-01-01 01:00:00 	3 	        0.76
and so on 	        .. 	        ..


The data in SIGNAL_DATA will grow every hour with new records for each signal defined in the table SIGNALS

Desired result of the query(based on user input for datetime)
DATETIME              AAA 	BBB 	CCC 	
2012-01-01 00:00:00   56 	871 	0.5 	
2012-01-01 01:00:00   57 	987 	0,75 	
and so on 	       .. 	.. 	.. 	

If the data in the first table would be static it would be fairly easy to write a lengthy but working query.
select distinct(h0.datetime) datetime,
(select value from signal_data h2 where h2.datetime=h0.datetime and h2.signal_id=1) AAA,
(select value from signal_data h3 where h3.datetime=h0.datetime and h3.signal_id=1) BBB,
(select value from signal_data h4 where h4.datetime=h0.datetime and h4.signal_id=1) CCC,
-- AND SO ON for each signal
from signal_data h0
where h0.datetime between start_date and end_time
and h0.signal_id in(select signal_id from signals)


I have been considering using a dynamic sql to create the query on the fly and the run it as well but the problem is that my client is somewhat limited(ie only capable of running normal queries etc) Again, if the signals where static then it would be possible to write a function that returned a TABLE type with a definitions matching the query. But as there is no way to know beforehand that definitions the best I have so far succeeded in is returning a REF CURSOR. Unfortunately, my client does not know how to parse/fetch a cursor so no help there.

Most grateful for any help or insight!

Re: Dynamic Columns based on Query(Oracle10G 10.2.0.3.0) [message #540657 is a reply to message #540656] Wed, 25 January 2012 04:09 Go to previous messageGo to next message
Michel Cadot
Messages: 46653
Registered: March 2007
Location: Nanterre, France, http://...
Senior Member
Account Moderator
Here's an example of what you can do, it gives the number of employees in each department whose names are in the dept table:
SQL> var x refcursor
SQL> declare
  2    req varchar2(32000);
  3    del varchar2(1);
  4  begin
  5    req := 'select';
  6    for rec in ( select dname, deptno from dept order by 1 ) loop
  7      req := req || del || ' count(decode(deptno, ' || 
  8             rec.deptno || ', 1)) "' || rec.dname||'"';
  9      del := ',';
 10    end loop;
 11    req := req || ' from emp';
 12    open :x for req;
 13  end;
 14  /

PL/SQL procedure successfully completed.

SQL> print x
ACCOUNTING OPERATIONS   RESEARCH      SALES
---------- ---------- ---------- ----------
         3          0          5          6

1 row selected.

If you post a working Test case: create table and insert statements along with the result you want with these data then we will work with your table and data.

Regards
Michel
Re: Dynamic Columns based on Query(Oracle10G 10.2.0.3.0) [message #540672 is a reply to message #540657] Wed, 25 January 2012 05:07 Go to previous messageGo to next message
Ramses800
Messages: 12
Registered: January 2012
Location: Sweden
Junior Member
Thank for the reply,
however, that gets me a REF CURSOR that my client(web client written in Java for which I have no possibility of modifying(closed source)) can not handle....
Re: Dynamic Columns based on Query(Oracle10G 10.2.0.3.0) [message #540684 is a reply to message #540672] Wed, 25 January 2012 05:53 Go to previous messageGo to next message
Michel Cadot
Messages: 46653
Registered: March 2007
Location: Nanterre, France, http://...
Senior Member
Account Moderator
What can you modifiy and what can't you? Explain in details.
And post a test case.

Regards
Michel
Re: Dynamic Columns based on Query(Oracle10G 10.2.0.3.0) [message #540737 is a reply to message #540684] Wed, 25 January 2012 08:38 Go to previous messageGo to next message
Ramses800
Messages: 12
Registered: January 2012
Location: Sweden
Junior Member
I can not modify the client that request the data from the database. It is a compiled binary from third party vendor. It accepts standard queries as input(meaning that I write a query and the client executes it). It itself cannot execute dynamic SQL but it is possible to call a Oracle function/procedure that accepts parameter from the client.


Test Case

CREATE TABLE SIGNALS
(
SIGNAL_ID NUMBER,
SIGNAL_NAME VARCHAR2(64 BYTE)
);

INSERT INTO SIGNALS(SIGNAL_ID, SIGNAL_NAME) VALUES (1,'AAA');
INSERT INTO SIGNALS(SIGNAL_ID, SIGNAL_NAME) VALUES (2,'BBB');
INSERT INTO SIGNALS(SIGNAL_ID, SIGNAL_NAME) VALUES (3,'CCC');

CREATE TABLE SIGNAL_DATA
(
DATETIME DATE,
SIGNAL_ID NUMBER,
VALUE NUMBER
);

INSERT INTO SIGNAL_DATA(DATETIME,SIGNAL_ID,VALUE) VALUES(TO_DATE('2012-01-01 00:00:00','YYYY-MM-DD HH24:MI:SS'),1,56);
INSERT INTO SIGNAL_DATA(DATETIME,SIGNAL_ID,VALUE) VALUES(TO_DATE('2012-01-01 01:00:00','YYYY-MM-DD HH24:MI:SS'),1,57);
INSERT INTO SIGNAL_DATA(DATETIME,SIGNAL_ID,VALUE) VALUES(TO_DATE('2012-01-01 02:00:00','YYYY-MM-DD HH24:MI:SS'),1,58);
INSERT INTO SIGNAL_DATA(DATETIME,SIGNAL_ID,VALUE) VALUES(TO_DATE('2012-01-01 03:00:00','YYYY-MM-DD HH24:MI:SS'),1,59);

INSERT INTO SIGNAL_DATA(DATETIME,SIGNAL_ID,VALUE) VALUES(TO_DATE('2012-01-01 00:00:00','YYYY-MM-DD HH24:MI:SS'),2,871);
INSERT INTO SIGNAL_DATA(DATETIME,SIGNAL_ID,VALUE) VALUES(TO_DATE('2012-01-01 01:00:00','YYYY-MM-DD HH24:MI:SS'),2,987);
INSERT INTO SIGNAL_DATA(DATETIME,SIGNAL_ID,VALUE) VALUES(TO_DATE('2012-01-01 02:00:00','YYYY-MM-DD HH24:MI:SS'),2,991);
INSERT INTO SIGNAL_DATA(DATETIME,SIGNAL_ID,VALUE) VALUES(TO_DATE('2012-01-01 03:00:00','YYYY-MM-DD HH24:MI:SS'),2,1024);

INSERT INTO SIGNAL_DATA(DATETIME,SIGNAL_ID,VALUE) VALUES(TO_DATE('2012-01-01 00:00:00','YYYY-MM-DD HH24:MI:SS'),3,0.5);
INSERT INTO SIGNAL_DATA(DATETIME,SIGNAL_ID,VALUE) VALUES(TO_DATE('2012-01-01 01:00:00','YYYY-MM-DD HH24:MI:SS'),3,0.76);
INSERT INTO SIGNAL_DATA(DATETIME,SIGNAL_ID,VALUE) VALUES(TO_DATE('2012-01-01 02:00:00','YYYY-MM-DD HH24:MI:SS'),3,-1.53);
INSERT INTO SIGNAL_DATA(DATETIME,SIGNAL_ID,VALUE) VALUES(TO_DATE('2012-01-01 03:00:00','YYYY-MM-DD HH24:MI:SS'),3,5);
Re: Dynamic Columns based on Query(Oracle10G 10.2.0.3.0) [message #540740 is a reply to message #540737] Wed, 25 January 2012 08:47 Go to previous messageGo to next message
Michel Cadot
Messages: 46653
Registered: March 2007
Location: Nanterre, France, http://...
Senior Member
Account Moderator
Are they able to handle a ref cursor in a query?

SQL> create or replace function f return sys_refcursor is
  2    req varchar2(32000);
  3    del varchar2(1);
  4    res sys_refcursor;
  5  begin
  6    req := 'select';
  7    for rec in ( select dname, deptno from dept order by 1 ) loop
  8      req := req || del || ' count(decode(deptno, ' || 
  9             rec.deptno || ', 1)) "' || rec.dname||'"';
 10      del := ',';
 11    end loop;
 12    req := req || ' from emp';
 13    open res for req;
 14    return res;
 15  end;
 16  /

Function created.

SQL> select f() from dual;
F()
--------------------
CURSOR STATEMENT : 1

CURSOR STATEMENT : 1
ACCOUNTING OPERATIONS   RESEARCH      SALES
---------- ---------- ---------- ----------
         3          0          5          6

1 row selected.


1 row selected.

Regards
Michel
Re: Dynamic Columns based on Query(Oracle10G 10.2.0.3.0) [message #540743 is a reply to message #540740] Wed, 25 January 2012 08:54 Go to previous messageGo to next message
Ramses800
Messages: 12
Registered: January 2012
Location: Sweden
Junior Member
Michel Cadot wrote on Wed, 25 January 2012 15:47
Are they able to handle a ref cursor in a query?


No, unfortunately not.
Re: Dynamic Columns based on Query(Oracle10G 10.2.0.3.0) [message #540754 is a reply to message #540737] Wed, 25 January 2012 09:45 Go to previous messageGo to next message
syakobson
Messages: 771
Registered: January 2010
Senior Member
Ramses800 wrote on Wed, 25 January 2012 09:38
It is a compiled binary from third party vendor. It accepts standard queries as input(meaning that I write a query and the client executes it). It itself cannot execute dynamic SQL but it is possible to call a Oracle function/procedure that accepts parameter from the client.


What if you modify Michel's function to return generated SQL statement text. Then pass:

SELECT  function_name
  FROM  DUAL


to vendor binary. It will return result back to you, right? Then pass that result as SQL as to vendor binary.

SY.
Re: Dynamic Columns based on Query(Oracle10G 10.2.0.3.0) [message #540755 is a reply to message #540754] Wed, 25 January 2012 10:05 Go to previous messageGo to next message
Michel Cadot
Messages: 46653
Registered: March 2007
Location: Nanterre, France, http://...
Senior Member
Account Moderator
Which is what I've done but failed to express it correctly. Confused

@Ramses800
Are you saying that the software is able to handle any type returned in a query field but a ref cursor?
Did you try it?

Regards
Michel

[Updated on: Wed, 25 January 2012 10:08]

Report message to a moderator

Re: Dynamic Columns based on Query(Oracle10G 10.2.0.3.0) [message #540759 is a reply to message #540755] Wed, 25 January 2012 10:57 Go to previous messageGo to next message
Ramses800
Messages: 12
Registered: January 2012
Location: Sweden
Junior Member
It can handle returned tables, ie from "select blabla, bla" but not a ref cursor and yeah, I have tried it.

[Updated on: Wed, 25 January 2012 10:57]

Report message to a moderator

Re: Dynamic Columns based on Query(Oracle10G 10.2.0.3.0) [message #540760 is a reply to message #540759] Wed, 25 January 2012 11:03 Go to previous messageGo to next message
Michel Cadot
Messages: 46653
Registered: March 2007
Location: Nanterre, France, http://...
Senior Member
Account Moderator
Do you mean it accepts a table (array) datatype in "blabla"?

Regards
Michel
Re: Dynamic Columns based on Query(Oracle10G 10.2.0.3.0) [message #540848 is a reply to message #540760] Thu, 26 January 2012 03:56 Go to previous messageGo to next message
Ramses800
Messages: 12
Registered: January 2012
Location: Sweden
Junior Member
Yes, I just put in a standard query like below as a string into the client.
select distinct(h0.datetime) datetime,
(select value from signal_data h2 where h2.datetime=h0.datetime and h2.signal_id=1) AAA,
(select value from signal_data h3 where h3.datetime=h0.datetime and h3.signal_id=1) BBB,
(select value from signal_data h4 where h4.datetime=h0.datetime and h4.signal_id=1) CCC,
from signal_data h0
where h0.datetime between start_date and end_time
and h0.signal_id in(select signal_id from signals)
Re: Dynamic Columns based on Query(Oracle10G 10.2.0.3.0) [message #540853 is a reply to message #540848] Thu, 26 January 2012 05:15 Go to previous messageGo to next message
Michel Cadot
Messages: 46653
Registered: March 2007
Location: Nanterre, France, http://...
Senior Member
Account Moderator
In this query no field is an array, they are all a single value.

Regards
Michel
Re: Dynamic Columns based on Query(Oracle10G 10.2.0.3.0) [message #540861 is a reply to message #540853] Thu, 26 January 2012 06:35 Go to previous messageGo to next message
Ramses800
Messages: 12
Registered: January 2012
Location: Sweden
Junior Member
Sorry, then I misunderstood your meaning. Does this change anything?
Re: Dynamic Columns based on Query(Oracle10G 10.2.0.3.0) [message #540863 is a reply to message #540861] Thu, 26 January 2012 06:39 Go to previous messageGo to next message
Michel Cadot
Messages: 46653
Registered: March 2007
Location: Nanterre, France, http://...
Senior Member
Account Moderator
Yes, I wonder how your software is not built to handle a ref cursor if it is built to handle an array.

Anyway, if it is not written to handle this then you can't do what you want.

Regards
Michel
Re: Dynamic Columns based on Query(Oracle10G 10.2.0.3.0) [message #540869 is a reply to message #540863] Thu, 26 January 2012 06:59 Go to previous messageGo to next message
Ramses800
Messages: 12
Registered: January 2012
Location: Sweden
Junior Member
I was hoping that someone could formulate a killer query eliminating the need for a dynamic query....
Re: Dynamic Columns based on Query(Oracle10G 10.2.0.3.0) [message #540870 is a reply to message #540869] Thu, 26 January 2012 07:12 Go to previous messageGo to next message
Michel Cadot
Messages: 46653
Registered: March 2007
Location: Nanterre, France, http://...
Senior Member
Account Moderator
The only killer is ref cursor... or you can concatenate all fields in a single string,
it depends on what your application does with the result.

Regards
Michel
Re: Dynamic Columns based on Query(Oracle10G 10.2.0.3.0) [message #541060 is a reply to message #540870] Fri, 27 January 2012 06:24 Go to previous messageGo to next message
Ramses800
Messages: 12
Registered: January 2012
Location: Sweden
Junior Member
Michel Cadot wrote on Thu, 26 January 2012 14:12
or you can concatenate all fields in a single string,


Yes, we have tried something along those lines

select datetime,
       max(substr(sys_connect_by_path (value, ';'),2)) values_by_id
from (
select signals.signal_id,
        to_char(h.datetime,'yyyy-mm-dd hh24:mi:ss') datetime,
        h.value,
        row_number() over (partition by h.datetime order by signals.signal_id) rn
from signals v, signal_data h
where 
 signals.signal_id = signal_data.signal_id
and   h.datetime between caltosys(sysdate-1) and caltosys(sysdate)
)
start with rn = 1
connect by rn = prior rn + 1
and prior datetime = datetime
group by datetime
order by datetime


and getting this
DATETIME                VALUES_BY_ID
2012-01-01 00:00:00	56;871;0.5
2012-01-01 01:00:00	57;987;0.76


But getting from here into the desired output have yet eluded us....

[Updated on: Fri, 27 January 2012 06:26]

Report message to a moderator

Re: Dynamic Columns based on Query(Oracle10G 10.2.0.3.0) [message #541062 is a reply to message #541060] Fri, 27 January 2012 06:35 Go to previous messageGo to next message
Michel Cadot
Messages: 46653
Registered: March 2007
Location: Nanterre, France, http://...
Senior Member
Account Moderator
What is the desired output?
Is your application not able to convert the strings into several columns to display them?

Regards
Michel
Re: Dynamic Columns based on Query(Oracle10G 10.2.0.3.0) [message #541066 is a reply to message #540656] Fri, 27 January 2012 06:58 Go to previous messageGo to next message
Ramses800
Messages: 12
Registered: January 2012
Location: Sweden
Junior Member
Ramses800 wrote on Wed, 25 January 2012 10:57

Desired result of the query(based on user input for datetime)
DATETIME              AAA 	BBB 	CCC 	
2012-01-01 00:00:00   56 	871 	0.5 	
2012-01-01 01:00:00   57 	987 	0,75 	
and so on 	       .. 	.. 	.. 	


The client only display each row/column that the resulting table contains, so no.

Is there any way to query the results with the concatenated string into a view with multiple columns?
Re: Dynamic Columns based on Query(Oracle10G 10.2.0.3.0) [message #541075 is a reply to message #541066] Fri, 27 January 2012 08:20 Go to previous messageGo to next message
Michel Cadot
Messages: 46653
Registered: March 2007
Location: Nanterre, France, http://...
Senior Member
Account Moderator
Does it display: in a report file? On screen? On web page? with text format?
with table format (meaning html table)?...

Realize we know NOTHING about your application.
For me your output is just lines of strings, so if the query returns strings it is ok.

Regards
Michel

[Updated on: Fri, 27 January 2012 08:21]

Report message to a moderator

Re: Dynamic Columns based on Query(Oracle10G 10.2.0.3.0) [message #541145 is a reply to message #541075] Fri, 27 January 2012 22:40 Go to previous messageGo to next message
Ramses800
Messages: 12
Registered: January 2012
Location: Sweden
Junior Member
The web client outputs a html table(it run in Internet Explorer) but basically anything that Oracle SQL Developer can put into a grid seems to work
Re: Dynamic Columns based on Query(Oracle10G 10.2.0.3.0) [message #541146 is a reply to message #541145] Fri, 27 January 2012 23:44 Go to previous messageGo to next message
Michel Cadot
Messages: 46653
Registered: March 2007
Location: Nanterre, France, http://...
Senior Member
Account Moderator
If I understand, your application blindly converts the result set into an html table but how it converts a DATE dadatype for instance? Or is it mandatory for your query to ALWAYS return strings (VARCHAR)?

Regards
Michel
Re: Dynamic Columns based on Query(Oracle10G 10.2.0.3.0) [message #541157 is a reply to message #541146] Sat, 28 January 2012 13:59 Go to previous message
Ramses800
Messages: 12
Registered: January 2012
Location: Sweden
Junior Member
To tell you the truth, I just dont know how the client handles it. But it manages to convert DATE/NUMBER/etc into text by itself
Previous Topic:Help gathering summary data
Next Topic:Displaying PDF file in email through Oracle Procedure
Goto Forum:
  


Current Time: Thu Feb 23 04:14:56 CST 2012

Total time taken to generate the page: 2.51090 seconds
.:: Forum Home :: Blogger Home :: Wiki Home :: Contact :: Privacy ::.