Bu seride Query nesneleri ile ilgili paylaşmak istediğim son konu join kavramlarıdır. Bu konunun başlangıcı için giriş makalesini ve sıralama, gruplama makalesini incelebilirsiniz.
Alttaki kodları incelediğinizde query nesnelerini kullanırken kodun son derece modüler olduğunu farkedebilirsiniz. Bu sayede, örneğin, kullanıcıdan alınan JoinMode değerine göre çalışma zamanında join modu rahatlıkla değiştirilebilir. Ya da joine yeni bir tablo eklenebilir vb.
Tablolarla ilgili yapılabilecek en önemli optimizasyonlardan birisinin join kullanmak olduğundan bahsetmiştik. Ve ilgili makalede table buffer kullanarak join konusunu incelemiştik. Bu yazımızda ise aynı sorguların Query nesneleri ile nasıl yapıldığını inceleyeceğiz.
Joini kısaca özetlersek; Join sayesinde iki farklı tablodaki veriler sırayla ele alınarak ilişkili kayıtları bulmak yerine, tüm ilişkili kayıtları içeren bir veri kümesi oluşturularak bu küme içinde işlem yapılır. Bu sayede o işlem için gereksiz kayıtlara hiç değinilmemiş olur.
Axapa’da SQL’den bildiğimiz inner join ve outer join yapıları aynen korunur. Ayrıca bu iki yapıya ek olarak exists join ve notExists join tipleri mevcuttur. Şimdi bunlara sıra ile değinelim, ama öncelikle custTable ve custTrans tablolarımızda alttaki gibi bir veri kümesi olduğunu varsayacağız:
Bu tablolara göre M001 ve M003’ün ikişer satır hareketi varken, M002’nin hiç hareketi yoktur.
CustTable | CustTrans | |||
---|---|---|---|---|
AccountNum | Name | AccountNum | AmountMST | |
M001 | Ali | M001 | 250 | |
M002 | Hasan | M001 | 60 | |
M003 | Kadir | M003 | 20 | |
M003 | 85 |
1. Inner join:
Inner join en çok bilinen join yöntemidir. Bu yöntemde ilk tablodaki kayıtlar ile ikinci tablodaki kayıtlar belirtilen kıstas çerçevesinde kartezyen çarpıma tabi olurlar. Sonuç kümesine ikinci tabloda kaydı olmayan kayıtlar alınmaz. Inner join için Inner kelimesini belirtmek gerekmez, zira varsayılan join tipi inner joindir.
Yazım şekli :
Yazım şekli :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
| Query q; QueryRun qr; QueryBuildDataSource qbdsCustTable, qbdsCustTrans; CustTable custTable; CustTrans custTrans; ; q = new Query(); qbdsCustTable = q.addDataSource(tableNum(CustTable)); qbdsCustTrans = qbdsCustTable.addDataSource(tableNum(CustTrans)); qbdsCustTrans.relations( true ); qr = new QueryRun(q); if (qr.prompt()) { while (qr.next()) { custTable = qr. get (tableNum(CustTable)); custTrans = qr. get (tableNum(CustTrans)); info(strFmt( "%1 : %2 : %3 : %4" , custTable.AccountNum, custTable.Name, custTrans.AccountNum, custTrans.AmountMST)); } } //----- While select ile ----- while select custTable join custTrans where custTable.AccountNum == custTrans.AccountNum { info(strFmt( "%1 : %2 : %3 : %4" , custTable.AccountNum, custTable.Name, custTrans.AccountNum, custTrans.AmountMST)); } |
Sonuç kümesi alttaki gibi olacaktır.
CustTable Join CustTrans | |||
---|---|---|---|
AccountNum | Name | AccountNum | AmountMST |
M001 | Ali | M001 | 250 |
M001 | Ali | M001 | 60 |
M003 | Kadir | M003 | 20 |
M003 | Kadir | M003 | 85 |
2. Outer join:
Inner joine benzer olarak ilk tablodaki kayıtlar ile ikinci tablodaki kayıtlar belirtilen kıstas çerçevesinde kartezyen çarpıma tabi olurlar. Ancak sonuç kümesinde ikinci tabloda kaydı olmayan kayıtlar tek bir satır olarak yer alır.
Yazım şekli :
Yazım şekli :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
| Query q; QueryRun qr; QueryBuildDataSource qbdsCustTable, qbdsCustTrans; CustTable custTable; CustTrans custTrans; ; q = new Query(); qbdsCustTable = q.addDataSource(tableNum(CustTable)); qbdsCustTrans = qbdsCustTable.addDataSource(tableNum(CustTrans)); qbdsCustTrans.relations( true ); qbdsCustTrans.joinMode(JoinMode::OuterJoin); qr = new QueryRun(q); if (qr.prompt()) { while (qr.next()) { custTable = qr. get (tableNum(CustTable)); custTrans = qr. get (tableNum(CustTrans)); info(strFmt( "%1 : %2 : %3 : %4" , custTable.AccountNum, custTable.Name, custTrans.AccountNum, custTrans.AmountMST)); } } //----- While select ile ----- while select custTable outer join custTrans where custTable.AccountNum == custTrans.AccountNum { info(strFmt( "%1 : %2 : %3 : %4" , custTable.AccountNum, custTable.Name, custTrans.AccountNum, custTrans.AmountMST)); } |
Sonuç kümesi alttaki gibi olacaktır.
CustTable Outer Join CustTrans | |||
---|---|---|---|
AccountNum | Name | AccountNum | AmountMST |
M001 | Ali | M001 | 250 |
M001 | Ali | M001 | 60 |
M002 | Hasan | ||
M003 | Kadir | M003 | 20 |
M003 | Kadir | M003 | 85 |
3. Exists join:
Bu yöntem kullanıldığında sonuç kümesinde ikinci tabloda en az bir kaydı olan kayıtlar yer alır.Ayrıca ikinci tablodaki herhangibir alanda veri bulunmaz.
Yazım şekli :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
| Query q; QueryRun qr; QueryBuildDataSource qbdsCustTable, qbdsCustTrans; CustTable custTable; CustTrans custTrans; ; q = new Query(); qbdsCustTable = q.addDataSource(tableNum(CustTable)); qbdsCustTrans = qbdsCustTable.addDataSource(tableNum(CustTrans)); qbdsCustTrans.relations( true ); qbdsCustTrans.joinMode(JoinMode::ExistsJoin); qr = new QueryRun(q); if (qr.prompt()) { while (qr.next()) { custTable = qr. get (tableNum(CustTable)); custTrans = qr. get (tableNum(CustTrans)); info(strFmt( "%1 : %2 : %3 : %4" , custTable.AccountNum, custTable.Name, custTrans.AccountNum, custTrans.AmountMST)); } } //----- while select ile ----- while select custTable exists join custTrans where custTable.AccountNum == custTrans.AccountNum { info(strFmt( "%1 : %2 : %3 : %4" , custTable.AccountNum, custTable.Name, custTrans.AccountNum, custTrans.AmountMST)); } |
4. NotExists join:
Bu yöntem kullanıldığında sonuç kümesinde ikinci tabloda hiç kaydı olmayan kayıtlar yer alır. Ve yine ikinci tablodaki herhangibir alanda veri bulunmaz.
Yazım şekli :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
| Query q; QueryRun qr; QueryBuildDataSource qbdsCustTable, qbdsCustTrans; CustTable custTable; CustTrans custTrans; ; q = new Query(); qbdsCustTable = q.addDataSource(tableNum(CustTable)); qbdsCustTrans = qbdsCustTable.addDataSource(tableNum(CustTrans)); qbdsCustTrans.relations( true ); qbdsCustTrans.joinMode(JoinMode::NotExistsJoin); qr = new QueryRun(q); if (qr.prompt()) { while (qr.next()) { custTable = qr. get (tableNum(CustTable)); custTrans = qr. get (tableNum(CustTrans)); info(strFmt( "%1 : %2 : %3 : %4" , custTable.AccountNum, custTable.Name, custTrans.AccountNum, custTrans.AmountMST)); } } //----- while select ile ----- while select custTable notexists join custTrans where custTable.AccountNum == custTrans.AccountNum { info(strFmt( "%1 : %2 : %3 : %4" , custTable.AccountNum, custTable.Name, custTrans.AccountNum, custTrans.AmountMST)); |
Hiç yorum yok:
Yorum Gönder