seçme * ile sütun seçme


124

Sadece 2/3 sütuna ihtiyacım olursa ve sorgularım SELECT * bu sütunları seçme sorgusunda sağlamak yerine , daha fazla / daha az G / Ç veya bellekle ilgili herhangi bir performans düşüşü olur mu?

* Gerek kalmadan seçersem ağ ek yükü mevcut olabilir.

Ancak belirli bir işlemde, veritabanı motoru her zaman diskten atomik tuple mı çekiyor yoksa yalnızca seçme işleminde istenen sütunları mı çekiyor?

Her zaman bir demet çekiyorsa, G / Ç ek yükü aynıdır.

Aynı zamanda, bir demet çekerse, istenen sütunları tuple'dan çıkarmak için bir bellek tüketimi olabilir.

Öyleyse, durum buysa, someColumn'un seçilenden daha fazla bellek ek yüküne sahip olacağını seçin *


Sorduğunuz belirli bir RDBMS var mı? SELECTSorguların nasıl yürütüldüğü / işlendiği veritabanından veritabanına farklı olabilir.
Lèse majesté

10
Bir yana, PostgreSQL'de, CREATE VIEW foo_view AS SELECT * FROM foo;daha sonra tablo foo'ya sütunlar ekleyin derseniz , bu sütunlar beklendiği gibi foo_view'da otomatik olarak görünmez. Başka bir deyişle, *bu bağlamda, SELECT başına değil, yalnızca bir kez genişler (görünüm oluşturma zamanında). ALTER TABLE'den kaynaklanan komplikasyonlar nedeniyle, (pratikte) *Zararlı Kabul Edildiğini söyleyebilirim .
Joey Adams

@JoeyAdams - sadece PostgresQL değil, bu aynı zamanda Oracle'ın davranışıdır.
APC

1
@OMG Ponies: Benzer gönderinin farkında değildim. Ancak bunlar gerçekten benzer değil. @ Lèse majesté: Generic RDBMS'den bahsediyorum. belirli bir satıcı hakkında değil @ Joey Adams: Hmm * 'nin güvensiz olduğunu biliyorum. sadece performansla ilgili konuları tartışmak istiyorum.
Neel Basu

Yanıtlar:


31

Her zaman bir demet çeker (tablonun dikey olarak bölümlere ayrıldığı - sütun parçalarına bölündüğü durumlar hariç), bu nedenle sorduğunuz soruyu yanıtlamak performans açısından önemli değildir. Bununla birlikte, diğer birçok nedenden dolayı (aşağıda), her zaman özellikle istediğiniz sütunları ada göre seçmelisiniz.

Her zaman bir demet çeker, çünkü (aşina olduğum her satıcı RDBMS'de), her şeyin temelindeki disk üstü depolama yapısı (tablo verileri dahil), tanımlanmış G / Ç Sayfalarına dayanır (örneğin, SQL Server'da, her Sayfa 8 kilobayt). Ve her G / Ç okuma veya yazma Sayfa'ya göre .. Yani, her yazma veya okuma eksiksiz bir veri Sayfasıdır.

Bu temel yapısal kısıtlama nedeniyle, bir sonuç olarak, bir veritabanındaki her veri satırı her zaman bir ve yalnızca bir sayfada olmalıdır. Birden fazla veri Sayfasına yayılamaz (gerçek blob verilerinin ayrı Sayfa yığınlarında depolandığı ve gerçek tablo satırı sütununun daha sonra yalnızca bir işaretçi aldığı bloblar gibi özel şeyler hariç). Ancak bu istisnalar sadece istisnalardır ve özel durumlar haricinde genellikle geçerli değildir (özel veri türleri veya özel durumlar için belirli optimizasyonlar)
Bu özel durumlarda bile, genellikle, verilerin gerçek tablo satırının kendisi ( Blob için gerçek verilere işaretçi veya her neyse), tek bir GÇ Sayfasında depolanmalıdır ...

İSTİSNA. Uygun olduğu tek yer Select *, aşağıdaki gibi bir Existsveya Not Existsyüklem cümlesinden sonraki alt sorgudadır:

   Select colA, colB
   From table1 t1
   Where Exists (Select * From Table2
                 Where column = t1.colA)

