2 Temmuz 2020 Perşembe

INNER JOIN ON - Veya Kısaca JOIN İki Tablonun Kesişimi Yoksa Satır Dönmez

Giriş
INNER JOIN bazen sadece JOIN olarak yazılabilir. Join tiplerini görsel olarak gösteren resimler burada. İki tablonun kesişimini verir. Genellikle bir nesneye ait alt listeleri çekmek için kullanılır

Söz Dizimi
Şuna benzer
SELECT ... FROM Table1 t1 INNER JOIN Table2 t2 ON t2.id = t1.id WHERE ... GROUP BY ...;
Time Table - Tarihçe - Kullanımı
Eğer Table1'i yine kendisi ile join' lemek istersek ortada Table2 olmadığı için bir "inner select" yapmak gerekir. Bu kullanım özellikle "time table" tarzı event' leri kaydeden tablolar için kullanılır.
SELECT ... FROM Table1 t1 INNER JOIN Table2 t2 ON t2.id =
(SELECT FROM TABLE1 where t1.id = t2.id and t1.X < t2.X);
Örnek
Şöyle yaparız
select * from test a
inner join (
  select distinct order_id from test
  where status_update = 'Delivered'
) b on a.order_id = b.order_id
where status_date between '2020-01-01' and '2020-04-25'
Bu durumda iki tablo birleştiği için iki tane orderid sütunu ortaya çıkar
order_id | status_update | status_date | order_id
:------- | :------------ | :---------- | :-------
A        | Received      | 2020-01-01  | A       
A        | Pending       | 2020-01-15  | A       
A        | Processing    | 2020-01-07  | A       
A        | Delivered     | 2020-01-15  | A       
C        | Received      | 2020-02-15  | C       
C        | Delivered     | 2020-02-20  | C       

Aynı şeyi INNER JOIN Alternatifini - yani "IN (SELECT ...)" şeklinde kullanarak şöyle yaparız
select *
from t
where status_date between date '2020-01-01' and date '2020-04-25'
  and order_id in (
  select order_id
  from t
  where status_update = 'Delivered'
);
Bu durumda çıktı olarak şunu alırız
 order_id  status_update  status_date 
 --------- -------------- ----------- 
 A         Received       2020-01-01  
 A         Pending        2020-01-15  
 A         Processing     2020-01-07  
 A         Delivered      2020-01-15  
 C         Received       2020-02-15  
 C         Delivered      2020-02-20  
INNER JOIN Alternatifi
Örnek
Şöyle de yapabiliriz
SELECT ft.TransactionID,
  ft.CompanyID
FROM Finance.FinancialTransaction AS ft
WHERE ft.CompanyID IN (SELECT c.CompanyID
                    FROM Management.Company AS c
                    WHERE CompanyDesc = 'Aerospace & Defense');

INNER JOIN Örnekleri
Örnek - İki Tablo
Elimizde şöyle bir tablo olsun
CREATE TABLE employee ( id SERIAL PRIMARY KEY, username VARCHAR );
CREATE TABLE time_punch (
  id SERIAL PRIMARY KEY,
  employee_id INT NOT NULL REFERENCES employee(id),
  is_out_punch BOOLEAN NOT NULL DEFAULT FALSE,
  punch_time TIMESTAMP NOT NULL DEFAULT now()
);
INSERT INTO employee (username) VALUES ('Bear');
INSERT INTO time_punch (employee_id, is_out_punch, punch_time)
VALUES
(1, false, '2020-01-01 10:00:00'),
(1, true, '2020-01-01 11:30:00'); 
time_punch tablosunu kendisiyle join yapmak için şöyle yaparız
SELECT tp1.punch_time - tp2.punch_time AS time_worked
FROM time_punch tp1
JOIN time_punch tp2
ON tp2.id = (
  SELECT tps.id
  FROM time_punch tps
  WHERE tps.id < tp1.id
  AND tps.employee_id = tp1.employee_id
  AND NOT tps.is_out_punch
  ORDER BY tps.id desc LIMIT 1
)
WHERE tp1.employee_id = 1 AND tp1.is_out_punch

SQL
time_worked
-------------
01:30:00 (1 row)
Örnek - İki Tablo
Elimizde iki tablo olsun.
Table 1:
    +-----+------+-------+
    |  ID |  QTY |  Name |   
    |  1  |  14  |  Milk | 
    |  2  |  15  |  Egg  |
    |  3  |  44  | Apple |
    +-----+------+-------+

    Table 2:
    +-----+------+-------------+
    |  ID | QTY1 |  Location   |   
    |  1  |   5  |  Food shelf | 
    |  2  |   6  |  Food shelf |
    |  3  |   8  |  Food shelf |
    +-----+------+-------------+
Bu iki tablonun farkını görmek isteyelim.
Table 3:
    +-----+-------+-----+-----+-------------+-------+
    |  ID |  QTY  | QTY1| SOLD|  Location   | Name  |
    |  1  |   14  |  5  |  9  |  Food shelf | Milk  |
    |  2  |   15  |  6  |  9  |  Food shelf | Egg   |
    |  3  |   44  |  7  | 37  |  Food shelf | Apple |
    +-----+-------+-----+-----+-------------+-------+
Şöyle yaparız.
SELECT t1.ID, t1.QTY, t2.QTY AS QTY1, (t1.QTY - t2.QTY) AS SOLD, t2.Location, t1.Name 
FROM table1 t1 inner join table2 t2 on t1.ID = t2.ID;
Örnek - İki Tablo
Elimizde 3 tane tablo olsun. Artist'e ait şarkıları çekmek isteyelim.
Artist
 ArtistID (pk)
 ArtName

Song
 SongID (pk)
 SongTitle

ArtistSong
 ArtSongID (pk)
 ArtistID (fk)
 SongID (fk)
Şöyle yaparız.
SELECT ArtName, SongTitle
FROM ArtistSong aso
JOIN Artist a ON aso.ArtistID = a.ArtistID
JOIN Song s ON aso.SongID = s.SongID;
Örnek
A'dab'ye ve B'den A'ya iki tane bağımsız sorgu inner join ile birleştirilebilir. Şöyle yaparız.
SELECT TR1.Title AS SourceTitle, 
       TR2.Title AS DestinationTitle
FROM [Result Map] AS RM
INNER JOIN Table_Result TR1 ON RM.Source_Id=TR1.Id
INNER JOIN Table_Result TR2 ON tr2.Id=RM.destination_id;
Örnek - Üç Tablo
Takip ettiğim kişilere ait son tweet'leri görmek isteyelim. Şöyle yaparız. Burada Türkçe düşünürsek select yapılan tablolar cümledeki nesnelere göre tersten. İngilizce düşünürsek "latest tweets of the users that I follow" ise aynı sırada
SELECT tweets.*, users.*
FROM tweets

JOIN users
  ON users.id = tweets.sender_id

JOIN follows
  ON follows.followee_id = users.id

WHERE follows.follower_id = $user_id

ORDER BY tweets.time DESC
LIMIT 100;
LEFT JOIN İle Farkı
Elimizde şöyle bir kod olsun
select *
from tbl1 inner join
     tbl2
     on true;
Açıklaması şöyle. Yani iki tablonun kesişimi yoksa satır dönmez.
When tbl2 has no rows, the INNER JOIN version returns no rows. The LEFT JOIN version returns rows from the first table with NULL values from the second.
Eğer şöyle yaparsak boş satırlar elde edebiliriz.
select *
from tbl1 left join
     tbl2
     on true;


Hiç yorum yok:

Yorum Gönder