🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: borland.public.vdbase.data.sql
9 messages
9 total messages Started by Mark Berry Fri, 19 Feb 1999 00:00
SQL OUTER JOIN giving unpredictable results
#37
Author: Mark Berry
Date: Fri, 19 Feb 1999 00:00
44 lines
2116 bytes
Hi,

I've been corresponding on this topic over in the programming forum
(news://forums.inprise.com/36CCC521.2AB93588%40nospam.mcbsys.com), then
realized there is a special place just for SQL!  Maybe someone here can
steer me in the right direction...

I have an application that is supposed to maintain a 1:1 relation
between two tables, Contact1 and Contact2, based on the AccountNo
field.  Sometimes this gets out of whack, and I'm trying to write a
little VDB7 routine to display (and ultimately delete) orphaned
records.  The example below looks for Contact1 records with no matching
Contact2.  

The basic question is how to identify orphaned records with SQL.  My
RIGHT OUTER JOIN checking a field in the "left-side" table for NULL
doesn't seem to bring back any rows.

My sample contact1 has 1 record, and contact2 has 0 records, i.e.
Contact1's record is an orphan.  When I run this code:

SELECT *
FROM "M:\GM4Trados\Test\contact2.dbf" Contact2
   RIGHT OUTER JOIN "M:\gm4trados\Test\contact1.dbf" Contact1
   ON  (Contact2.ACCOUNTNO = Contact1.ACCOUNTNO)  
WHERE  (Contact2.ACCOUNTNO IS NULL)  

I get no rows in the result.  However, this old-fashioned approach:

use contact1
use contact2 in select() order contact2
set relation to accountno into contact2
browse

does in fact give me a row to browse.

After reading the posts here under the "Query troubles" topic, I'm
wondering whether this whole thing may have to be re-written
anyway--will I be able to delete the orphaned records if I ever get this
JOIN to behave?

Thanks,

Mark Berry
Re: SQL OUTER JOIN giving unpredictable results
#38
Author: Romain Strieff [TeamB]
Date: Sat, 20 Feb 1999 00:00
42 lines
1767 bytes
In article <36CE28AB.704C343B@nospam.mcbsys.com>, Mark Berry politely 
paraphrased ...
> After reading the posts here under the "Query troubles" topic, I'm
> wondering whether this whole thing may have to be re-written
> anyway--will I be able to delete the orphaned records if I ever get this
> JOIN to behave?
> 
If the result is readonly you won't be able to delete them, behaveing or 
not. I'm by no stretch of imagination an SQL guy, but this works for me, 
try it out.

close all
erase master.dbf
erase child.dbf
if not file("MASTER.DBF")
  create table "master.dbf" (order_id char(2))
  use "master.dbf"
  generate 10   //10 records from 01-10
  replace all order_id with str(recno(),2,0,"0")
  use
endif
if not file("CHILD.DBF")
  create table "child.dbf" (order_id char(2))
  use "child.dbf"
  generate 7   //7 record from 01-07
  replace all order_id with str(recno(),2,0,"0")
  use
endif

DELETE FROM MASTER M WHERE NOT M.ORDER_ID IN;
      (SELECT ORDER_ID FROM CHILD C WHERE c.ORDER_ID=M.ORDER_ID)
use master
//now 08.09 and 10 which where not in child.dbf
// are also deleted in the master
browse 

-- 
Romain Strieff [TeamB]
Please read this newsgroup guide below before 
posting on the private Inprise newsgroups.
http://www.inprise.com/newsgroups/guide.html
--
Re: SQL OUTER JOIN giving unpredictable results
#40
Author: Steve Koterski
Date: Mon, 22 Feb 1999 00:00
28 lines
1817 bytes
On Fri, 19 Feb 1999 19:14:51 -0800, Mark Berry <markb@nospam.mcbsys.com>
wrote:

[...]

>I have an application that is supposed to maintain a 1:1 relation
>between two tables, Contact1 and Contact2, based on the AccountNo
>field.  Sometimes this gets out of whack, and I'm trying to write a
>little VDB7 routine to display (and ultimately delete) orphaned
>records.  The example below looks for Contact1 records with no matching
>Contact2.  
>
>The basic question is how to identify orphaned records with SQL.  My
>RIGHT OUTER JOIN checking a field in the "left-side" table for NULL
>doesn't seem to bring back any rows.

[...]

What version of the BDE are you using? I seem to recall a problem in some
earlier version using outer joins *and* filtering to just the non-matching
rows like this. Does it work if you juxtapose the two tables and use a LEFT
OUTER JOIN?

//////////////////////////////////////////////////////////////////////////
Steve Koterski                       "For people who like peace and quiet:
Technical Publications               a phoneless cord."
INPRISE Corporation                                             -- Unknown
http://www.inprise.com/delphi
Re: SQL OUTER JOIN giving unpredictable results
#42
Author: Mark Berry
Date: Mon, 22 Feb 1999 00:00
29 lines
1838 bytes
Roamin,

Romain Strieff [TeamB] wrote:
> If the result is readonly you won't be able to delete them, behaveing or
> not. I'm by no stretch of imagination an SQL guy, but this works for me,
> try it out.
> 
> DELETE FROM MASTER M WHERE NOT M.ORDER_ID IN;
>       (SELECT ORDER_ID FROM CHILD C WHERE c.ORDER_ID=M.ORDER_ID)

Thanks, that works great on my sample data and makes sense to my simple
mind (select the good ones, then NOT them).  It also doesn't seem to
create the huge temporary tables created by a JOIN.  I was actually
testing with "SELECT *" in place of "DELETE", since I want to give the
user the opportunity to review the records before deleting them.

The problem comes when run on production-size tables.  I've got five
tables to check.  The master is about 4000 records; the child tables
range from 4000 to 55,000.  I finally killed the process after an hour. 
It CPU-bound, I think--NT Task Manager showed it running at 81% of my
Pentium Pro 200 the whole time, and I didn't hear a lot of disk
swapping.

I'm beginning to wonder if it wouldn't be simpler to just loop through
each table and do a findKey() based on each record.  WDYT?

Thanks much for your help!

Mark Berry
Re: SQL OUTER JOIN giving unpredictable results
#43
Author: Mark Berry
Date: Mon, 22 Feb 1999 00:00
25 lines
1660 bytes
Steve,

Steve Koterski wrote:
> What version of the BDE are you using? I seem to recall a problem in some
> earlier version using outer joins *and* filtering to just the non-matching
> rows like this. Does it work if you juxtapose the two tables and use a LEFT
> OUTER JOIN?

I get the same results with 4.51 and 5.01, RIGHT or LEFT OUTER JOIN.

This is happening when Contact1 has 1 record and Contact2 has 0.  If I
add one more record to Contact1, an interesting thing happens:  the SQL
Results grid correctly displays both orphaned records until I scroll
right to look at other columns.  Then only the first record is visible;
the second row disappears (turns gray), although the indicator columns
still shows two rows.  If I try to scroll up, I see "1 of 2" briefly in
the upper right corner.  When I scroll back to the left, the second row
still is not visible.

Any ideas?  What are my alternatives?  Is the nested SELECT suggested by
Romain the way to go?  Why is that so slow?

Thanks very much for your help,

Mark Berry
Re: SQL OUTER JOIN giving unpredictable results
#44
Author: Romain Strieff [TeamB]
Date: Tue, 23 Feb 1999 00:00
28 lines
1773 bytes
In article <36D1B713.8E3E747B@nospam.mcbsys.com>, Mark Berry politely 
paraphrased ...
> 
> Thanks, that works great on my sample data and makes sense to my simple
> mind (select the good ones, then NOT them).  It also doesn't seem to
> create the huge temporary tables created by a JOIN.  I was actually
> testing with "SELECT *" in place of "DELETE", since I want to give the
> user the opportunity to review the records before deleting them.
> 
> The problem comes when run on production-size tables.  I've got five
> tables to check.  The master is about 4000 records; the child tables
> range from 4000 to 55,000.  I finally killed the process after an hour. 
> It CPU-bound, I think--NT Task Manager showed it running at 81% of my
> Pentium Pro 200 the whole time, and I didn't hear a lot of disk
> swapping.
---
No idea, are there _simple_ indexes for the involved fields?

> I'm beginning to wonder if it wouldn't be simpler to just loop through
> each table and do a findKey() based on each record.  WDYT?
---
That's also a possibility. 
-- 
Romain Strieff [TeamB]
Please read this newsgroup guide below before 
posting on the private Inprise newsgroups.
http://www.inprise.com/newsgroups/guide.html
--
Re: SQL OUTER JOIN giving unpredictable results
#45
Author: Mark Berry
Date: Tue, 23 Feb 1999 00:00
18 lines
1286 bytes
I think I figured out how to get the join to work:  

- Put the table containing orphaned records on the left side of a LEFT
OUTER JOIN.

- Explicitly specify field names, i.e. don't use "SELECT *".

- Issue last() and first() before checking endOfSet.

I guessed at the last part after noticing that the SQL grid didn't
correctly display rows until you scrolled down, then back up.  (Does
news of such anomolies ever get back to Inprise?  Or this VDB still
being developed/debugged?)

Unfortunately, I'm unable to delete the rows based on this rowset, but
it may be the best way to display rows before deletion.

Mark Berry
Re: SQL OUTER JOIN giving unpredictable results
#46
Author: Mark Berry
Date: Tue, 23 Feb 1999 00:00
33 lines
1864 bytes
Romain,

Romain Strieff [TeamB] wrote:
> No idea, are there _simple_ indexes for the involved fields?

No, but there are indexes that _begin_ with the involved field.  Adding
a simple index didn't affect performance.

I believe your earlier example could be simplified to omit the condition
within the subquery:

  DELETE FROM MASTER M WHERE NOT M.ORDER_ID IN;
      (SELECT ORDER_ID FROM CHILD C)

But even with that simplification, executing a SELECT with the "NOT IN
(subquery)" approach takes 1 minute 39 seconds on a medium-size table,
compared to 7 seconds for the "OUTER JOIN" approach.  And "delete for
not seek(key,alias)" takes 4 seconds.

I can only guess that the IN operator is not very efficient; maybe it
was tested more on short lists of values.  Too bad, as it does seem to
be the most elegant solution.

So I guess it's OUTER JOIN to get a rowset for displaying the records,
and "delete for not seek()" to do the actual deletion.  So much for
OODML.

Thanks again for your input.  I'm frustrated by the difficulties of
performing this simple operation, but I'm grateful for the SQL lesson!

Regards,

Mark Berry
Re: SQL OUTER JOIN giving unpredictable results
#47
Author: Romain Strieff [TeamB]
Date: Wed, 24 Feb 1999 00:00
37 lines
2115 bytes
In article <36D34BF6.997CBB03@nospam.mcbsys.com>, Mark Berry politely 
paraphrased ...
> 
> Romain Strieff [TeamB] wrote:
> > No idea, are there _simple_ indexes for the involved fields?
> No, but there are indexes that _begin_ with the involved field.  Adding
> a simple index didn't affect performance.

> 
> I believe your earlier example could be simplified to omit the condition
> within the subquery:
> 
>   DELETE FROM MASTER M WHERE NOT M.ORDER_ID IN;
>       (SELECT ORDER_ID FROM CHILD C)
> 
> But even with that simplification, executing a SELECT with the "NOT IN
> (subquery)" approach takes 1 minute 39 seconds on a medium-size table,
> compared to 7 seconds for the "OUTER JOIN" approach.  And "delete for
> not seek(key,alias)" takes 4 seconds.
>
> I can only guess that the IN operator is not very efficient; maybe it
> was tested more on short lists of values.  Too bad, as it does seem to
> be the most elegant solution.
> 
> So I guess it's OUTER JOIN to get a rowset for displaying the records,
> and "delete for not seek()" to do the actual deletion.  So much for
> OODML.
> 
> Thanks again for your input.  I'm frustrated by the difficulties of
> performing this simple operation, but I'm grateful for the SQL lesson!
You know more than I about this.<G> I hate the stuff.
-- 
Romain Strieff [TeamB]
Please read this newsgroup guide below before 
posting on the private Inprise newsgroups.
http://www.inprise.com/newsgroups/guide.html
--
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads