Alt sorgular 'takma adlar, ana sorgular ile aynı' takma adları


23

Takma adları alt sorgunun diğer adlarıyla aynı olan bir SQL sorgusu var.

Örneğin:

select *
from ROOM r
where ...
         (
              select *
              from ROAD r
              where ...
         )

Bu iyi çalışıyor, alt sorgunun takma adı ana olanı gizliyor gibi görünüyor.

  1. Her durumda bu şekilde çalışır mı?
  2. Hiç tanımsız sonuç alacak mıyım?
  3. Bunu yapmakta sorun olmazsa, ana sorgunun referansına nasıl başvurabilirim r?

1
Kısa cevaplar "1.Evet", "2.Hayır" ve "3.Hayır, bu durumda, yapamazsınız (bu yüzden böyle bir referans yapmak istiyorsanız gerçekten sorun değil)"
ypercubeᵀᴹ

Yanıtlar:


15

Yuvalanmış alt sorguların üst sorguda kullanılan diğer takma adları kullanması tamamdır, ancak kodu okuyan biri için biraz kafa karıştırıcı olabilir. Yuvalanmış bir alt sorgudaki diğer adların ad alanı ebeveyn üzerindeki ad alanından ayrıdır. Örneğin, aşağıdaki sorguda b, biçinde kullanılan bir diğer adı da içeren iç içe bir alt sorgu var . Bu, programlayıcı için potansiyel olarak kafa karıştırıcı olabilir, ancak DBMS motoruyla iyi olurdu:

   select a.foo
          ,b.bar
          ,b.BarCount
      from (select b.bar
                  ,count (*) as BarCount
              from BarTable b
              join OtherTable o
                on b.OtherTableID = o.OtherTableID
             group by b.bar) b
      join Foobar a
        on a.bar = b.bar

İlişkili bir alt sorguda ebeveynin diğer adına erişiminiz vardır, bu nedenle diğer adın üst sorguda ve ilişkili alt sorguda benzersiz olması gerekir. Aşağıdaki gibi bir ilişkili alt sorgu alırsak, ana sorgu ile ilişkili alt sorgu arasında paylaşılan tek, genel bir ad alanımız vardır:

select a.foo
      ,b.bar
  from Foobar a
  join Bar b
    on b.FooBarID = a.FooBarID
 where not exists
       (select 1
          from Bar b2
         where b2.BarCategoryID = b.BarCategoryID
           and b2.BarDate > b.BarDate)

Korelasyonlu alt sorgu 1 gibi bir birleşme işlemine katılmadığından bir diğer adı yoktur . Başvurular bve hem de alt sorgu b2için barkullanılabilir, çünkü ilişkili alt sorgular üst ad ile takma adlar için ad alanlarını paylaşır.


1 Belirtilen asıl işlem, iç içe geçmiş bir alt sorguya karşı birleştirme değil, ilişkili bir alt sorgu olmasına rağmen, en iyileştiricinin sahnelerin arkasındaki plandaki birleştirme işleçlerini kullanmayı seçebileceğini unutmayın.


İlk sorgudaki alt sorgu türetilmiş bir tablodur ve standart SQL her zaman bir ad verilmesini gerektirir: bu gereksinim için mantıklı bir neden yoktur, ancak SQL Server bunu yine de uyguladı, ancak belirli bir örnekte bir ad seçtiyseniz gereklidir. İkinci sorgudaki alt sorgu türetilmiş bir tablo değildir, bu nedenle neden bir ad gerektirmez ( ilişkili bir alt sorgu olması önemsizdir).
birgün,

@ onedaywhen - Herhangi bir durum düşünemiyorum, ancak alt sorgunun ebeveynde kullanılan diğer adlara erişmesi gereken ilişkili bir alt sorgu. Aklında belirli bir şey var mı?
ConcOedOfTunbridgeWells

Sorunu anladığımdan emin değilim. Belki de yorumunuza özel olarak cevap verdiğimi açıkça belirtmeliyim, "İlişkili alt sorgu, böyle bir birliğe katılmayacağından başka bir takma adı yoktur." Cevabımın, değişkenler ile ilgili kuralların (SQL standardının 'korelasyon isimleri ne diyorsunuz ve' takma isimler 'dediği), katılımlara (veya başka şekilde) katılımlarla doğrudan ilgili olmadığı noktasını aktarması gerekiyordu.
birgün,

Basit örnek: SELECT * FROM ( SELECT c FROM T ) AS T2;- birleşme yok, korelasyon yok ancak SQL standardı türetilmiş tablonun bir aralık değişkeni ( T2bu durumda) atanmasını gerektiriyor .
birgün,

3

EndişeliOfTunbridgeWells, yazıyorsunuz (benimkine vurgu yapıyorsunuz): "İlişkili bir alt sorguda ebeveynin diğer adlarına erişiminiz vardır, bu nedenle diğer adın üst sorguda ve ilişkili alt sorguda benzersiz olması gerekir ."

Özgünlüğün gerekli olduğuna inanmıyorum. Bir takma adın korelasyon adı olarak ilişkilendirilmiş bir alt sorguda kullanılmasının yanı sıra dış sorgudaki tablo takma adının kullanılması durumunda, alt sorgudaki takma adın öncelik alacağına inanıyorum.

Örnek:

CREATE TABLE #T (A INT)
CREATE TABLE #U (A INT)
CREATE TABLE #V (A INT)

INSERT INTO #T (A) VALUES (1), (2), (3)
INSERT INTO #U (A) VALUES (2), (3), (4)
INSERT INTO #V (A) VALUES (3), (4), (5)

SELECT
    T1.A
FROM
    #T AS T1
    INNER JOIN #U AS T2 ON T1.A = T2.A
WHERE
    EXISTS (SELECT * FROM #V AS T2 WHERE T1.A = T2.A)

Çıktı "3" dir: T ve U tabloları ortak 2 ve 3'tür, ancak WHEREbelirteç daha sonra 3'e dönen satırları filtreler ve 2 V'de yoktur.

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.