Her gruptan n kayıt okuma

Birbirleriyle ilişkili iki tablo düşünelim. Birinci tabloda başlık bilgileri ikinci tabloda ise bu başlığa ait detayların bulunduğunu varsayarak her başlıktan n tane detay kaydını getirmek için nasıl bir query yazmamız gerekir. Özellikle haber sitelerinin anasayfalarında her gruptan belli kriterlere uygun n kayıt getirmek veya yüksek stoklu ürün gruplarının en yüksek stoklu n tane ürününü listelemek için bu tür pratik querylere ihtiyaç duyarız.

Bu türden bir query oluşturmak için örnek olarak Grup ve Urun şeklinde iki tane tablo oluşturalım.

CREATE TABLE [dbo].[Grup] (
[GrupId] [int] IDENTITY (1, 1) NOT NULL ,
[GrupAd] [char] (10) NULL
) ON [PRIMARY]
GO

CREATE TABLE [dbo].[Urun] (
[UrunId] [int] IDENTITY (1, 1) NOT NULL ,
[UrunAd] [char] (10) NULL ,
[GrupId] [int] NULL ,
[Stok] [int] NULL
) ON [PRIMARY]

Birinci tabloda ürün grupları, ikinci tabloda ise ürün bilgileri ve stok adetleri bulunmaktadır. Örnek olarak aşağıdaki kayıtları girelim.

GrupIdGrupAd
1G1
2G2
UrunIdUrunAdGrupIdStok
1P114
2P226
3P317
4P420
5P521
6P613

Bu veriler doğrultusunda aşağıdaki işlemleri yapalım;
Her grubun ilk veya ürününü okumak.
Gruplara ait ilk veya son ürünü okumak veya stoğu en fazla veya en düşük olan ürünleri okumak için UrunId veya Stok tutarlarından yararlanılır. Bu tür sorgularda sub query kullanılır. İç query’de Urun tablosunu GrupId’ye göre gruplayıp o gruba ait ilk veya son ürünü bulunur vey o ürünlere ait ID üzerinden ürünlerin bilgilerine erişilir.

SELECT U.GrupId,UrunId,UrunAd,Stok
FROM Urun U INNER JOIN (
SELECT GrupId,MIN(UrunId) as MinUrunId
FROM Urun GROUP BY GrupId
) as T ON U.GrupId=T.GrupId AND U.UrunId=T.MinUrunId
GrupIdUrunIdUrunAdStok
11P14
22P26

Yine aynı şekilde en büyük ürünleri de bulabiliriz.

SELECT U.GrupId,UrunId,UrunAd,Stok
FROM Urun U INNER JOIN (
SELECT GrupId,MAX(UrunId) as MaxUrunId
FROM Urun GROUP BY GrupId
) as T ON U.GrupId=T.GrupId AND U.UrunId=T.MaxUrunId


Her grubun ilk 2 ürününü getirelim.
Bunun önceki query’den farkı birden fazla ürünün isteniyor olmasıdır. Bilindiği Max veya MIN gibi grupsal fonksiyonlar, tek kayıt döndürür. Bu tür işlemleri kolayca yapabilmek için satırları numaralandırmak gerekir. Bunun için tablodaki IDENTITY olan UrunId kolonundan yararlanacağız. Bu numarayı kullanarak tabloyu kendisiyle JOIN edeceğiz. Burada her grubun ilk 2 kaydını getireceğimiz için her ürünü ele alıp o üründen önce kaç kayıt olup olmadığını sorgulayacağız. Kendisinden önce en fazla 2 kayıt olan ürünleri getireceğiz. Böylece o gruptaki ilk 2 kayıt gelmiş olur.

SELECT U1.GrupId,GrupAd,UrunId,UrunAd,Stok
FROM Urun U1 INNER JOIN Grup G ON U1.GrupId=G.GrupId
WHERE (SELECT COUNT(*)
FROM Urun AS U2
WHERE U2.GrupId = U1.GrupId AND U2.UrunId<U1.UrunId) < 2
ORDER BY G.GrupAd
GrupIdGrupAdUrunIdUrunAdStok
1G11P14
1G13P37
2G22P26
2G24P40

