簡體   English   中英

Scala Slick:如何進行除聯接(左外部聯接為null)?

[英]Scala Slick: How to do an except join (left outer join with is null)?

我正在使用scala 2.11,slick 2.1.0和postgres 9.6。 大版本升級是不可能的。

我有2個相同的表(從相同的模型創建),我想做一個例外聯接(左邊的外部聯接為null): 除了加入

我的模型如下所示:

trait Coffee {
  val coffeeLoversId:         Option[Int]
  val taxId:                  Option[Long]
  val internationalCoffeeId:  String
  val providerId:             String
}

class Coffees(tag: Tag, schema: String) extends Table[Coffee](tag, Some(schema), "coffees")

  val coffeeLoversId: Column[Option[Int]] = column[Option[Int]]("coffee_lovers_id")
  val taxId: Column[Option[Long]] = column[Option[Long]]("tax_id")
  val internationalCoffeeId: Column[String] = column[String]("international_coffee_id", O.DBType("VARCHAR"))
  val providerId: Column[String] = column[String]("provider_id", O.DBType("VARCHAR"))

  def * = (coffeeLoversId, taxId, internationalCoffeeId, providerId) <> (Coffee.tupled, Coffee.unapply)

  def ? = (coffeeLoversId, taxId, internationalCoffeeId.?, providerId.?).shaped.<>({r=>import r._; _1.map(_=> Coffee.tupled((_1, _2, _3.get, _4.get)))}, (_:Any) =>  throw new Exception("Inserting into ? projection not supported."))
}


object Coffees {
  def tableQuery(implicit schema: TableSchema) = TableQuery[Coffees]{ tag : Tag => new Coffees(tag, schema.name) }
}

我想運行的SQL查詢是:

SELECT * from previous.coffees PRV 
LEFT JOIN current.coffees CUR 
ON PRV.international_coffee_id = CUR.international_coffee_id 
WHERE PRV.international_coffee_id IS NULL;

我能夠做到:

for {
  (c,s) <- Coffees.tableQuery(previousSchema).leftJoin(
    Coffees.tableQuery(currentSchema)
    ) on((x,y) => x.internationalCoffeeId === y.internationalCoffeeId)
} yield(c)

這似乎給了我一個左外部WHERE PRV.international_coffee_id IS NULL ,但是我在過濾null服務器端時遇到了麻煩(添加WHERE PRV.international_coffee_id IS NULL

如果有任何建議或想法,我將不勝感激。

我能夠實現自己的目標。 首先,我嘗試使用scala的條件理解:

for {
  (c,s) <- Coffees.tableQuery(previousSchema).leftJoin(
    Coffees.tableQuery(currentSchema)
    ) on((x,y) => x.internationalCoffeeId === y.internationalCoffeeId)
if(s.internationalCoffeeId.isEmpty)
} yield(c)

這可以正常工作,並且在數據庫上進行測試得到了預期的結果,因為我知道我是在scala中而不是在數據庫服務器上過濾結果。

所以我一直努力,終於

for {
  (c,s) <- Coffees.tableQuery(previousSchema).leftJoin(
    Coffees.tableQuery(currentSchema)
    ) on(
    (x,y) => x.internationalCoffeeId === y.internationalCoffeeId
    ).filter(_._2.internationalCoffeeId.isEmpty)
} yield(c)

我還不清楚為什么編譯器無法正確選擇類型,而我的過濾器中卻沒有為匿名函數輸入參數的類型,但是我直接在元組上進行處理。 我驗證selectStatement可以在Query (或本例中為CompiledStreamingExecutable )中直接使用selectStatement獲得所需的SQL查詢:

val query = Coffees.tableQuery(previousSchema).leftJoin(
    Coffees.tableQuery(currentSchema)
) on(
    (x,y) => x.internationalCoffeeId === y.internationalCoffeeId
).filter(_._2.internationalCoffeeId.isEmpty)
query.selectStatement

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM