Postgres'te [FROM x, y] ne anlama geliyor?


12

Postgres ile yeni başlıyorum. Okuma Bu belgeyi ben bu sorgu rastladım:

SELECT title, ts_rank_cd(textsearch, query) AS rank
FROM apod, to_tsquery('neutrino|(dark & matter)') query
WHERE query @@ textsearch
ORDER BY rank DESC
LIMIT 10;

Ben, bu sorguda her şeyi anlayabiliyorum dışında bunun için: FROM apod, ....

Bu ne anlama ,geliyor? Ben katılmak için alışkınım ama FROMvirgülle ayrılmış birden fazla ifadeye değil .

İnternette boşuna arama yaptım. Ona bakıp düşündükten sonra bana öyle geliyor ki, sorgu adı verilen bir değişkeni bildiriyor, böylece onu birden çok kez kullanabiliyor. Fakat bu doğruysa, bununla ne ilgisi var FROM?

Yanıtlar:


10

Bir örtük oluşturur CROSS JOIN. SQL-89 sözdizimidir.

Burada kullandığım values(1)ve values(2)sadece örnekler için pseduo-tablolar (değer tablolar) oluşturun. Onlardan sonra gelen t(x)ve FROM-Diğer Adlarıg(y) olarak adlandırılan parantez içindeki karakter sütun ( ve sırasıyla) için diğer addır . Bunu test etmek için kolayca bir tablo oluşturabilirsiniz.xy

SELECT *
FROM (values(1)) AS t(x), (values(2)) AS g(y)

Şimdi nasıl yazacağınız.

SELECT *
FROM (values(1)) AS t(x)
CROSS JOIN (values(2)) AS g(y);

Oradan INNER JOINbir koşul ekleyerek bunu örtük yapabilirsiniz .

SELECT *
FROM (values(1)) AS t(x)
CROSS JOIN (values(1)) AS g(z)
WHERE x = z;

Veya açık ve yeni INNER JOINsözdizimi,

SELECT *
FROM (values(1)) AS t(x)
INNER JOIN (values(1)) AS g(z)
  ON ( x = z );

Yani örneğinizde ..

FROM apod, to_tsquery('neutrino|(dark & matter)') query

Bu aslında daha yeni sözdizimiyle aynı,

FROM apod
CROSS JOIN to_tsquery('neutrino|(dark & matter)') AS query

bu aslında aynıdır, çünkü bu durumda to_tsquery()bir satır değil , bir satır döndürür,

SELECT title, ts_rank_cd(
  textsearch,
  to_tsquery('neutrino|(dark & matter)')
) AS rank
FROM apod
WHERE to_tsquery('neutrino|(dark & matter)') @@ textsearch
ORDER BY rank DESC
LIMIT 10;

Bununla birlikte, yukarıdakiler potansiyel olarak to_tsquery('neutrino|(dark & matter)')iki kez ortaya çıkabilir, ancak bu durumda - STABLE (ile doğrulandı ) to_tsqueryolarak işaretlenir .\dfS+ to_tsquery

STABLE, işlevin veritabanını değiştiremediğini ve tek bir tablo taramasında aynı bağımsız değişken değerleri için sürekli olarak aynı sonucu döndüreceğini, ancak sonucunun SQL deyimleri arasında değişebileceğini belirtir. Bu, sonuçları veritabanı aramalarına, parametre değişkenlerine (geçerli saat dilimi gibi), vb. Bağlı olan işlevler için uygun seçimdir. (Geçerli komut tarafından değiştirilen satırları sorgulamak isteyen AFTER tetikleyicileri için uygun değildir.) Ayrıca current_timestamp işlev ailesi, değerleri bir işlem içinde değişmediği için kararlı olarak nitelendirilir.

SQL-89 ve SQL-92 arasındaki farkların daha eksiksiz bir karşılaştırması için, ayrıca buradaki yanıma da bakın


Çok teşekkür ederim. Sadece SQL ile başlıyorum. Sadece ,Kartezyen bir ürün olduğu ve karşılaştırma yapılmadığı için çapraz birleştirme olması mantıklıdır . Sadece 1 soru daha cevaplayabilir misiniz LÜTFEN? ne t(x)de (values(1)) AS t(x)???
andrerpena

@andrerpena güncellendi.
Evan Carroll

1
sen en iyisin. Kristal netliğinde açıklama. Bir ton teşekkürler.
andrerpena

Bir tablo diğer adı için "FROM takma ad" terimini hiç duymadım . satır değil, to_tsquery()bir değer döndürür . Bir fonksiyon tanımlanır sırf Ve , bu sorgu planlayıcısı anlamına gelmez olacaktır tekrarlanan değerlendirilmesini kaçının. Bu can . STABLE
Erwin Brandstetter

12

Manuel ayrıntılı açıklaması var içinde virgül FROMlistesindeki bölüm içinde Tablo İfadeler :

FROMMadde virgülle ayrılmış tablo referans listesi verilen bir veya daha fazla başka tablolardan bir tablo türetir.

FROM table_reference [, table_reference [, ...]]

Tablo başvurusu, bir tablo adı (muhtemelen şema nitelemeli) veya bunların alt sorgusu, JOINyapısı veya karmaşık kombinasyonları gibi türetilmiş bir tablo olabilir . Maddede birden fazla tablo referansı listelenmişse FROM, tablolar çapraz birleştirilir (yani, satırlarının Kartezyen ürünü oluşturulur; aşağıya bakınız).

Virgülle ayrılmış tablo başvurularının SQL standardının açık bir JOINsözdiziminden daha önceki bir sürümünde tanımlanmış olması virgülün yanlış veya eski olmasına neden olmaz . Teknik olarak gerekli olduğu (aşağıya bakın) veya sorgu metnini daha netleştirdiği açık birleştirme sözdizimi kullanın.

Kılavuz tekrar:

FROM T1 CROSS JOIN T2eşdeğerdir FROM T1 INNER JOIN T2 ON TRUE (aşağıya bakınız). Aynı zamanda FROM T1, T2.

Ancak "eşdeğer" aynı anlama gelmez . Kılavuzun notları gibi küçük bir fark var :

Not
Bu ikinci eşdeğerlik, JOINvirgülden daha sıkı bağlandığından , ikiden fazla tablo görüntülendiğinde tam olarak tutulmaz . Örneğin FROM T1 CROSS JOIN T2 INNER JOIN T3 ON conditionaynı değildir FROM T1, T2 INNER JOIN T3 ON condition, çünkü conditionkutu referans T1birinci durumda ancak ikinci.

Bu ilgili soru, farkın uygunluğunu göstermektedir:

Temel olarak, gözleminiz tam olarak doğru:

bana öyle geliyor ki, sorgu olarak adlandırılan bir değişkeni birden çok kez kullanabiliyor.

Herhangi bir işlev FROMlistede "tablo işlevi" olarak kullanılabilir . Ve işlev parametreleri, tüm tablolardan işlevin solundaki sütunlara başvurabilir, çünkü gösterim:

FROM apod, to_tsquery('neutrino|(dark & matter)') query

gerçekten şuna eşittir:

FROM apod CROSS JOIN LATERAL to_tsquery('neutrino|(dark & matter)') AS query

LATERAL sorguları kılavuzu:

Görüntülenen tablo işlevlerinden FROMönce anahtar sözcük gelebilir LATERAL, ancak işlevler için anahtar sözcük isteğe bağlıdır ; işlevin bağımsız değişkenleri her durumda önceki FROM öğeleri tarafından sağlanan sütunlara başvuru içerebilir.

Cesur vurgu benim.

Anahtar kelimeAS tamamen önce opsiyonel gürültüdür tablo diğer adları (olarak karşıt kolon takma adlarına da omit değil tavsiye, ASolası belirsizliklerden kaçınmak için). Daha fazlası ile ilgili cevap:

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.