Her grubun stoğu bulunan ilk 2 ürününü getirelim.
Yukarıdaki query’e stok koşulunu da ekleyeceğiz. Bu koşulu hem içerdeki query hem de dış query’e ekleyerek doğru sonuca varırız. Eğer sadece dış query’e yazarsak ilk 2 kayıt içerisinde stoğu 0 olan kayıt olduğu için(UrunId=4) 2 nolu grubtan tek kayıt gelecektr. Sadece iç query’e yazarsak bu sefer 2.gruba ait hem 4 hem de 5 nolu ürün gelecektir. 5 nolu ürün gelir çünkü gerçekten de kendisinde önce stoğu>0 olan 2 kayıt var. Bu iki sıkıntıyı aşmak için her iki tarafa da stok koşulunu ekleyeceğiz.

 SELECT U1.GrupId,GrupAd,UrunId,UrunAd,Stok
FROM Urun U1 INNER JOIN Grup G ON U1.GrupId=G.GrupId
WHERE (SELECT COUNT(*)
FROM Urun AS U2
WHERE U2.GrupId = U1.GrupId AND U2.UrunId<U1.UrunId AND U2.Stok < 0 
GrupIdGrupAdUrunIdUrunAdStok
1G11P14
2G22P26
1G13P37
2G25P51

Her grubun son 2 ürününü listeleyelim.
Her grubun en son kayıt edilmiş 2 ürününü getirelim. En son kayıt edilmiş ürünler, UrunId’leri en yüksek olarak ürünlerdir. Yine aynı şekilde yukarıdaki queryleri kullanacağız. Tek farkı, ürünleri sorgularken üründen sonra kayıt edilmiş ürünleri listeleyeceğiz.

SELECT U1.GrupId,GrupAd,UrunId,UrunAd,Stok
FROM Urun U1 INNER JOIN Grup G ON U1.GrupId=G.GrupId
WHERE (SELECT COUNT(*)
FROM Urun AS U2
WHERE U2.GrupId = U1.GrupId AND U2.UrunId


Her grubun son 2 ürününü listeleyelim.
Bu yazıda geliştirdiğimiz queryleri basit haliyle UNION ifadesiyle de yapabiliriz. Fakat bunun için her SELECT cümlesini manual oluşturmamız gerekir. Örneğin her grubun ilk 2 ürününü listeyelim.

SELECT TOP 2 UrunId,UrunAd FROM Urun WHERE GrupId=1
UNION
SELECT TOP 2 UrunId,UrunAd FROM Urun WHERE GrupId=2


burada görüldüğü gibi yeni bir grup eklendiğinde UNION ifadesiyle yeni bir SELECT satırı eklemek gerekir. Peki UNION ile her grubun en son iki ürününü nasıl okuruz. Bunun örneğini bir sonraki yazıda yapalım.

Her gruptan n kayıt okuma” hakkında 4 yorum

  1. burak tosun

    vallahi ben bu oyunu sevdim ne deseniz ben bu oyunu iyi buldum ne yazıkki sevmeyenler de var

    Cevapla
  2. ugur.doner

    Merhabalar

    “Her grubun ilk 2 ürününü getirelim.” kısmındaki örnek kod bölümünde html ve sql kodları içe içe geçmiş durumda olduğundan konuyu algılayamadım düzeltmenizi rica ediyorum. Ayrıca diğer vermiş olduğunuz bilgilerden çok faydalandım sonsuz teşekkürler.

    Cevapla
  3. Taner GÜLBENZER

    Merhabalar;
    “Her grubun ilk 2 ürününü getirelim” ve diğerlerinde maalesef kodlar yarım olduğundan okunamıyor. Rica etsem tam okunabilir halini gösterebilir misiniz?

    Cevapla

Bir cevap yazın

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