Skip to Main Content
  • Questions
  • Selecting Blank row if data in a table doesn't exist.

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, Jitin.

Asked: May 03, 2006 - 2:36 am UTC

Last updated: May 04, 2006 - 12:25 pm UTC

Version: 9.2.0.4.0

Viewed 1000+ times

You Asked

I've three tables,say A, B & C having three columns each.
Create table A
(Col1 number(2), Col2 Varchar2(10), Col3 Varchar2(10));

Create table B
(Col1 number(2), Col2 Varchar2(10), Col3 Varchar2(10));

Create table C
(Col1 number(2), Col2 Varchar2(10), Col3 Varchar2(10));

Insert into A values(1,'A','def');
Insert into A values(2,'A','def');
Insert into A values(3,'A','def');
Insert into A values(4,'A','def');

Insert into B values(1,'B','efg');
Insert into B values(2,'B','efg');
Insert into B values(2,'B','XYZ');
Insert into B values(4,'B','efg');

Insert into C values(2,'C','ijk');
Insert into C values(4,'C','ijk');

Now I've to display data from three tables in given format.

Col1 Col2 Col3

1 A def
B efg
C -
2 A def
B efg
B xyz
C ijk
3 A def
B -
C -
4 A def
B efg
C ijk

i.e. I've to insert blank row where ID's are even not existing in Tables B & C.

Can I do this in a single query?

Please help.

Thanks




and Tom said...

col2 seems "not necessary", but


ops$tkyte@ORA9IR2> select a.* from a
2 union all
3 select a.col1, 'B', b.col3 from a left join b on (a.col1 = b.col1)
4 union all
5 select a.col1, 'C', c.col3 from a left join c on (a.col1 = c.col1)
6 order by 1, 2, 3
7 /

COL1 COL2 COL3
---------- ---------- ----------
1 A def
1 B efg
1 C
2 A def
2 B XYZ
2 B efg
2 C ijk
3 A def
3 B
3 C
4 A def
4 B efg
4 C ijk

13 rows selected.


assuming a.col1 is the primary key of A. If not, you'll need to distinct that:

ops$tkyte@ORA9IR2> with ids as (select distinct col1 from a)
2 select a.* from a
3 union all
4 select a.col1, 'B', b.col3 from ids a left join b on (a.col1 = b.col1)
5 union all
6 select a.col1, 'C', c.col3 from ids a left join c on (a.col1 = c.col1)
7 order by 1, 2, 3
8 /

COL1 COL2 COL3
---------- ---------- ----------
1 A def
1 B efg
1 C
2 A def
2 B XYZ
2 B efg
2 C ijk
3 A def
3 B
3 C
4 A def
4 B efg
4 C ijk

13 rows selected.




