SQL Spec, EXISTS () içinde GROUP BY gerektiriyor mu?


11

Microsoft şu anda bu sözdizimine izin vermektedir.

SELECT *
FROM ( VALUES (1) ) AS g(x)
WHERE EXISTS (
  SELECT *
  FROM ( VALUES (1),(1) )
    AS t(x)
  WHERE g.x = t.x
  HAVING count(*) > 1
);

GROUP BYBu EXISTSmaddede, ANSI SQL geçerli olmadığına dikkat edin . Yoksa sadece bir uygulama detayını ortaya çıkarıyor mu?

Referans olarak, bu aynı sözdiziminin PostgreSQL'de kullanılmasına izin verilmez.

HATA: "tx" sütunu GROUP BY deyiminde görünmeli veya toplama işlevinde kullanılmalıdır

Ancak bu sözdizimine izin verilir.

SELECT *
FROM ( VALUES (1) ) AS g(x)
WHERE EXISTS (
  SELECT 1  -- This changed from the first query
  FROM ( VALUES (1),(1) )
    AS t(x)
  WHERE g.x = t.x
  HAVING count(*) > 1
);

Ve bu sözdizimine izin verilir.

SELECT *
FROM ( VALUES (1) ) AS g(x)
WHERE EXISTS (
  SELECT *
  FROM ( VALUES (1),(1) )
    AS t(x)
  WHERE g.x = t.x
  GROUP BY t.x  -- This changed from the first query
  HAVING count(*) > 1
);

Soru , @ErikE ile sohbette bir sohbetten kaynaklanıyor

Yanıtlar:


11

SQL 2011 spec buldum ...

Eğer <select list>“*” sadece bulunan <table subquery>hemen içerdiği olduğunu <exists predicate>, daha sonra <select list>bir eşdeğerdir <value expression>keyfi olduğunu <literal>.

Bu *, bu bağlamda keyfi bir değişmez değere eşdeğer olmadığında, aslında PostgreSQL'in spesifikasyonu bozduğunu doğrular .

Unutmayın ki bu farklı bir sorun

SELECT *
FROM ( VALUES (1),(2),(3) ) AS t(x)
HAVING count(*) > 1

Hangi her iki veritabanı reddetmek.

PostgreSQL,

HATA: "tx" sütunu GROUP BY deyiminde görünmeli veya toplama işlevinde kullanılmalıdır

SQL Server,

'Tx' sütunu, toplama işlevinde veya GROUP BY deyiminde bulunmadığından seçim listesinde geçersiz.

Bu hata PostgreSQL'de neden devam ediyor?

Bu sorunu çözmede yardım ettiği için irc.freenode.net/#PostgreSQL adresindeki RhodiumToad'a teşekkürler. Ayrıca bu durumu çözmedeki zorluğa dikkat çekiyor

20:33 <RhodiumToad> tek problem pg'de yapabileceğiniz (func () 'u seçin ... burada func () 0 satır döndürebilen bir SRF

SRF, ayarlanan bir döndürme işlevidir.

PostgreSQL'de, örneğin 1-10 generate_seriesarasında bir seri oluşturmak için bir SRF kullanabiliriz ( çekirdekte)

SELECT * FROM generate_series(1,10); 

Ve biz de onu buraya koyabiliriz.

SELECT generate_series(1,10);

İkisi birlikte bize çapraz birleştirme (kartezyen ürün) verir

SELECT generate_series(1,10), generate_series(1,2);

Ancak, bunlardan herhangi biri 0 satır döndürürse, hiçbir şey elde edemezsiniz. Etkili olarak bununla aynı

SELECT * FROM ( VALUES (1) ) AS t(x)
CROSS JOIN ( SELECT 1 LIMIT 0 ) AS g;

Ve bunu tamamen optimize etmede sorun var. 0 satır döndüren ve EXISTS öğesini false olarak değerlendirmeye zorlayan bir EXIST deyiminin içindeki bir seçim listesinde bir SRF'ye sahip olabilirsiniz.

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.