2013-07-03 2 views
2

쿼리에서 Query(query.length).first을 실행하려고하면 동일한 이름의 여러 열이있는 2 개의 테이블이 조인됩니다. 잘못된 형식의 SQL이 나타납니다. 예를 생각해Slick에서 조인에 의해 반환 된 행 수는 어떻게 계산합니까?

// in Main.scala 
import scala.slick.driver.MySQLDriver.simple._ 
object Main extends App { 

    object Houses extends Table[Long]("Houses") { 
    def id = column[Long]("id") 
    def * = id 
    } 
    object Rooms extends Table[(Long, Long)]("Rooms") { 
    def id = column[Long]("id") 
    def houseId = column[Long]("houseId") 
    def * = id ~ houseId 
    } 

    val query = for { 
    h <- Houses 
    r <- Rooms 
    if h.id === r.houseId 
    } yield (h, r) 
    println("QUERY: " + Query(query.length).selectStatement) 
} 

// in build.sbt 
scalaVersion := "2.10.2" 

libraryDependencies += "com.typesafe.slick" %% "slick" % "1.0.1" 

이 예는 다음과 같은 SQL을 생성합니다 명확하게 잘못하고 id 열이 select x4.id, x5.id 일부를 복제하기 때문에 MySQL이 거부

select x2.x3 from 
    (select count(1) as x3 from 
    (select x4.`id`, x5.`id`, x5.`houseId` 
    from `Houses` x4, `Rooms` x5 where x4.`id` = x5.`houseId`) x6) x2 

합니다.

query.list.size 

을하지만 쿼리에서 모든 행을 추출하여 성능을 크게 방해하는 것입니다 와이어, 이상을 보내드립니다 :

나는 다음을 수행을 시도 할 수 있습니다.

내가 뭘 잘못하고 있니? 그것을 고칠 수있는 방법이 있습니까?

답변

6

흥미로운 문제입니다. 일반적으로 SQL을 사용하면 이름 충돌을 일으킬 수있는 다른 열을 별칭으로 지정하지만 Slick (또는 가능한 경우)과 함께 작동하는 방법을 잘 모르겠습니다.

val query = for { 
    h <- Houses 
    r <- Rooms 
    if h.id === r.houseId 
} yield h.id.count 

지금 idcount 호출이되지 않습니다, 그러나 이것은이 보이는 깨끗한 SQL 문을 생성 :하지만 당신은 방금 계산하려면 나는 단지 하나의 열을 선택하여 믿는이 문제를 해결할 수 있습니다 : 내가 .length를 사용하여 시도

select count(x2.`id`) from `Houses` x2, `Rooms` x3 where x2.`id` = x3.`houseId` 

아무것도가 잘못했다 SQL의 무리를 생산했다.

귀하의 코멘트에 대한 응답으로

편집

, 당신은 그것이 방식으로 쿼리를 떠나 (과의 쿼리 자체 인해 필드 충돌/조인의 모호성에 깨진 것을 잊지) 다음과 싶었다 (

def main(args: Array[String]) { 
    val query = for { 
    h <- Houses 
    r <- Rooms 
    if h.id === r.houseId 
    } yield (h,r) 

    val lengthQuery = query.map(_._1.id.count) 
} 

여기에서의 포인트 당신이 어떤 질문을 할 수 있어야하고 map 그것을 카운트 쿼리에 하나의 열을 선택하여이 같을 것이라고, 또한 그것에서 카운트 쿼리를 도출 할 수 전체 개체 대신) 그 다음에 해당그 열에 10. 이 경우 결과는 Tuple2이므로 id 열까지 추가 수준으로 이동해야하지만 사진을 얻는다고 생각합니다.

+0

실제로 작동합니다. 나는 일반적인'Query [A, B]'의 경우에 해결책이 존재하기를 바란다. 왜냐하면 그것은 코드의 복잡함을 줄이기 때문이다. (현재의 해결책은 모든 쿼리에 대해 코드를 손으로 쓸 것을 요구한다.) 그러나 일반적인 해결책이 가능한 방법을 알지 못하기 때문에 이것이 유일한 방법입니다. – Rogach

+0

@Rogach, 귀하의 의견에 대한 답변으로 답변에 대한 자세한 내용을 추가했습니다. – cmbaxter

+0

감사합니다. 그러나 나는 다른 것을 의미했다. 예를 들어, 쿼리에서 물건을 가져오고, 제한값을 적용하고, 쿼리 개체를 계산하는 도우미 메서드 인'runApiQuery [A, B] (query : Query [A, B])' 올바르게''runApiQuery' 호출자에게 부담을주지 않으면 서'query.length'를 메서드 내에서 수행 할 수 있습니다. (그리고 Slick 팀은 벌써 6 일 동안 버그를 주석 처리하지 않았기 때문에 곧 그렇게되지는 않을 것입니다).현재 runApiQuery : runApiQuery [A, B, C] (q : Query [A, B]) (countCol : A => Column [C])에 매개 변수를 추가하고 나중에 신체. – Rogach

관련 문제