Join Islemi – Inner Join

Giris

Bu makalemizde birden fazla tabloda bulunan birbiri ile iliskili verileri iliskilerine göre tek bir sorgu ile nasil çekecegimize bakacagiz.

Microsoft SQL Server gibi veritabanlari verileri birbiri ile iliskili bir sekilde farkli tablolarda tutmamizi saglarlar. Bu sayede büyük verileri tek bir tabloda tutmak yerine iliskisel olarak farkli tablolara dagitabiliriz. Bu bize performans ve daha kolay anlasilir bir yapi olarak geri döner. Örnegin bir satis sisteminde Müsteri bilgileri ve ürün bilgileri farkli iki tabloda tutulur. Bunlarla iliskili üçüncü bir tabloda ise müsterinin siparis bilgileri tutulur. Eger iliskisel bir yapi kurmazsak siparis tablosunda müsteri ve ürün ile ilgili ihtiyaç duydugumuz tüm verileri tutmak zorunda kaliriz ki buda siparis tablomuzun kolon sayisini artiracagi gibi veriler arasinda bütünlük saglanamamasi gibi büyük sorunlara yol açabilir. Bunun yerine siparis tablosunda müsteri ve ürünleri tanimlayacak birer tanimlayici ID alani tutmamiz yeterli olacaktir. Verilerin bu sekilde iliskili olarak tutulmasi ise, müsterilerin vermis oldugu siparislerin detayi ile ilgili bir sorgu yazmamiz gerektiginde daha karmasik sorgular yazmamizi gerektirecektir.  Bu makalemizde bu tür tablolardan verileri tek bir SQL cümlesi ile nasil çekecegimize deginecegiz.

.

Birden Fazla Tabloda Tutulan Iliskisel Verileri Almak

Yukarda bahsettigimiz gibi siparis bilgilerinin tutuldugu bir veritabanimiz olsun. Bu veritabaninda müsteri, ürün ve siparis bilgilerini tutmak için 3 farkli tablo kullanalim. 1. tablo müsteri bilgilerini 2. tablo ürün bilgilerini 3. tablo ise 1. ve 2. tablodaki ID leri iliskilendirerek hangi müsterinin hangi ürünü aldigi bilgisini tutsun. Örnegimizde kullanacagimiz basit veritabanini kullanmak için asagidaki SQL scriptini kendi SQL serverinizda çalistirin. Sorguda [VeritabaniIsmi]yerine kullanacaginiz veritabani ismini yazmayi unutmayin.
 

Müsteri Tablosu için;

USE [VeritabaniIsmi]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO

