18 Eylül 2014 Perşembe

Query nesneleri (Queries)-3 : Inner Join, Outer Join, Exists Join, NotExists Join

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.
CustTableCustTrans
AccountNumNameAccountNumAmountMST
M001AliM001250
M002HasanM00160
M003KadirM00320
M00385
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 :
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
AccountNumNameAccountNumAmountMST
M001AliM001250
M001AliM00160
M003KadirM00320
M003KadirM00385
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 :
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
AccountNumNameAccountNumAmountMST
M001AliM001250
M001AliM00160
M002Hasan
M003KadirM00320
M003KadirM00385
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));
 }

Bakınız : Query nesneleri 1 Query nesneleri 2Query nesneleri 4

Ali Güç - 2014


Hiç yorum yok:

Yorum Gönder