Skip to content

Comparing nullable columns in Squeryl

Comparing nullable columns in Squeryl published on Comparing nullable columns in Squeryl へのコメントはまだありません

How to compare nullable columns in Squeryl

Suppose we have a table definition like this:

case class T1 (
  id: Int,
  col1: Option[Int]
)
object FooDb extends Schema {
  val t1 = table[T1]("t1")
}

And, we want to execute a query like the following:

select * from t1 where col1 < 10

The correct statement in Squeryl is shown below:

from(FooDb.t1)( t1 =>
  where(t1.col1 lt Some(10))
  select(t1)
)

This isn’t very intuitive, and actually, it took me a lot of time to get to this answer.

Here are some that I tried and failed

The most intuitive one doesn’t compile:

  where(t1.col1 lt 10) // -> doesn't compile

This one causes NoSuchElementException:

  where(t1.col1.get lt 10) // -> NoSuchElementException

Another one that causes NoSuchElementException:

  where(t1.col1.map(_ lt 10).get) // -> NoSuchElementException

Official site should have example

I’ve found some guys that were having the same issue:

I think the Squeryl web site should have an example that uses nullable column in the where clause.

SquerylでPostgreSQLのgeometry関連関数を使う

SquerylでPostgreSQLのgeometry関連関数を使う published on SquerylでPostgreSQLのgeometry関連関数を使う への1件のコメント

以前別ブログで、Squerylで最初からは用意されていない集計関数(median)を実装する、というエントリを書いた。今回はそれと似た内容で、PostgreSQLの位置情報の関数をSquerylで使えるようにしてみる。

Squeryl 0.9.5-6

距離を調べるSQL

今回使いたいのは、2点間の距離を調べる <-> という関数。例えば、以下のクエリーのように、ある位置(36.726637,139.526557)から3000m以内にある点のうち、距離が近い順に30件取得したいとする。これをSquerylを使って実現したい。

SELECT p.*, (p.latlng <-> POINT(36.726637,139.526557)) * 111000 as l
FROM place p
WHERE (p.latlng <-> POINT(36.726637,139.526557)) < 3000.0 / 111000.0
ORDER BY p.latlng <-> POINT(36.726637,139.526557)
LIMIT 30

Continue reading SquerylでPostgreSQLのgeometry関連関数を使う

SquerylでORDER BY NULLS FIRST (又はLAST)を実行するには

SquerylでORDER BY NULLS FIRST (又はLAST)を実行するには published on SquerylでORDER BY NULLS FIRST (又はLAST)を実行するには へのコメントはまだありません

本記事は、MLで質問して返ってきた内容をまとめただけ。

ORDER BYを指定した時のNULLの扱い

SQLでORDER BYを指定した時、その列にNULLがあった場合、その行はどこに来るのか?デフォルトだと「最小の値」として処理されるんだけど、いくつかのDBMSではNULLS FIRSTあるいはNULLS LAST句を付けることによってその動作を制御することが出来る。

SquerylでNULLS FIRST/LASTを扱うには

以下の様なのを作って、

import org.squeryl.dsl.ast.{FunctionNode, ExpressionNode}
import org.squeryl.internals.StatementWriter

object OrderBy {
  def nullsLast(col: ExpressionNode) = new FunctionNode("", None, Seq(col)) {
    override def doWrite(sw: StatementWriter) = {
      col.write(sw)
      sw.write(" nulls last")
    }
  }

  def nullsFirst(col: ExpressionNode) = new FunctionNode("", None, Seq(col)) {
    override def doWrite(sw: StatementWriter) = {
      col.write(sw)
      sw.write(" nulls first")
    }
  }
}

後は、クエリーを組み立てる所で以下のようにするだけ。

import com.example.OrderBy.nullsLast
// ...
        orderBy(nullsLast(someColumn) desc))

分かってしまえば簡単だった。