3

値をすべての可能な値、一種の「すべてをキャッチ」値、アンチ NULL に一致させるためのトリックは postgresql にありますか?

現時点では、「キャッチオール」キーワードを選択して、クエリで強制的に一致させることをお勧めします。

WITH cities AS (SELECT * FROM (VALUES('USA','New York'),
                                     ('USA','San Francisco'),
                                     ('Canada','Toronto'),
                                     ('Canada','Quebec')
                               )x(country,city)),
     zones  AS (SELECT * FROM (VALUES('USA East','USA','New York'),
                                     ('USA West','USA','San Francisco'),
                                     ('Canada','Canada','catchall')
                               )x(zone,country,city))
SELECT z.zone, c.country, c.city
FROM cities c,zones z
WHERE c.country=z.country
  AND z.city IN (c.city,'catchall');

   zone   | country |     city
----------+---------+---------------
 USA East | USA     | New York
 USA West | USA     | San Francisco
 Canada   | Canada  | Toronto
 Canada   | Canada  | Quebec

新しいカナダの町が「都市」テーブルに挿入された場合、「ゾーン」テーブルはそれを「カナダ」ゾーンの一部として自動的に認識します。上記のクエリは、私が探している機能を満たしていますが、広いデータベースで複数回繰り返されると、扱いにくく、エラーが発生しやすくなります。

これは適切な方法ですか、より良い方法はありますか、それとも間違った質問をしていますか?

ご回答ありがとうございます。

4

3 に答える 3

1

NULL個人的には、これがより良い選択になると思います:

select z.zone, c.country, c.city
from cities c join
     zones z
     on c.country = z.country and
        (c.city = z.city or z.city is null);

あるいは:

select z.zone, c.country, c.city
from cities c join
     zones z
     on c.country = z.country and
        c.city = coalesce(z.city, c.city);

countryDenis によると、Postgres はとの両方の最初のクエリでインデックスを使用するのに十分賢いようcityです。

と の両方にインデックスがある場合は、2 部結合を行うこともzone(country)できzone(country, city)ます。2 部結合を行うことができます。

select coalesce(zcc.zone, zc.zone) as zone, c.country, c.city
from cities c join
     zones zcc
     on c.country = z.country and
        c.city = z.city join
     zones zc
     on c.country = z.country and
        zc.city is null;

もう少し複雑ですが、両方の結合で適切なインデックスを使用できる必要があります。

于 2013-06-05T21:32:30.917 に答える