DÜZENLEME: @Mike Sherer yorumuna hitap etmek için, Evet, hem teknik olarak, hem özel durumunuz için hem de estetik olarak biraz tanımla doğrudur. İlk olarak, istenen sütun kümesi bazı dizinde depolananların bir alt kümesi olsa bile, sorgu işlemcisi aynı nedenlerle yalnızca istenenleri değil, o dizinde depolanan her sütunu getirmelidir - TÜM G / Ç, sayfalar ve dizin verileri, tablo verileri gibi IO Sayfalarında saklanır. Dolayısıyla, bir dizin sayfası için "tuple" ı dizinde depolanan sütun kümesi olarak tanımlarsanız, ifade yine de doğrudur.
ve ifade estetik olarak doğrudur çünkü asıl mesele, verileri istediğiniz şeye değil, G / Ç sayfasında depolananlara göre getirmesidir ve bu, temel tablo G / Ç Sayfasına veya bir dizine erişiyor olsanız da geçerlidir. I / O Sayfası.

Kullanmamak için diğer nedenler için Select *bkz. Neden SELECT *zararlı kabul edilir? :


"Her zaman bir demet çeker" emin misin? Hmm Tamam Yani haklıydım. bu durumda, durum aynı G / Ç ek select *yüküne göre daha az bellek ek yüküne sahip olacaktır select column. yani ağ yükünü bırakırsak. select *daha az genel giderselect column
Neel Basu

10
Bu doğru değil. Kafamın tepesinden bir örnek, MySQL'de yalnızca indekslenmiş bir sütunun değerini istediğinizde (örneğin, yalnızca satır varlığını kontrol etmek için) ve MyISAM depolama motorunu kullanıyorsanız, verileri MYI dosyası, bellekte olabilir ve diske bile gitmez!
Mike Sherov

Ya, eğer istenen tuple kümesi bellekteyse, G / Ç olmayacaktır ama bu özel bir durumdur. Peki yazlık nedir? Dizine alınmış bir Sütun seçersem, tüm demet okunmaz mı? aksi takdirde tüm demet okunur?
Neel Basu

MySql'in önbelleğe alma işlemini nasıl yaptığından tam olarak emin değilim, ancak SQL Server ve Oracle'da, veriler bellek içi önbellekte olsa bile, diskten erişirken olduğu gibi aynı Sayfa yapısını kullanarak ona erişmeye devam ediyor. Bu, veri sayfası başına bir bellek G / Ç gerektireceği anlamına gelir ... tam olarak diskte olduğu gibi. (bellek G / Ç'lerinin elbette Disk G / Ç'lerinden çok daha hızlı olması dışında). Aslında bu, önbelleğe alma tasarımının amacı, erişim sürecini verilerin konumu konusunda tamamen bağımsız kılmaktır.
Charles Bretana

2
"Diğer birçok nedenden dolayı" daha fazla heceleyebilir misin? Çünkü bunlar benim için net değildi. Performans önemli değilse, neden sütun adları istemekle ilgilenesiniz?
Dennis

111

SELECT *Üretim kodunda asla (asla) kullanmamanızın birkaç nedeni vardır :

  • Veritabanınıza ne istediğinize dair herhangi bir ipucu vermediğiniz için, o tablodaki sütunları belirlemek için önce tablonun tanımını kontrol etmesi gerekecektir. Bu arama biraz zamana mal olacak - tek bir sorguda çok fazla değil - ama zamanla artıyor

  • sütunların yalnızca 2 / 3'üne ihtiyacınız varsa, 1 / 3'ünde çok fazla veri seçiyorsunuz, bu da diskten alınması ve ağ üzerinden gönderilmesi gerekiyor

  • Verinin belirli yönlerine güvenmeye başlarsanız, örneğin döndürülen sütunların sırası, tablo yeniden düzenlendikten ve yeni sütunlar eklendiğinde (veya var olanlar kaldırıldığında) kötü bir sürprizle karşılaşabilirsiniz.

  • SQL Server'da (diğer veritabanları hakkında emin değil), bir sütun alt kümesine ihtiyacınız varsa, her zaman kümelenmemiş bir dizinin bu isteği karşılama ihtimali vardır (gerekli tüm sütunları içerir). A ile SELECT *, bu olasılıktan en başından vazgeçiyorsunuz. Bu özel durumda, veriler dizin sayfalarından (eğer bunlar gerekli tüm sütunları içeriyorsa) alınır ve dolayısıyla disk G / Ç ve bellek ek yükü, bir SELECT *....sorgu yapmaya kıyasla çok daha az olur .

