sql >> Databasteknik >  >> RDS >> PostgreSQL

Hur använder man ANY istället för IN i en WHERE-klausul med Rails?

Det finns två varianter av IN uttryck:

  • expression IN (subquery)
  • expression IN (value [, ...])

På samma sätt två varianter med ANY konstruera:

  • expression operator ANY (subquery)
  • expression operator ANY (array expression)

En underfråga fungerar för båda teknikerna, men för den andra form av varje, IN förväntar sig en värdelista (enligt definition i standard SQL) medan = ANY förväntar sig en array .

Vilket ska jag använda?

ANY är ett senare, mer mångsidigt tillägg, det kan kombineras med vilken binär operator som helst som returnerar ett booleskt värde. IN brinner ner till ett specialfall av ANY . Faktum är att dess andra form är omskriven internt:

IN skrivs om med = ANY
NOT IN skrivs om med <> ALL

Kontrollera EXPLAIN utgång för alla frågor att se själv. Detta bevisar två saker:

  • IN kan aldrig vara snabbare än = ANY .
  • = ANY kommer inte att bli avsevärt snabbare.

Valet bör avgöras av vad som är lättare att tillhandahålla :en lista med värden eller en array (möjligen som array literal - ett enda värde).

Om ID:n du ska skicka kommer inifrån DB hur som helst, det är mycket effektivare att välja dem direkt (underfråga) eller integrera källtabellen i frågan med en JOIN (gilla @mu kommenterade).

För att klara en lång lista av värderingar från din kund och få bästa prestanda , använd en array, unnest() och gå med, eller tillhandahåll det som tabelluttryck med VALUES (som @PinnyM kommenterade). Men observera att en JOIN bevarar möjliga dubbletter i den angivna arrayen/uppsättningen medan IN eller = ANY låt bli. Mer:

  • Optimera en Postgres-fråga med ett stort IN

I närvaro av NULL-värden, NOT IN är ofta fel val och NOT EXISTS skulle vara rätt (och snabbare också):

  • Välj rader som inte finns i andra tabeller

Syntax för = ANY

För matrisuttrycket accepterar Postgres:

  • en matriskonstruktor (matrisen är konstruerad från en lista med värden på Postgres-sidan) av formen:ARRAY[1,2,3]
  • eller en array literal av formen '{1,2,3}' .

För att undvika ogiltiga casts kan du casta uttryckligen:

ARRAY[1,2,3]::numeric[]
'{1,2,3}'::bigint[]

Relaterat:

  • PostgreSQL:Problem med att skicka array till proceduren
  • Hur man skickar anpassad typarray till Postgres-funktionen

Eller du kunde skapa en Postgres-funktion med en VARIADIC parameter, som tar individuella argument och bildar en array av dem:

  • Att skicka flera värden i en enda parameter

Hur skickar man arrayen från Ruby?

Förutsatt id vara integer :

MyModel.where('id = ANY(ARRAY[?]::int[])', ids.map { |i| i})

Men jag pysslar bara med Ruby. @mu ger detaljerade instruktioner i detta relaterade svar:

  • Skickar du array av värden till en SQL-fråga i ruby?



  1. Lägg till Ordinal Indicator till ett datum i PostgreSQL

  2. Hur man bestämmer fältvärdet som inte kan konverteras till (decimal, float,int) i SQL Server

  3. Hur får man ett float-resultat genom att dividera två heltalsvärden med T-SQL?

  4. Stöder PostgreSQL transparent komprimering av tabeller (fragment)?