Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
FPW2.6 Self-Join Problem
Message
From
15/11/1999 06:28:49
Cetin Basoz
Engineerica Inc.
Izmir, Turkey
 
General information
Forum:
Visual FoxPro
Category:
Databases,Tables, Views, Indexing and SQL syntax
Miscellaneous
Thread ID:
00290598
Message ID:
00291180
Views:
19
>I have a Parent with up to 6 Child Records.
>
>I want to show all the child records in the Screen for the Parent Record using @SAYs.
>
>I want to make a Self Join of my child tables so that all Child records with the same pl_account will be one record in the Cursor.
>
>Unique key for this child table = pl_account + pl_letter
>
>Table Osdpl:
> pl_Account C 5
> pl_letter C 1
> pl_namelas C 20
>
> Total Records = 89 records
> pl_letter = 'A' = 56 records
> pl_letter = 'B' = 23 records
> pl_letter = 'C' = 9 records
>
> A OR B = 79 records
> A OR C = 65 records
> B OR C = 32 records
> A + B + C = 9 records
>
>My goals:
>
> 56 records with no duplications of Names
> These 56 will have
>
> 56 'A' names
> 23 'B' names
> 9 'C' names
>That is, most of the records will have NULLs in the 'B' and 'C' portions
>
>
>SELECT A.pl_account AS A_account, ;
> A.pl_letter AS A_letter, ;
> A.pl_namelas AS A_namelas, ;
> B.pl_letter AS B_letter, ;
> B.pl_namelas AS B_namelas, ;
> C.pl_letter AS C_letter, ;
> C.pl_namelas AS C_namelas ;
> FROM Osdpl A, ;
> Osdpl B, ;
> Osdpl C ;
> WHERE ;
> A.pl_letter = 'A' ;
> AND B.pl_letter = 'B' ;
> AND C.pl_letter = 'C' ;
> GROUP BY 1 ;
> ORDER BY 1 INTO CURSOR Pat_list
>
>There are 89 records.
>
>The above join yields 56 records. This is the corrent number of unique pl_account records.
>
>The 'A' columns are correct.
>
>'B' columns are 90% the same A_namefir and A_namelas'.
>
>'C' columns are also about 90% similar to each other -- C_namefir and C_namelas. But the names are completely different than those in the 'B' columns.


Charles,
FP2.x didn't support outer joins directly as in VFP. You could do what you want in many ways. Here are some :
****************
* Method 1
****************
Clear all
Use OSdpl order tag main alias crs_A && main key pl_account+pl_letter
Use OSdpl order tag main in 0 again alias crs_B && main key pl_account+pl_letter
Use OSdpl order tag main in 0 again alias crs_C && main key pl_account+pl_letter
Select distinct pl_account ;
  from OSdpl ;
  where .t. ;
  into cursor crsParent
Set relation ;
  to pl_account+"A" into crs_A, ;
  pl_account+"B" into crs_B, ;
  pl_account+"C" into crs_C

Browse fields ;
  pl_account :h = "A_account", ;
  A_letter = crs_A.pl_letter, ;
  A_Namelas = crs_A.pl_namelas, ;
  B_Letter = crs_B.pl_letter, ;
  B_Namelas = crs_B.pl_namelas, ;
  C_Letter = crs_C.pl_letter, ;
  C_Namelas = crs_C.pl_namelas ;
  nomodify

****************
* Method 2
****************
Use OSdpl order tag main && main key pl_account+pl_letter
Create cursor Pat_list ;
  (A_Account C(5), A_letter C(1), A_Namelas C(20), ;
  B_Letter C(1), B_Namelas C(20), ;
  C_Letter C(1), C_Namelas C(20))
Select distinct pl_account from OSdpl into array aAccounts
For ix = 1 to alen(aAccounts,1)
  m.A_Account = aAccounts[ix,1]
  =seek(aAccounts[ix,1]+"A","osdpl")
  m.A_letter = OSdpl.pl_letter
  m.A_Namelas = OSdpl.pl_namelas
  =seek(aAccounts[ix,1]+"B","osdpl")
  m.B_Letter = OSdpl.pl_letter
  m.B_Namelas = OSdpl.pl_namelas
  =seek(aAccounts[ix,1]+"C","osdpl")
  m.C_Letter = OSdpl.pl_letter
  m.C_Namelas = OSdpl.pl_namelas
  Insert into Pat_list from memvar
Endfor
Select Pat_list
Go top
Browse


****************
* Method 3
****************
=SubSel("A")
=SubSel("B")
=SubSel("C")
Select A.A_Account, A_letter, A_Namelas, ;
  B_Letter, B_Namelas, ;
  C_Letter, C_Namelas ;
  from crs_A A, crs_B B, crs_C C ;
  where ;
  A.A_Account = B.B_Account ;
  and B.B_Account = C.C_Account ;
  order by 1 ;
  into cursor Pat_list
Browse


Function SubSel
  Parameters tcLetter
  Select pl_account AS (tcLetter+"_account"), ;
    pl_letter AS (tcLetter+"_letter"), ;
    pl_namelas as (tcLetter+"_Namelas") ;
    from OSdpl ;
    where pl_letter = tcLetter ;
    union ;
    SELECT pl_account AS (tcLetter+"_account"), ;
    " " AS (tcLetter+"_letter"), ;
    " " as (tcLetter+"_Namelas") ;
    where pl_account not in ;
    (select distinct pl_account from OSdpl where pl_letter = tcLetter) ;
    and .t. ;
    FROM OSdpl  ;
    order by 1 ;
    INTO CURSOR ("crs_"+tcLetter)
Cetin
Çetin Basöz

The way to Go
Flutter - For mobile, web and desktop.
World's most advanced open source relational database.
.Net for foxheads - Blog (main)
FoxSharp - Blog (mirror)
Welcome to FoxyClasses

LinqPad - C#,VB,F#,SQL,eSQL ... scratchpad
Previous
Reply
Map
View

Click here to load this message in the networking platform