Rating

  (3 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

still need help...

Jitin, May 04, 2006 - 3:04 am UTC

Hi Tom,
Thanks for quick response. But now the problem is that data is in same table.
Scenario:

I've a table containing thousands of records of three types.(A,B & C).
Actually, scenario is this that my table can have zero or multiple rows of 'B' & 'C' type for each row of Type 'A'.
Scripts are given below.

CREATE TABLE AB (col1 number(3), col2 number(3), col3 varchar2(5), col4 number(5));

INSERT INTO AB values (1,2,'A',3000);
INSERT INTO AB values (1,2,'B',3000);
INSERT INTO AB values (1,3,'A',3000);
INSERT INTO AB values (1,3,'C',2000);
INSERT INTO AB values (2,1,'A',4000);
INSERT INTO AB values (2,1,'B',3000);
INSERT INTO AB values (2,1,'B',1000);
INSERT INTO AB values (3,1,'A',5000);
INSERT INTO AB values (3,1,'C',3000);
INSERT INTO AB values (3,1,'C',1000);
INSERT INTO AB values (3,1,'C',1000);

Now I want my output in form as

Col1 Col3 Col4
---- ---- ----
1 A 3000
B 3000
C 2000
2 A 4000
B 3000
B 1000
C -
3 A 5000
B -
C 3000
C 1000
C 1000

Please help.

thanks,
Jitin



Tom Kyte
May 04, 2006 - 3:31 am UTC

You know.... one wonders why this wasn't the original question - since the original question was so very different from this!

Your output is confusing - why isn't A repeated in your output for col1 = 1?  (or why is C repeated when col1 = 3)

ops$tkyte@ORA9IR2> with
  2  data as
  3  (select distinct col1 from ab where col3 = 'A'),
  4  abc as
  5  (select 'A' col3 from dual union all
  6   select 'B' col3 from dual union all
  7   select 'C' col3 from dual ),
  8  abc_data as
  9  (select * from data, abc)
 10  select abc_data.col1, abc_data.col3, ab.col4
 11    from abc_data left join ab on (abc_data.col1 = ab.col1 and abc_data.col3 = ab.col3)
 12   order by abc_data.col1, abc_data.col3
 13  /

      COL1 C       COL4
---------- - ----------
         1 A       3000
         1 A       3000
         1 B       3000
         1 C       2000
         2 A       4000
         2 B       3000
         2 B       1000
         2 C
         3 A       5000
         3 B
         3 C       3000
         3 C       1000
         3 C       1000

13 rows selected.
 

still need help....

Jitin, May 04, 2006 - 3:55 am UTC

Hi tom,
Thanks for the solution.
I think, I was not able to explain my requirement properly. I'm sorry for that.

I got the same solution Using CASE and PipeLined Function Split as given below.

SELECT
LS.COL1,
LS.ITEMS,
CASE
WHEN LS.ITEMS = AB.COL3 THEN
AB.COL4
ELSE
NULL
END COL3
FROM
(
SELECT * FROM
(SELECT DISTINCT COL1 FROM AB) EF,
(SELECT * FROM TABLE(SPLIT('A,B,C'))) GH
) LS,
AB
WHERE LS.COL1 = AB.COL1(+)
AND LS.ITEMS = AB.COL3(+)
ORDER BY LS.COL1
--I used Split function here instead of Using 'select from dual' to make it more Dynamic though I think it'll be an overhead?

output:
COL1 C COL4
---------- - ----------
1 A 3000
1 A 3000
1 B 3000
1 C 2000
2 A 4000
2 B 3000
2 B 1000
2 C
3 A 5000
3 B
3 C 3000
3 C 1000
3 C 1000

But actual requirement is...
'A' type record is a master record and one set of records is identified by value of Col1.
i.e. Records with value 1 in col1 is a set in which 'A' is master record while 'B' & 'C' are child records. 'A' record is reconciled (e.g.reconcilation of invoices and payments) with 'B' type record and has value in col2 different than value in col2 when 'A' record is reconciled with 'C' type record.
In last set of my records, I got the payment ('C' type record) in three parts against one invoice ('A' type record.) -- Please check numeric sum of 'A' & 'C' records.

My requirement is to show all payments for a single invoice.

Hope, this time, I made myself clear..Sorry for so much of trouble but you are the only one I can ask.

Is it possible to solve this thing or do u think that there is some flaw in design?

Thanks again for help,
jitin



Tom Kyte
May 04, 2006 - 7:07 am UTC

if you have master and detail in the same table - one would be inclined to say "that is a flaw in the design"

I don't see any difference from your output vs mine - I don't see any refinement of the problem statement yet - what is wrong with my proposed query?

A reader, May 04, 2006 - 8:03 am UTC

My query was not at all a refinement.It cannot be. I just asked you about overhead in my query using Split Function as I found that cost of query by you was lesser.

Secondly, its not exactly Master-detail relationship as there are no references made on columns. I just meant that like master-detail records, 'A' type records are used as 'Base Records' and are not supposed to be repeated in output while 'B' & 'C' type records can be multiple.



Tom Kyte
May 04, 2006 - 12:25 pm UTC

you started with:

...
I think, I was not able to explain my requirement properly. I'm sorry for that.
......

I had to assume that meant "not there yet, didn't quite get it right"


This is clearly master/detail - what you described anyway. I don't know what you meant by "there are no references made on columns".




So, did we or did we not get the "final solution to the problem here" or did you need to refine the question.