Evet, başlangıçta biraz daha fazla yazmayı gerektirir ( SQL Server için SQL İstemi gibi araçlar size yardımcı olacaktır) - ancak bu gerçekten istisnasız bir kuralın olduğu bir durumdur: üretim kodunuzda asla SELECT * kullanmayın. HİÇ.


13
Pratikte sizinle hemfikir olmanıza rağmen, tablodan sütun verilerini alırken kesinlikle haklısınız, bu soru ele alındığı için), yine de EVER'e yapılan vurgu, bu kuralların TÜM Sql sorguları için genel olmadığını belirtmeme neden oluyor .. Özellikle, bir EXISTS yükleminden sonra bir alt sorguda kullanılması (olduğu gibi Where Exists (Select * From ...) Select *kesinlikle sorun değildir ve bazı çevrelerde en iyi uygulama olarak kabul edilir.
Charles Bretana

3
@Charles Bretana: evet, bu IF EXISTS(SELECT *...özel bir durum - çünkü hiçbir veri gerçekten alınmıyor , ancak bu sadece bir varlığın kontrolü, SELECT * orada bir sorun değil ...
marc_s

1
Tablolarımdan birinden veri almayı mümkün kılan bir API geliştiriyorsam ne olacak? Kullanıcının hangi verilerle ilgilendiğini bilmediğim için, SELECT * 'in kabul edilebilir olacağını varsayıyorum?
Simon Bengtsson

1
@SimonBengtsson: Yine de buna karşı çıkıyorum - tablonuzdaki belirli sütunlarda müşteriye göstermek istemediğiniz bazı "idari" verileriniz olduğunu varsayalım. Her zaman açıkça alınacak sütunların bir listesini belirtirdim
marc_s

1
Bu doğru. API ile kullanılmak üzere özel olarak ayarlanmış bir görünümü sorgularken ne olacak?
Simon Bengtsson

21

Her zaman yalnızca selectgerçekten ihtiyacınız olan sütunları kullanmalısınız. Daha çok yerine daha azını seçmek hiçbir zaman daha az verimli değildir ve ayrıca daha az beklenmedik yan etkiyle karşılaşırsınız - örneğin, istemci tarafında sonuç sütunlarınıza indeksle erişmek, ardından tabloya yeni bir sütun ekleyerek bu dizinlerin yanlış hale gelmesini sağlamak gibi.

[değiştir]: Erişim anlamına geliyor. Aptal beyin hala uyanıyor.


3
İlk bakışta pek kimsenin düşünmeyeceğini düşündüğüm uç durum için +1 - istemci tarafında dizinler ve sütunlar eklendi / değiştirildi.
Tomas Aschan

1
Evet, ancak sütunlar için sayısal endeksler bu kadar yaygın mı? ORM kullanıyorsanız, sütun verilerine her zaman dize anahtarlarını veya özellik adlarını kullanarak eriştim.
Lèse majesté

11
bunu uzun zaman önce görmüş, genç programcı bir tablodan * seçmiş ve sütun sırası hakkında varsayımlarda bulunmuştur; bir başkası masayı değiştirir değiştirmez tüm kodu bozuldu. Ne kadar eğlendik.
Paul McKenzie

7
Genel olarak yalnızca kod okunabilirliği uğruna sütun sırasını kullanmak muhtemelen kötü bir fikirdir SELECT *, onunla kullanmak iki kat daha kötüdür .
Lèse majesté

2
Vay canına, istemci kodundaki indekse göre sütunlara erişmek olağanüstü derecede kötü bir fikir gibi görünüyor . Bu nedenle, sütunların bir sonuç kümesinde görünme sırasına güvenmek, herhangi bir şekilde bana çok kirli geliyor.
Matt Peterson

7

Büyük lekeler depolamadığınız sürece performans bir sorun teşkil etmez. SELECT * 'i kullanmamanın en büyük nedeni, döndürülen satırları tuple olarak kullanıyorsanız, sütunların şemanın belirttiği sırayla geri gelmesi ve bu değişirse tüm kodunuzu düzeltmeniz gerekmesidir.

Öte yandan, sözlük tarzı erişim kullanıyorsanız, sütunların hangi sırayla geldiği önemli değildir çünkü onlara her zaman adıyla erişiyorsunuz.


6

Bu hemen aklıma kullandığım bir sütun türü içeren bir tablo getiriyor blob; genellikle birkaç Mbs boyutunda bir JPEG resmi içeriyordu .

Söylemeye gerek yok, gerçekten ihtiyacım SELECTolmadıkça o köşeyi yapmadım . Bu verilerin etrafta dolaşması - özellikle birden çok satır seçtiğimde - sadece bir güçlüktü.

Ancak, normalde bir tablodaki tüm sütunları sorguladığımı itiraf edeceğim.


20
LOB sütunları her zaman SELECT * tehlikelerinin en sevdiğim örneğidir. Bu yüzden, üçüncü paragrafı okuyana kadar size olumlu oy verecektim. Cık, cık. Başka bir geliştirici, şu anda böyle bir sütuna sahip olmayan bir tabloya bir BLOB eklerse ne olur?
APC

1
@APC, keşke yorumunuzu daha fazla yükseltebilseydim. Büyük bir performans düşüşüne neden olmadan bir sütun eklemek isteyen zavallı iş arkadaşınızı düşünün! Birkaç saat sonra masum görünümlü seçiminizi keşfettiklerinde ne kadar kızacaklarını bir düşünün *.
Mike Sherov

1
@ user256007, evet, BLOB olmasa bile ... BLOB uç bir örneği gösteriyor. Charles'a cevabımı kontrol edin, belirli sütunları seçmenin, verileri diske bile gitmeden bellekten almanızı sağlayabileceği zamanlar vardır!
Mike Sherov

1
@Richard, bence DB performansını optimize etmek için harika olduklarını düşünüyorum, bu da zamanın% 99'u olan ana endişeniz değil. Çoğu çerçevede olduğu gibi, saf performanstan ödün verirken daha hızlı geliştirme sağlamak için işleri genelleme eğilimindedirler. Knuth'un dediği gibi: "Erken optimizasyon, tüm kötülüklerin köküdür." Seçili sütunların performansı ile seçme * arasındaki performans konusunda endişelenmeniz gereken noktaya geldiğinizde (Twitter'a RoR hakkında sorun) bunun için endişelenebilir ve daha sonra optimize edebilirsiniz. Çerçeve bunu destekleyecek kadar sağlam değilse, yanlış çerçeveyi kullandığınızı söyleyebilirim.
Mike Sherov

1
@ user256007 - genel kural "SELECT * kullanmayın" dir. marc_s'nin cevabı, durumun neden böyle olduğuna dair tüm açıklamaları içerir.
APC

6

Bir SQL seçimi sırasında, DB SELECT a, b, c ... için SELECT * olup olmadığına bakılmaksızın her zaman tablonun meta verilerine başvuracaktır. Neden? Çünkü sistemdeki tablonun yapısı ve düzeni hakkındaki bilgiler burada.

Bu bilgileri iki nedenle okuması gerekir. Bir, basitçe ifadeyi derlemek için. En azından mevcut bir tabloyu belirttiğinizden emin olması gerekir. Ayrıca, bir ifadenin son çalıştırılmasından bu yana veritabanı yapısı değişmiş olabilir.

Şimdi, tabii ki, DB meta verileri sistemde önbelleğe alındı, ancak yapılması gereken hala işleniyor.

Ardından, meta veriler sorgu planını oluşturmak için kullanılır. Bu, bir ifade her derlendiğinde de olur. Yine, bu önbelleğe alınmış meta verilere karşı çalışır, ancak her zaman yapılır.

Bu işlemin yapılmadığı tek zaman, DB'nin önceden derlenmiş bir sorgu kullandığı veya önceki bir sorguyu önbelleğe aldığı zamandır. Bu, değişmez SQL yerine bağlama parametrelerini kullanma argümanıdır. "SEÇ * TABLEDEN NEREDE anahtar = 1" sorgudan farklı bir sorgu "SEÇ * TABLEDEN NEREDE anahtar =?" ve "1" çağrıya bağlıdır.

DB'ler orada çalışmak için sayfa önbelleğe alma işlemine büyük ölçüde güvenir. Çoğu modern DB, belleğe tamamen sığacak kadar küçüktür (veya, belki de modern belleğin birçok DB'ye uyacak kadar büyük olduğunu söylemeliyim). Ardından, arka uçtaki birincil G / Ç maliyetiniz günlüğe kaydetme ve sayfa temizlemedir.

Bununla birlikte, hala DB'niz için diske vuruyorsanız, birçok sistem tarafından yapılan birincil optimizasyon, tabloların kendileri yerine dizinlerdeki verilere güvenmektir.

Eğer varsa:

CREATE TABLE customer (
    id INTEGER NOT NULL PRIMARY KEY,
    name VARCHAR(150) NOT NULL,
    city VARCHAR(30),
    state VARCHAR(30),
    zip VARCHAR(10));

CREATE INDEX k1_customer ON customer(id, name);

Sonra "SELECT id, name FROM customer WHERE id = 1" yaparsanız, DB'niz bu verileri tablolardan değil dizinden çekmeniz çok olasıdır.

Neden? Sorguyu tatmin etmek için muhtemelen dizini kullanacaktır (tablo taramasına karşı) ve where cümlesinde 'ad' kullanılmasa da, bu dizin yine de sorgu için en iyi seçenek olacaktır.

Artık veritabanı sorguyu karşılamak için ihtiyaç duyduğu tüm verilere sahiptir, bu nedenle tablo sayfalarını kendilerinin vurması için bir neden yoktur. Dizinin kullanılması, genel olarak tabloya kıyasla dizinde daha yüksek bir satır yoğunluğuna sahip olduğunuzdan daha az disk trafiği ile sonuçlanır.

Bu, bazı veritabanları tarafından kullanılan belirli bir optimizasyon tekniğinin el dalgalı bir açıklamasıdır. Birçoğunun birkaç optimizasyon ve ayarlama tekniği vardır.

Sonunda, SELECT * elle yazmanız gereken dinamik sorgular için kullanışlıdır, "gerçek kod" için asla kullanmam. Tek tek sütunların tanımlanması, DB'ye sorguyu optimize etmek için kullanabileceği daha fazla bilgi verir ve şema değişikliklerine vb. Karşı kodunuzda size daha iyi kontrol sağlar.


Will, sırf PRIMARY KEY ile birlikte NOT NULL kullanıyorsun diye cevabını reddettim. Bu şekilde yazmanız için iyi bir neden var mı?
Öğrenci

4

Bence sorunuzun kesin bir cevabı yok, çünkü düşünen bir performansa ve uygulamalarınızın bakımını yapma olanağına sahipsiniz. Select columndaha performanslı select *, ancak odaklı bir nesne sistemi geliştiriyorsanız, o zaman kullanımı seveceksiniz object.propertiesve uygulamaların herhangi bir bölümünde bir özelliğe ihtiyacınız olabilir, o zaman özel durumlarda özellik elde etmek için daha fazla yöntem yazmanız gerekecektir. select *tüm özellikleri kullanın ve doldurun. Uygulamalarınızın kullanımının iyi bir performansa sahip olması gerekir select *ve bazı durumlarda performansı artırmak için seçme sütununu kullanmanız gerekir. O zaman, performansa ihtiyaç duyduğunuzda uygulamaları yazma ve sürdürme olanağına ve performansa sahip iki dünyanın en iyisine sahip olacaksınız.


4

Burada kabul edilen cevap yanlış. Bununla karşılaştım, başka bir soru bunun kopyası olarak kapatıldığında (hala cevabımı yazarken - grr - bu nedenle aşağıdaki SQL diğer soruya atıfta bulunuyor).

Her zaman SELECT özniteliğini, özniteliği kullanmalısınız ... SEÇMEYİN *

Öncelikle performans sorunları içindir.

Kullanıcılardan bir isim seçin WHERE name = 'John';

Çok faydalı bir örnek değil. Bunun yerine düşünün:

SELECT telephone FROM users WHERE name='John';

(İsim, telefon) üzerinde bir dizin varsa, tablodan ilgili değerlere bakmaya gerek kalmadan sorgu çözülebilir - bir kaplama indeksi vardır.

Ayrıca, tablonun kullanıcının bir resmini ve yüklenmiş bir CV'yi içeren bir BLOB'a sahip olduğunu ve SELECT * kullanan bir elektronik tablonun tüm bu bilgileri DBMS arabelleklerine geri çekeceğini varsayın (diğer yararlı bilgileri önbellekten dışarı atmaya zorlar). Daha sonra bunların tümü, gereksiz veriler için ağdaki çalışma süresi ve istemcideki bellek kullanılarak istemciye gönderilecektir.

İstemci verileri numaralandırılmış bir dizi olarak alırsa (PHP'nin mysql_fetch_array ($ x, MYSQL_NUM) gibi) işlevsel sorunlara da neden olabilir. Belki kod yazıldığında 'telefon' SELECT * tarafından döndürülecek üçüncü sütundu, ancak daha sonra birisi gelir ve masaya 'telefon'dan önce konumlandırılan bir e-posta adresi eklemeye karar verir. İstenilen alan şimdi 4. sütuna kaydırılmıştır.


2

Her iki şekilde de yapmak için sebepler var. PostgreSQL'de SELECT * 'i çok kullanıyorum çünkü PostgreSQL'de SELECT * ile yapabileceğiniz, özellikle de saklı yordamlarda açık bir sütun listesiyle yapamayacağınız pek çok şey vardır. Benzer şekilde, Informix'te, miras alınan bir tablo ağacı üzerindeki SELECT * size pürüzlü satırlar verebilirken, açık bir sütun listesi, alt tablolardaki ek sütunlar da döndürüldüğünden bunu yapamaz.

Bunu PostgreSQL'de yapmamın ana nedeni, bir tabloya özgü iyi biçimlendirilmiş bir tür elde etmemi sağlamasıdır. Bu, sonuçları alıp PostgreSQL'de tablo türü olarak kullanmamı sağlıyor. Bu ayrıca, sorguda katı bir sütun listesinden çok daha fazla seçeneğe izin verir.

Öte yandan, katı bir sütun listesi size db şemalarının belirli şekillerde değişmediğine dair uygulama düzeyinde bir kontrol sağlar ve bu yardımcı olabilir. (Bu tür kontrolleri başka bir düzeyde yaparım.)

Performans gelince, VIEW'leri ve türleri döndüren saklı yordamları (ve ardından saklı yordamın içindeki bir sütun listesini) kullanma eğilimindeyim. Bu, hangi türlerin döndürüleceğini kontrol etmemi sağlıyor.

Ancak SELECT * 'i genellikle temel tablolardan ziyade bir soyutlama katmanına karşı kullandığımı unutmayın.


2

Bu makaleden alınan referans:

SELECT * olmadan: O anda ”SELECT *” i kullandığınızda, veritabanından daha fazla sütun seçersiniz ve bu sütunun bir kısmı uygulamanız tarafından kullanılmayabilir. Bu, veritabanı sisteminde ekstra maliyet ve yük oluşturacak ve ağda daha fazla veri dolaşımı sağlayacaktır.

SELECT * ile: Özel gereksinimleriniz varsa ve sütun ekleme veya silme işlemi sırasında dinamik ortam oluşturduysanız, uygulama koduna göre otomatik olarak işlenir. Bu özel durumda, uygulama ve veritabanı kodunu değiştirmeniz gerekmez ve bu, üretim ortamını otomatik olarak etkileyecektir. Bu durumda “SEÇ *” i kullanabilirsiniz.


0

Burada görmediğim tartışmaya bir nüans eklemek için: G / Ç açısından, sütun odaklı depolamaya sahip bir veritabanı kullanıyorsanız yalnızca belirli bir sorgu yaparsanız çok daha az G / Ç yapabilirsiniz. sütunlar. SSD'lere geçtikçe, faydalar satır odaklı depolamaya göre biraz daha küçük olabilir, ancak a) yalnızca ilgilendiğiniz sütunları içeren blokları okumak b) genellikle diskteki verilerin boyutunu büyük ölçüde azaltan sıkıştırma ve dolayısıyla diskten okunan veri hacmi.

Sütun tabanlı depolamaya aşina değilseniz, Postgres için bir uygulama Citus Data'dan gelir, diğeri Greenplum, başka bir Paraccel, diğeri (gevşek bir şekilde konuşursak) Amazon Redshift'tir. MySQL için Infobright, hemen hemen feshedilen InfiniDB var. Diğer ticari teklifler arasında HP'den Vertica, Sybase IQ, Teradata ...


-1
select * from table1 INTERSECT  select * from table2

eşit

select distinct t1 from table1 where Exists (select t2 from table2 where table1.t1 = t2 )

Lütfen kodunuzu vurgulayıp Ctrl + K
WhatsThePoint
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.