CREATE TABLE [dbo].[Musteri](
      [MusteriKey] [uniqueidentifier] NOT NULL,
      [Ad] [nvarchar](50) NULL,
      [Soyad] [nvarchar](50) NULL,
      [TelNo] [char](10) NULL,
      [Adres] [nvarchar](200) NULL,
 CONSTRAINT [PK_Musteri] PRIMARY KEY CLUSTERED
(
      [MusteriKey] ASC

)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, 
ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

SET ANSI_PADDING OFF
GO

ALTER TABLE [dbo].[Musteri] ADD  CONSTRAINT [DF_Musteri_MusteriKey] 
 DEFAULT (newid()) FOR [MusteriKey]
GO

Ürün Tablosu için;

USE [VeritabaniIsmi]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[Urun](
      [UrunKey] [uniqueidentifier] NOT NULL,
      [UrunAdi] [nvarchar](50) NULL,
      [Fiyat] [decimal](6, 2) NULL,
      [Açýklama] [nvarchar](50) NULL,
 CONSTRAINT [PK_Urun_1] PRIMARY KEY CLUSTERED
(
      [UrunKey] ASC

)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, 
ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

ALTER TABLE [dbo].[Urun] ADD  CONSTRAINT [DF_Urun_UrunKey]  DEFAULT (newid()) 
FOR [UrunKey]
GO

 .

Siparis Tablosu için;

USE [VeritabaniIsmi]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[Siparis](
      [SiparisKey] [uniqueidentifier] NOT NULL,
      [SiparisNo] [int] NULL,
      [MusteriKey] [uniqueidentifier] NULL,
      [UrunKey] [uniqueidentifier] NULL,
      [Adet] [smallint] NULL,
      [Tarih] [datetime] NULL,
 CONSTRAINT [PK_Siparis] PRIMARY KEY CLUSTERED
(
      [SiparisKey] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF,
 ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

ALTER TABLE [dbo].[Siparis] ADD  CONSTRAINT [DF_Siparis_SiparisKey]  
DEFAULT (newid()) FOR [SiparisKey]
GO

Yukaridaki scriptleri çalistirdi iseniz veritabaniniz da örnegimizde kullanacagimiz tablolar olusmus demektir.

Inner Join

Birden fazla join türü vardir. Bu makalemizde Inner Join islemine deginecegiz.  Inner Join birlestirilen tablolarda iliskinin saglandigi tüm kayitlari getirir. Simdi Müsterilerin vermis oldugu siparislerin tarihleri getirelim.

select m.Ad,m.Soyad,m.Adres,s.Tarih from Musteri m inner join Siparis s 
on m.MusteriKey = s.MusteriKey

Yukaridaki sorguyu çalistirdigimizda asagidaki bilgiler gelir. Gelen sonuç tablolara kaydettiginiz verilere göre degisiklik gösterebilir.

Ad Soyad Adres Tarih
Mehmet Sabri KUNT Dikmen/Ankara 2010-05-01 09:00:00.000
Seher KUNT Dikmen/Ankara 2009-01-14 12:00:00.000
Seher KUNT Dikmen/Ankara 2008-04-14 09:00:00.000

Yukaridaki sorguya göre müsteri tablomuzda olup hiç siparis vermemis olan müsteriler gelmez. Çünkü Inner Join isleminde sadece iki tabloda da ayni degere sahip olan bilgiler gelir. Örnegimizde Siparis ve Müsteri tablolarini MusteriKey ile birlestirdigimize göre Müsteri tablosunda ve Siparis tablosunda olan ayni MüsteriKey’ler birlestirilerek getirilir. Hiç siparis vermemis bir müsterimize ait MusteriKey siparis tablosunda olmayacagi için sorgu sonucunda bu müsterimize ait bir kayit dönmez. Yukaridaki join sorgusunda Musteri ve Siparis tablolarini yer degistirerek de kullanabilirdik. Iki durumda da sonuç degismezdi.

select m.Ad,m.Soyad,m.Adres,s.Tarih from  Siparis s
inner join Musteri  m on m.MusteriKey = s.MusteriKey

Join sorgumuzda her iki tabloda da MusteriKey’leri esit olan kayitlari getirdik. Join isleminde iki tablo arasinda iliski kurarken seçecegimiz alanin primary ve veya foreign key olma zorunlulugu yoktur.  Veri tipi uyumlu olan herhangi iki alani iliskilendirerek sorgumuzu yazabiliriz. Tabi bu iliski mantikli olmali.  Bir foreign key alani ile iliski kurarsak sorgu performansimiz artar, ayrica text alanlar yerine int gibi alanlarin birlestirilmesi tavsiye edilir. Primary Key alanlar üzerinde birlestirme yapmak bize karsilastirdigimiz bilginin mükerrer olmadigini garantiler çünkü primary key alanlari unique olmak zorundadir. Inner Join ifadesi asagidaki gibi where kelimesi kullanilarak da yazilabilir.

select m.Ad,m.Soyad,m.Adres,s.Tarih from  Musteri m,Siparis s 
where s.MusteriKey = m.MusteriKey

Yukaridaki örnegimizde Siparis ve Musteri tablolarini birlestirerek müsterinin vermis oldugu siparislerin tarihlerini bulduk, simdide veritabanimizdaki 3 tabloyu da birlestirerek müsterinin siparisi ile ilgili ürün bilgisi de dahil tüm bilgileri alalim. Sorgumuzun yeni hali;

select m.Ad,m.Soyad,m.Adres,s.SiparisNo,u.UrunAdi,u.Fiyat 
from  Siparis s 
inner join Musteri  m on m.MusteriKey = s.MusteriKey
inner join Urun u on s.UrunKey = u.Urunkey

.

Yukaridaki sorgu sonucu asagidaki kayitlar döner.

Ad Soyad Adres SiparisNo UrunAdi Fiyat
Mehmet Sabri KUNT Dikmen/Ankara 123 HP Pavilion dv2100 1400.00
Seher KUNT Dikmen/Ankara 123456 Samsung 19 inc LCD 250.00
Seher KUNT Dikmen/Ankara 123456 Samsung D880 410.00

Sorgunun sonucuna bakarsak Siparis tablosunda bulunan kayitlara ait musterikey ve urunkey lere ait musteri ve urun tablosundaki kayitlar getirilir ve hepsi tek bir satirda birlestirilir. Inner join isleminde musteri tablomuzda veya urun tablomuzda kaç adet kayit oldugunun önemi yoktur. Bizim için önemli olan Siparis, Musteri ve Urun tablosunda iliskilendirdigimiz alandaki bilgilerin ayni oldugu kayitlardir. Ara tablomuz siparis olduguna göre Siparis tablosunda bulunan MusteriKey alaninin Musteri tablosundaki karsiligi veya UrunKey alaninin Urun tablosundaki karsiligi önemlidir.  Eger siparis tablosunda olmasina ragmen Musteri tablosunda bu MusteriKey ile ilgili bir kayit yoksa bu kayit sorgumuzun sonucuna yansimaz.  Siparis tablosundaki bir kayittaki musterikeye ait bilgi musteri tablosunda  ayrica UrunKeye ait bilgide Urun tablosunda olmaliki bu siparis bilgisi sorgu sonucumuzda görünsün. Bu çok dikkat etmemiz gereken bir durumdur. Mesela bir müsteriye abc ürünü satildi daha sonra bu abc ürünü Urun tablosundan silindi ise Inner Join ile yapacagimiz sorgularda Siparis tablosunda bulunan bu kayit da ki UrunKey Urun tablosunda bulunamadigi için bu siparis bilgisi sorgu sonucumuza gelmez. Çekmek istediginiz bilgiye göre bu durum önemli olabilir.
Bu makalemizde Join islemlerine giris yaptik ve Inner Join ile basit bir örnek yaptik. Bir sonraki makalemde diger join türlerinde Outer Join hakkinda bilgi verecegim.

Tags:

20 thoughts on “Join Islemi – Inner Join

  •  merhaba ufuk. güzel degerlendirmen için tesekkür ederim. Faydali olabildiysek ne mutlu bize. JOin islemi ile ilgili diger makalelerimizide incelemeni tavsiye ederim.

  •  gördügüm en güzel makalelerden birisi, 

    genelde faydalanir yorum yazmam 🙂

    ama bu makaleye yorum yazip tesekkür etmek istedim.

    Eline Koluna saglik

  • tablolar arasi join yapabilmek için illa foreign key tanimlamasi yapmaya gerek yok. iki tablo arasinda iliskili kolon üzerinden join islemini gerçeklestirebiliriz. Eger tablolar arasinda veri bütünlügünü saglamak istiyor isek bu kolonlardan detay tablosunda foreign key ana tabloda ise primary key tanimlamasini yapmamiz gerekir. Bu makaledede konumuz bu degildi o yüzden kafa karistirmaya gerek yok diye düsünmüstüm.

  • ALTER

    TABLE Siparis ADD CONSTRAINT FK_Siparis__UrunKey FOREIGN KEY (UrunKey) REFERENCES Urun

    GO<

  • Siparis tablosuna Foreign Key tanimlamadan nasi iliski kurdurdun orasini çözemeim dogrusu…

  • aysegul zaten tek veritabani icinde 3 tablo kullanilmis. 3 farkli veritabani nerden cikti

  • Merhabalar,

    benim burada anlamadigim neden 3 tane ayri veritabani kullanildi ? bir veritabani altinda 3 ayri tablo da neden kullanilmadi müseri,ürün ve siparisler ? kafam iyce karisti 🙂 bir açiklik getirirseniz sevinirim…

     

  • Çok güzel anlatilmis. Gönülden tesekkür ediyorum

  • Super olmus emegine saglik.

  • gerçekten çok faydali bsr paylasim olmus.Unuttugum konuyu tekrar hatirlatti bana anlatim çok güzel tesekkürler

  • Makale Ha Diyince Olmuyor  Emek Lazim Bolca Vakit Lazim TAam emek Verelim Ama Volca Vakit Yoktur

  • Malum sitemiz hazir bir script veya template degil. Isin zevkli tarafi herseyi sifirdan yapmak bence. O yuzden islerden vakit bulabildikçe siteye yeni özellikler eklemeye ve hatalari gidermeye çalisiyorum.

    E posta adresini aliyorum cunku yakin zamanda yorum yazan kisileri ilgilendigi makale ile ilgili yeni bir yorum geldiginde haberdar etmek istiyorum.

    Ayric diger maddelerde yazdiklariniz için tesekkür ederim. Sizlerden de makaleler bekleriz 🙂

  •  1 e posta yayinlanmayacak sa neden var

    2 güzel bir paylalim

    3 elinize saglik

    4 afiyet olsun

    5 ben gidiyorum

    6 yeter

    7 daha aklima bir sey gelmedi

    8 ben simdi kaçar

    9 sonra görüsürüz ayriyeten rakam  kalmadi devai haftaya

  • Güzel paylasim, emeginize saglik

  • süper bir anlatim çok tesekkürler.

  • Tesekkurler Cok yararli cok iyi anlatilmis bi makale.Beyninize saglik

  • Gerçektende çok yararli bir paylasim olmus sizden paylasimlarinizin devemini bekliyoruz.

  • Sayenizde inner join mantigini anladim. Bundan daha yalin ve anlasilir anlatim olamazdi herhalde. Tesekkürler…

  • Çok güzel anlatmissiniz tesekkür ederim…

  • select * from musteriler where id =200;

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir