Aynı SELECT listesindeki referans sütun takma adı


27

Eski bir MS Access tabanlı sistemi PostgreSQL'e dönüştürüyorum. Access'te, SELECT’lerde oluşturulan alanlar daha sonraki alanlar için denklemlerin bir parçası olarak kullanılabilir:

SELECT
    samples.id,
    samples.wet_weight / samples.dry_weight - 1 AS percent_water,
    100 * percent_water AS percent_water_100
FROM samples;

Bunu PostgreSQL'de yaptığımda, Postgres bir hata veriyor:

HATA: "yüzde_su" sütunu mevcut değil.

Alt seçimlerden birini seçerek bu konuda nasıl çalışabilirim:

SELECT
    s1.id,
    s1.percent_water,
    100 * s1.percent_water AS percent_water_100
FROM (
    SELECT
        samples.id,
        samples.wet_weight / samples.dry_weight - 1 AS percent_water
    FROM samples
    ) s1;

Karmaşık yuvalamanın üstesinden gelmek için ilk kod bloğunda olduğu gibi herhangi bir kısayol var mı? Ben de söyleyebilirim 100 * (samples.wet_weight / samples.dry_weight - 1) AS percent_water_100ama bu, kodumda gerçekleşen çok daha büyük bir matematik sisteminin ne olduğuna dair küçük bir örnektir, onlarca üst üste düzinelerce daha karmaşık matematik parçaları. Kendimi tekrar etmeden mümkün olduğu kadar temiz yapmayı tercih ederim.

Yanıtlar:


24

Bazen uygunsuz olabilir, ancak standart SQL davranışıdır ve belirsizlikleri önler. Aynı SELECTlistede sütun diğer isimlerine başvuruda bulunamazsınız .

Daha kısa sözdizimi seçenekleri var:

SELECT s.*, s.percent_water * 100 AS percent_water_100
FROM  (
   SELECT id, wet_weight / NULLIF(dry_weight - 1, 0) AS percent_water
   FROM   samples
   ) s;

Ve LATERALPostgres 9.3+ 'de bir birleşim kullanabilirsiniz :

SELECT s.id, s1.percent_water
     , s1.percent_water * 100 AS percent_water_100
FROM   samples s
     , LATERAL (SELECT s.wet_weight / NULLIF(s.dry_weight - 1, 0) AS percent_water) s1;

NULLIF()Sıfır hataya karşı savunmak için ekledim .


2
Merhaba. SQL standardının belirsizliklerini engelleyen bir örnekle cevabınızı uzatabilir misiniz?
Eugen Konkov

4

Bunun gibi bir şeye çarpıyorum, 500'den fazla hatlı Netezza sorgusunu (aka değiştirilmiş Postgres) SQL Server'a taşıdım. Netezza'da hesaplanan sütun takma adının akış aşağı referanslarda bir değer olarak kullanılmasına izin verildi.

Benim çalışmam, CROSS APPLY uygulamasını ilişkili bir alt sorgu ile kullanmaktı. Bunun güzelliği, orijinal sorgudaki sütun diğer adıyla ilgili çok sayıda referansın değiştirilmesine gerek olmamasıdır.

OP'den gelen sorguyu kullanarak, CROSS APPLYyöntem şöyle görünür:

SELECT
    s.id,
    x.percent_water,
    100 * x.percent_water AS percent_water_100
FROM samples AS s
CROSS APPLY (SELECT s.wet_weight / s.dry_weight - 1 AS percent_water ) x ;

1
CROSS APPLY(ve OUTER APPLY) LATERALalt sorguları yazmanın SQL Server yoludur .
ypercubeᵀᴹ

4
cross applyPostgres'te yok . Postgres standartlara yapışır ve kullanır cross join lateral.
a_horse_with_no_name
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.