Postgres dizisinde değerin var olup olmadığını kontrol edin


196

Postgres 9.0 kullanarak, belirli bir dizide bir değer olup olmadığını sınamak için bir yol gerekir. Şimdiye kadar böyle bir şey buldum:

select '{1,2,3}'::int[] @> (ARRAY[]::int[] || value_variable::int)

Ama bunun daha basit bir yolu olması gerektiğini düşünüyorum, göremiyorum. Bu daha iyi görünüyor:

select '{1,2,3}'::int[] @> ARRAY[value_variable::int]

Bunun yeterli olacağına inanıyorum. Ancak bunu yapmanın başka yolları varsa lütfen paylaşın!

Yanıtlar:


323

ANYYapı ile daha basit :

SELECT value_variable = ANY ('{1,2,3}'::int[])

Sağ işlenen ANY(parantezler arasında) bir küme (örneğin bir alt sorgunun sonucu) veya bir dizi olabilir . Kullanmanın birkaç yolu vardır:

Önemli bir farklılık: (Dizi operatörleri <@, @>, &&et al.) Beklemek dizi işlenen gibi türleri destek veya cin GiST endeksleri ise, PostgreSQL standart dağılımında ANYyapı, tahmin unsuru işlenen sol ve bu endeksleri desteklemediği türü. Misal:

Bunların hiçbiri NULLelemanlar için geçerli değildir. Test etmek için NULL:


Teşekkürler. Kılavuzun o kısmını atlamış olmalı. Harika çalışıyor. Otomatik dökümün yan etkisi vardır. Örnek: SELECT 1 :: smallint = HERHANGİ ('{1,2,3}' :: int []) çalışıyor. İfadenin sağ tarafına HERHANGİ () yerleştirdiğinizden emin olun.
Mike Starov

Cevap için teşekkürler. Benim sorgu yerel çalıştı bir sorun var, ama Heroku bu mesajı atma edildi ANY/ALL (array) requires array on right sideait eklenti ::int[]cazibesi yaptı.
kinduff

burada S.employee_id <@ BİR ( ' "+ employeeIDsArray +"' :: int []) Bu döner PSQLException: HATA: eksik boyut değeri
Ramprasad

3
Bu internet yıllarında bir dinozor sorusu olmasına rağmen, benim gibi yavaş insanlar 'something' = ANY(some_array)bir WHEREmaddede de kullanılabileceğinin farkında olmalıdır . Yalnızca Crom tarafından bilinen nedenlerden ötürü, son dört yılı, WHEREcümlelerde dizi karşılaştırıcılarını kullanamayacağımı düşünerek geçirdim . O günler artık gitti. (Çocukken kafama düştüm, belki de sadece ben).
GT.

1
@GT .: Özü: cümlede herhangi bir boolean ifade çalışır WHERE- Crom istekli.
Erwin Brandstetter

90

Girdiğim tuzak dikkat edin: Bir dizide belirli bir değer olup olmadığını kontrol ederken, yapmamalısınız:

SELECT value_variable != ANY('{1,2,3}'::int[])

ama kullan

SELECT value_variable != ALL('{1,2,3}'::int[])

yerine.


2
Bir tür çifte negatif; ALLvsANY
vol7ron

43
SELECT NOT value_variable = ANY('{1,2,3}'::int[])daha okunabilir olabilir
Ondřej Bouda

28

ancak bunu yapmanın başka yolları varsa lütfen paylaşın.

İki diziyi karşılaştırabilirsiniz. Sol dizideki değerlerden herhangi biri sağ dizideki değerlerle çakışırsa, true değerini döndürür. Bu bir tür hackish, ama işe yarıyor.

SELECT '{1}'   && '{1,2,3}'::int[];  -- true
SELECT '{1,4}' && '{1,2,3}'::int[];  -- true
SELECT '{4}'   && '{1,2,3}'::int[];  -- false
  • Birinci ve ikinci sorguda, değer 1doğru dizide
  • trueDeğer 4doğru dizide bulunmasa da ikinci sorgunun olduğuna dikkat edin
  • Üçüncü sorgu için, sol dizideki hiçbir değer (yani 4) sağ dizide değildir, bu nedenle döndürürfalse

dizide bir değere sahip olmak için başka bir tablodan nasıl sütun arayabilirim? örneğin, style_id öğesinin (id = 1 olduğu kullanıcılardan tercihleri ​​seçin) sınır 1 olduğu biralardan * seçin; style_id bir tamsayı veri türüdür; tercihler tamsayıdır [] Bu hatayı alıyorum HATA: işleç mevcut değil: tamsayı = tamsayı [] LINE 1: style_id öğesinin bulunduğu biralardan * seçin (belirli tercihler f ... ^ İPUCU: Hiçbir işleç verilen ad ve bağımsız değişken türüyle eşleşmiyor Açık tür kalıplar eklemeniz gerekebilir
HP

@HP Bu soruyu çözmenin farklı yolları var, yeni bir soru sormalısınız
vol7ron

mevcut bir soru olmadığından emin misin? @ vol7ron
HP

@HP Hiç değil, ancak yorumlar bir soru veya cevap hakkındaki yorumlar içindir; genellikle daha fazla bilgi eklemek veya ele alınmayan daha fazla bilgi istemek için kullanılır. Bu cevapla ilgili olmayan bir soru soruyorsunuz. Bence yorumda değil, yeni bir yazı olarak sorunuzu sorarak daha fazla şansınız olacak;)
vol7ron

@HP sorunuzu göndermediyseniz, burada görebilirsiniz: sqlfiddle.com/#!15/144cd/3 ne yapmanız gerektiğini gösteren bir örnek için - sorununuz farklıdır, çünkü dizinizi kirletmeniz gerekir.
vol7ron

4

unnestde kullanılabilir. Bu sıralar, bir dizi dizi genişler ve daha sonra basit bir değeri kontrol var olup kullanılarak basit gibidir INya da NOT IN.

Örneğin

  1. id => uuid

  2. exception_list_ids => uuid []

select * from table where id NOT IN (select unnest(exception_list_ids) from table2)


Evet. Benim sorgu planlarım SELECT UNNEST = ANY kadar iyi olmadığını unutmayın. İstediğinizi / beklediğinizi alıp almadığınızı görmek için sorgu planlarını kontrol etmenizi tavsiye ederim.
Rob Bygrave

3

Bir dizide bir öğenin varlığını ararken postgreslerin SQL ayrıştırıcısını geçmek için uygun döküm gerekir. Birleştirme yan tümcesinde array include operatörünü kullanan bir örnek sorgu:

Basitlik için sadece ilgili kısmı listeliyorum:

table1 other_name text[]; -- is an array of text

SQL'in birleştirme kısmı gösteriliyor

from table1 t1 join table2 t2 on t1.other_name::text[] @> ARRAY[t2.panel::text]

Aşağıdakiler de çalışır

on t2.panel = ANY(t1.other_name)

Ben sadece ayrıştırma sütun tam türü anlamaya tablo tanımı almak zorunda değilsiniz çünkü ekstra döküm gerekli olduğunu tahmin ediyorum. Diğerleri lütfen bu konuda yorum yapın.


1

Merhaba biri benim için iyi çalışıyor, belki birisi için yararlı

dizi_column :: text ilike ANY (ARRAY ['% text_to_search%' :: text]) 'dan;

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.