SQL (Structured
Query Language) kendisi bir programlama dili olmamasına rağmen bir çok
kişi tarafından programlama dili olarak
bilinir.
SQL
(Structured Query Language) kendisi bir programlama dili olmamasına rağmen bir
çok kişi tarafından programlama dili olarak bilinir.SQL herhangi bir veri
tabanı ortamında kullanılan bir alt dildir.(sub language) SQL ile yalnızca veri
tabanı üzerinde işlem yapabiliriz. SQL cümleceikleri kullanarak veri tabanına
kayıt ekleyebilir, olan kayıtları değiştirebilir silebilir ve bu kayıtlardan
listeler oluşturabiliriz.SQL cümlecikleri genellikle aynı olmakla birlikte
farklı veri tabanı ortamlarında değişebilmektedir.Ayrıca veri tabanlarının
kendilerine özgü sql komutlarıda vardır.Biz burada her ortamda geçerli olan
temel sql komutları işleyeceğiz.Şimdi örnekler kullanacağımız bir database
tanımlayalım.
FROM İlk önce
bu komut ile başlayalım.Bu komut bütün SQL cümleciklerinde bulunması gerekli
bir komuttur.Bu komut ile hangi tablolar üzerinde çalışacağımı veri tabanına
söylüyoruz.Eğer aynı sql cümleciği ile bir kaç tablo üzerinde işlem yapmak
istersek tablo isimleri arasına virgül koymalıyız.
SELECT Bu komut
ile database üzerindeki tablonun hangi kolonları alacağımız veritabanına
söyleriz.Tablonun bütün kolonlarını görmek istiyorsak '*' karekterini
kullanırız.Sadece belli kolonları görmek istiyorsak kolon isimlerini aralarına
virgül koyarak yanyana yazmalıyız.Yukarıdaki örnekleri açıklayacak olursak
birinci örnek personel tablosundaki bütün kayıtları getirecektir.İkinci örnekte
ise personel ve ücretler tablosundaki bütün kayıtlar
çekilecektir.
Örnek 1 :SELECT * FROM
meslekler; Bütün
meslek bilgilerini almak istersek yukarıdaki gibi bir query yazmalıyız. Örnek 2 :SELECT ad,soyad FROM
personel; Bu query
ise bize firmamızda çalışan bütün personeli listeler.
SQL'de Veri Tabanı
Oluşturma
SQL
komutları yalnızca bir veri tabanı üzerinde geçerli olduğu için veri tabanı
yaratma işlemlerini de anlatmanın yararlı olacağına inanıyorum.Aşağıda anlatılan
işlemler SQL Server 6.5 üzerinde gerçekleştirilmiştir.Database yaratmak için
aşağıdaki komutu yazabiliriz.
database_name : Bu yaratılacak olan veri
tabanının
ismidir.
ON :
Bu ise yaratılacak olan veri tabanın hangi device üzerinde yer alacağını
belirten bir parametredir.Burada aynı zamanda bu device üzerinde size
parametresi ile database'in ne kadar yer kaplayacağını belirmiş oluyoruz.Eğer
device tanımlamaz isek SQL server default device üzerinde 5 mb bir veri tabanı
yaratacaktır.Bu parametre içinde birkaç device ismi kullanarak veri tabanını bir
kaç device üzerinde yer almasını sağlayabiliriz.
LOG
ON : Bu ise yaratılacak olan veri
tabanın log'unun hangi device üzerinde yer alacağını belirten bir parametredir.Burada aynız zamanda bu device üzerinde size parametresi ile database'in
log'unun ne kadar yer kaplayacağını belirmiş oluyoruz.Eğer device tanımlamaz
isek SQL server default device üzerinde bir log tutacaktır.Bu parametre içinde
birkaç device ismi kullanarak veri tabanı log'unun bir kaç device üzerinde yer
almasını sağlayabiliriz.
Örnek 1 :CREATE DATABASE
fat123 Bu
komut ile SQL Server üzerinde fat123 isimli boş bir database yaratmış oluyoruz.(Dönen
mesaj :CREATE DATABASE: allocating 2560 pages on disk
'a1v1') Örnek 2 :CREATE DATABASE
fat123 ON master = 10 Bu komut
ile SQL Server'da master device'ı üzerinde 10 mb'lık fat123 isimli boş bir
database yaratmış oluyoruz. Örnek 3 :CREATE
DATABASE fat123 ON fat123 = 10 LOG ON fat123log = 5 Bu komut
ile SQL Server'da fat123 device'ı üzerinde 10 mb'lık fat123 isimli boş bir
database ve fat123log device'ı üzerinde 5 mb bir log yaratmış
oluyoruz. Örnek 4 :CREATE DATABASE
fat123 ON fat=10 , fat1 = 10 , fat2=10 , fat3=10 LOG ON fat123log = 20 Bu komut ile ise fat123
isimli veri tabanını 4 farklı device üzerinde yaratıyoruz.Genellikle oluşturulan database'in yarısı kadar bir alanda log için oluşturulur.
SQL
Komutları
Order By Bu komut ile belirtilen kolona
göre artan veya azalan bir sıralama ile sorgulama
yapabiliriz. ASC : kullanarak küçükten büyüğe doğru artan sıralama
yapabiliriz. DESC : kullanarak büyükten küçüğe doğru azalan sıralama
yapabiliriz. Ancak ASC kullanmak zorunlu değildir.Çünki default sıralama
tipi ASC'dir.Aynı anda birkaç kolon üzerindende sıralama
yapabiliriz.
Örnek 1 :SELECT * FROM
personel ORDER BY ad ASC; Bu query
ile personel tablosundaki bütün kayıtları ad'a göre küçükten büyüğe doğru
sıralarız. Örnek 2 :SELECT * FROM personel ORDER BY soyad DESC; Bu query
da yukarıdakinin tersine kayıtları büyükten küçüğe doğru
sıralar. Örnek 3 :SELECT * FROM
personel ORDER BY ad,soyad; Bu query kayıtları ad göre artan bir sıralama yapar.Ancak aynı ad ile yaratılmış birden
fazla kayıt varsa ise bunlarıda soyad sırasına göre artan bir şekilde sıralar.Eğer her iki
kolonda aynı ise o zaman okuduğu sırada sıralar. Örnek 4
:SELECT * FROM
personel ORDER BY dogum_tarihi DESC,ad,soyad; Bu
query'de ise pernel kayıtları büyükten küçüğe doğru sıralanıyor.Yani en genç
eleman'dan başlanarak en yaşlı elemana doğru bir liste yapılıyor.Doğum
tarihleri aynı olanlarda ise ad ve soyad'a göre bir sıralama
yapılmaktadır.
Where
Yukarıda yaptığımız sorgulamaların
hepsinde hiç bir koşul belirtmedik.Yani bütün kayıtları tablolardan çektik.Ancak gerçek hayat'ta bu kayıtların sadece bir kısmına ihtiyaç duyarız. Bize
gerekli olan dataları diğerlerinden ayıran bazı özellikleri vardır.İşte bu
özellikleri bu komut yardımı ile kullanarak gerekli datalara
ulaşabiliriz.
Örnek 5 : Adı ahmet olan personeli listelemek
istersek ne yapacağız.Aşagıdaki gibi bir sorgulama
yapacağız. SELECT * FROM
personel WHERE ad='ahmet'; Örnek
6 : Yaşı 40'dan büyük personeli listeleme istersek; SELECT * FROM
personel WHERE doğum_tarihi < '01.01.1959'; sorgulamasını
kullanmalıyız.Elemanın 40 yaşında büyük olması için 1959 yılından önce doğmuş
olması gerekmektedir.O halde doğum_tarihi 1959 yılından küçük olmalıdır. Örnek 7 : Adana'da doğmuş personeli listelemek istersek SELECT * FROM
personel WHERE dogum_yeri = 'Adana'; Örnek
8 : 300 milyondan fazla maaş alan kişileri işe maaşa göre sıralamak
istersek;
SELECT * FROM
ucretler WHERE aylik_ucret >= 300000000 ORDER BY
aylik_ucret;
Operatörler
Her
programlama dilinde olduğu gibi SQL'de de operatörler bulunur.Üç çeşit operatör
mevcuttur.Karşılaştırma oparatörleri , mantıksal operatörler ve kümeleme
operatörleri.Bu karşılaştırma operatörleri aşağıdaki gibidir
; operatör anlamı a>X ...X...a'dan
küçük a<X ...X...a'dan
büyük a=X ...X...a'ya eşit a=>X ...X...a'dan
küçük eşit a<=X ...X...a'dan
büyük eşit a<>X ...X...a'ya eşit
değil
Mantıksal operatörler ise AND,OR,NOT olarak verilebilir.Bu
operatörler burada anlatmayacağız.Bunlar standart bütün dillerde aynı olan
operatörlerdir.Kümeleme operatörleri ise datalar üzerinde gruplama yapmamızı
sağlayan operatörlerdir.Bu operatörler Between,In,Like operatörleridir.Bu
operatörlerin hepsini where ile birlikte kullanmalıyız.
Between
: Aralıklı sorgulama yapmak istersek kullanabilecegimiz bir operatördür.
Örnek 1 : SELECT * FROM
ucretler WHERE aylik_ucret BETWEEN 200000000 AND
300000000; Bu cümlecik ile 200 ile
300 milyon arasında maaş alanlar listelenecektir. Örnek 2
: SELECT * FROM
fat_bsl WHERE ft_tar BETWEEN '01.01.1998'
and '04.06.1999';
Bu sorgulamada ise
fatura tarihi 01.01.1998 ve 04.06.1999 tarihleri arasındaki faturalar
listelenmiştir.Verilen tarih formatının sistemde kullanılan tarih formatı ile
aynı olmasına dikkat edilmelidir.Yoksa sizin verdiğiniz tarih doğru olsa bile
format farklı ise sorgulamanız geriye data döndürmez.(Yukarıdaki sorgulamada
başıma geldide (:)
)
In : Bu komut ile belli
bir kolonun kümesini vererek işlemimizi daha kolay bir şekilde
yapabiliriz. Örnek 3 :SELECT * FROM
personel WHERE meslek_id IN (1,2,3);
Buradaki örnek 'te 1,2 veya 3 meslek grubundan herhangi birine dahil olan
personel listelenemektedir.Bu örnek aşagıdaki şekildeki gibide yapabiliriz. SELECT * FROM
personel WHERE meslek_id=1 OR meslek_id=2 OR
meslek_id=3;
Like : Bu
ise içinde belli bir karakter dizisi bulunan datalara ulaşmak istersek
kullanabileceğimiz bir operatördür. Örnek 4 :SELECT * FROM
personel WHERE adres LIKE '%İstanbul%'; Bu sorgulama ile
adres alanında İstanbul geçen kayıtları listelemiş oluruz. Örnek 5
:SELECT * FROM
personel WHERE adres LIKE '%İstanbul'; Bu sorgulama ile
adres alanının sonunda İstanbul geçen kayıtları listelemiş
oluruz. Örnek 6 :SELECT * FROM
personel WHERE adres LIKE 'İstanbul%'; Bu
sorgulama ile adres alanının başında İstanbul geçen kayıtları listelemiş
oluruz
SQL'de Yeni Bir Kayıt Eklemek
Tabloya
yeni bir satır eklemek istersek INSERT INTO sözcüğünü kullanırız.Genel kullanım
şekli aşağıdaki biçimdedir ; INSERT INTO tablo
adı VALUES (deger1,deger2,deger3,...); Eğer sadece belirli sahalara
değer girmek istersek INSERT INTO'yu aşağıdaki şekildeki gibide
kullanabiliriz. INSERT INTO tablo
adı(kolon1,kolon3,kolon9,kolon7) VALUES
(deger1,deger3,deger9,deger7); Örnek : Yeni bir
personel eklemek istersek ; INSERT INTO personel
VALUES
('asdf2345','Ahmet','Yıldırım','01.01.1960','Ankara','E',1,7,1,'ebuziya
cad.Bakırköy'); Örnek
: Yeni bir meslek eklemek istersek ; INSERT INTO
meslekler VALUES (23,'Belçi',200.000.000);
Bir
tablodan bazı kayıtları başka bir tabloyada aktarabiliriz.Bunun için aşağıdaki
gibi bir ifade yazmalıyız; INSERT INTO
tablo1 SELECT kolon1,kolon2,..FROM tablo2;
Örnek
:INSERT INTO
NEW_CUSTOMER SELECT NAME,CITY FROM
CUSTOMER;
SQL'de Tablolar Üzerinde İşlem
Yapma
Genellikle veri tabanı kayıtları
oluştururken bütün bilgileri bir tabloda değilde birkaç tablo üzerinde
tutarız.Bu dataların hem daha düzenli durmasını hemde gereksiz veri
tekrarlarını engellemiş olur.Şimdi farklı tablolara bölünmüş datalar üzerinde
işlem yapmamız gerekirse ne yapmamız gerekir.Aslında fazla bir şey yapmamız
gerekmez.Tek yapacağımız hangi tabloları kullanacaksak bunları from cümleceğinde
belirtmemizdir.Tabloları belirtirken aralarında , koymayı unutmazsak o zaman
sorun yok. Örnek 1 : Hangi personelin ne kadar maaş aldığını
listelemek istersek; SELECT
ad,soyad,aylik_ucret FROM personel,ucretler WHERE
sicil_no=per_sicil_no; Örnek
2 : İstanbul'da yaşayan Adana doğumlu personelin maaşlarını listelemek
istersek; SELECT
ad,soyad,aylik_ucret FROM personel,ucretler WHERE
sicil_no=per_sicil_no AND adres LIKE '%İstanbul%' AND dogum_yeri =
'Adana'; Örnek
3 : 300 milyondan fazla maaş alan ve 2 nolu meslek grubuna ait personeli
listelemek istersek; SELECT
ad,soyad,aylik_ucret FROM personel,ucretler WHERE
sicil_no=per_sicil_no AND aylik_ucret>300000000 AND
meslek_id=2; Örnek
4 : Muhasebe meslek grubuna ait personel listesi; SELECT
ad,soyad FROM
personel,meslekler WHERE meslek_id=meslek_id AND
meslek_aciklama='Muhasebe';
Şimdi
buradaki sorgulamımızda bir karışıklık söz konusu olacak.İki tane aynı isimde
meslek_id oldu.Bunu şu şekilde engelleyebiliriz. Tablolarda aynı isimde iki
kolon varsa bu kolanları kullanırken başlarıda tablo ismini getiririz araya bir
nokta koyarak kolon adını yazarız. SELECT
ad,soyad FROM
personel,meslekler WHERE personel.meslek_id=meslekler.meslek_id AND meslek_aciklama='Muhasebe'; Örnek
5 : Şirketimizde 30 yıldır çalışan ve 200 milyon altında maaş alan
personeli ödüllendirecegiz. Bunun için nasıl bir sorgulama
yapmalıyız. SELECT
ad,soyad FROM
personel,ucretler WHERE sicil_no=per_sicil_no AND
baslama_tarihi < '01.01.1969' AND aylik_ucret <
200000000; Örnek
6 : 22 yaşından büyük bilgi işlemde çalışan bayan personeli listelemek
istersek (NOT : cinsiyet= 0 : bayan 1 : erkek medeni_hal= 0 : bekar 1 :
evli ) SELECT
ad,soyad FROM
personel,meslekler WHERE personel.meslek_id=meslekler.meslek_id
AND meslek_aciklama='Bilgi İşlem' AND cinsiyet=0 AND dogum_tarihi
< '01.01.1977'; Örnek
7 : 40 yaşından küçük ,bilgi işlem veya muhasebe bölümünde
çalışan,erkek,200 milyondan fazla maaş alan ,Ankara doğumlu ,Sarıyer'de
oturan,10 yıldan fazla şirkette çalışan , bekar ,10 milyondan fazla kesinti
yapılan personeli listelemek istersek; SELECT
ad,soyad FROM
personel,meslekler,ucretler WHERE dogum_tarihi >
'01.01.1959' AND personel.meslek_id=meslekler.meslek_id AND
(meslek_aciklama='Bilgi İşlem' OR meslek_aciklama='Muhasebe') AND
cinsiyet=1 AND sicil_no=per_sicil_no AND aylik_ucret >
200000000 AND dogum_yeri='Ankara' AND adres LIKE '%Sarıyer%' AND
baslama_tarihi > '01.01.1989' AND medeni_hal=0 AND
kesinti>10000000; Örnek
8 : Muhasebe ve Pazarlama bölümü dışında çalışan personeli listelemek
istersek; SELECT
ad,soyad FROM
personel,meslekler WHERE personel.meslek_id=meslekler.meslek_id
AND meslek_aciklama<>'Pazarlama' AND
meslek_aciklama<>'Muhasebe'; Örnek
9 :40 yaşları arasında İzmir ve Bursa doğumlu adayları listelemek
istersek; SELECT
ad,soyad FROM personel WHERE dogum_tarihi BETWEEN
'01.01.1959' AND '01.01.1969' AND (dogum_yeri='İzmir' OR
dogum_yeri='Bursa'); Örnek
10 : Adı E ile başlayan, 3,5 ve 7 nolu meslek grubuna ait ,bayan,bekar,30
yaşından küçük , 100 milyondan fazla maaş alan personel listesi; SELECT
ad,soyad FROM personel,ucretler WHERE ad LIKE 'E%' AND
meslek_id IN (3,5,7) AND cinsiyet=0 AND medeni_hal=0 AND
dogum_tarihi > '01.01.1969' AND sicil_no=per_sicil_no AND
aylik_ücret > 100000000; Örnek
11 : Evli ve aile yardımı almayan persenol listesi; SELECT
ad,soyad FROM personel,ucretler WHERE medeni_hal=1 AND
aile_yardim=0;
SQL
Tablo'dan Kayıt Silmek
Tablodan
bir satır silmek istersek DELETE sözcüğünü kullanırız.Genel kullanım şekli
aşağıdaki biçimdedir ; DELETE FROM tablo
adı
Eğer yukarıdaki gibi bir sorgulama yazıp çalıştırırsak
tablodaki bütün kayıtları sileriz.Bunun için DELETE cümleciğini kullanırken
dikkat edilmelidir. Örnek : Sicil nosu 12345678 olan kayıt
silinmek istenirse; DELETE FROM personel
WHERE sicil_no='12345678'; Örnek
: Doğum tarihi 1940'dan önce doğmuş personel kayıtları silinmek
istenirse ; DELETE FROM personel
WHERE dogum_tarihi<'0';
SQL'de Kayıt Değişikliği
Tablodan bir kayıtı değiştirmek
istersek UPDATE sözcüğünü kullanırız.Genel kullanım şekli aşağıdaki biçimdedir
; UPDATE tablo
adı SET
kolon1=deger1,kolon2=deger2,...WHERE
kosul; Örnek : Sicil nosu 12345678 olan kayıtın
adresi değiştirlmek istenirse; UPDATE
personel SET adres='Bronz Sok.Teşvikiye' WHERE sicil_no='12345678'; Örnek
: Bütün personele uygulanan kesinti ücreti 10.000.000 sabit olarak
belirlenirse; UPDATE ucretler SET
kesinti='10000000'; Örnek
: Bütün personelin maaşına %20 zam yapılırsa; UPDATE ucretler SET
aylik_ucret=aylık_ucret*1.20;
SQL
Gruplama Fonksiyonları
SUM,AVG,MIN,MAX,COUNT(*),COUNT(DISTINCT))
MAX
Verilen
kolondaki en büyük değeri geri döndürür.Genel yazım biçimi aşağıdaki
gibidir; Select MAX(kolon_adı) FROM
tablo; Örnek : En fazla aylık ücret alan personel ne
kadar maaş alıyor? Select
MAX(aylik_ucret) From ucretler; Örnek
: En fazla aile yardımı alan personelin maaş ve sicil no'sunu öğrenmek
istersek; Select
per_sicil_no,MAX(aylik_ucret) From ucretler;
MIN
Verilen kolondaki en küçük değeri geri döndürür.Genel yazım biçimi
aşağıdaki gibidir; Select MIN(kolon_adı) FROM
tablo; Örnek : En düşük aylık ücret alan personel ne
kadar maaş alıyor ? Select
MIN(aylik_ucret) From ucretler; Örnek : En
az aile yardımı alan personelin maaşını ve sicil no'sunu öğrenmek istersek;
Select
per_sicil_no,MIN(aylik_ucret) From ucretler;
SUM
Verilen kolondaki Bütün değerleri toplayarak geri döndürür.Genel
yazım biçimi aşağıdaki gibidir; Select
SUM(kolon_adı) FROM tablo; Örnek : Personele ödenen
toplam ücret nedir ?
Select
SUM(aylik_ucret) From ucretler; Örnek :
Toplam ödenen aile yardımı bulunmak istenirse, Select
SUM(aile_yardimi) From ucretler;
AVG
Verilen kolondaki değerlerin aritmetiksel ortalamsını geri döndürür.Genel yazım biçimi aşağıdaki gibidir; Select
AVG(kolon_adı) FROM tablo; Örnek : Aylık ödenen ücret
ortalamasını bulmak istersek;
Select
AVG(aylik_ucret) From ucretler;
COUNT(*)
Verilen tablodaki record sayısını geri döndürür.Genel yazım biçimi
aşağıdaki gibidir ; Select COUNT(*) FROM
tablo; Örnek : Kaç tane personel çalıştığını
listelenmek istersek;
Select COUNT(*) From
personel;
COUNT(DISTINCT ..)
Verilen kolondaki unique record sayısını geri döndürür.Genel yazım
biçimi aşağıdaki gibidir ; Select COUNT(DISTINCT
kolon_adı) FROM tablo; Örnek : İsmi farklı kaç tane
personel çalıştığını listelenmek istenirse;
Select
COUNT(DISTINCT ad) From personel; Örnek 1: En
yüksek taban ücret olan meslek listelenmek istenirse; Select
MAX(taban_ücret) From meslekler; Örnek
2: Ortalama taban ücret listelenmek istenirse;
Select
AVG(taban_ücret) From meslekler; Örnek
3: 30.01.1990 yılından sonra işe başlıyanların ortalama ücreti
hesaplanmak istenirse;
Select
AVG(aylik_ücret) From ucretler Where
baslama_tarihi>'30.01.1990'; Örnek
4: Maaşından kesinti yapılan personele ödenen toplam ücret bulunmak
istenirse; Select
SUM(aylik_ücret) From ucretler Where
kesinti>0;
ÖZET (ÖRNEKLER)
En çok kullanılan
Fonksiyonlar
Karakter Ayırma SUBSTR(Kolon/Değer,Başlangıç,karekter
sayısı) SELECT SUBSTR('ORACLE',2.4)
BOLUM,SUBSTR(ADI,3,5) İSİM FROM Pers; Bolumİsim
RACL
HMET İki Tarih
arasında Kalan Ay sayını belirleme: MONTHS_BETWEEN(Tarih1,Tarih2) SELECT MONTHS_BETWEEN(SYSDATE,'05/05/1999')
FROM DUAL;
SELECT MONTHS_BETWEEN(SYSDATE,'05/05/1999')
11,21763 Bir Tarih Üzerine Ay Ekleme: SELECT HIREDATE.ADD_MONTHS(HIREDATE,3) FROM
PERSONEL WHERE BOLUM=20; HIREDATE ADD_MONTHS
02/04/1981
02/07/1981 Karakter Tipindeki veriyi verilen Formata
göre Dönüştürme: SELECT TO_CHAR(SYSDATE,'DD MONTH YYYY') TARIH
TO_CHAR(12000000,'999.999.999.999') SAYI FROM DUAL; TARİH SAYI
29 MAYIS 1998
1.200.000.000 SELECT TO_DATE('05/03/2004','DD-MM-YYYY' FROM
DUAL; TARİH
05-03-2004 Bir sütundaki Değerlerin Sayısını Bulma: SELECT COUNT(*) TOPLAM FROM PERS WHERE
BOLUM=20; TOPLAM
125 İki Tablonun Birleştirilmesi: SELECT ADI,ISI,BOLUMAD FROM PERS,SICIL WHERE
PERS.SICILNO=SICIL.SICILNL; ADIISIBOLUM
MEHMET MEMUR
BIM
AHMET SEF MUHASEBE Tablo Yapısını Değiştirme: ALTER TABLE PERS ADD (SPOUSEDS_ADI
VARCHAR2(10)); ALTER TABLE PERS MODIFY (ADI VARCHAR2(25)); Tabloya Satır Ekleme: INSERT INTO tablo_adı (Kolon1,Kolon2,...)
VALUES (Değer1,değer2,...); Tablodaki Satırları Günleme: UPDATE tablo_adı SET kolon=value1;Tablodaki Satırları Silme: DELETE FROM tablo_adı (WHERE koşul); Başka Bir Tablonun Kayıtlarını Kullanarak
Tablo Oluşturma: CREATE TABLE TEST AS SELECT BOLUM,ADI,SOYADI,SICIL
FROM PERS WHERE BOLUMNO=30; FROM personel A,personel B