2016-01-06 76 views
2

我試圖構建留在油滑3.1本類似的聯接查詢重複計算:斯卡拉油滑3.1.0 - 從2個表計數中列左連接查詢

SELECT 
    COUNT(p.id) AS replies, 
    COUNT(f.id) AS images 
    FROM posts AS p 
    LEFT JOIN files AS f 
    ON p.id = f.post_id 
    WHERE thread = :thread_id 

加入查詢的一部分是相當簡單,看起來像這樣:

val joinQ = (threadId: Rep[Long]) => 
    (postDAO.posts joinLeft fileRecordDAO.fileRecords on (_.id === _.postId)) 
    .filter(_._1.thread === threadId) 

使用joinQ(1L).map(_._1.id).length產生COUNT(1),其對所有行 - 而不是結果,我想獲得的。使用joinQ(1L).map(_._1.id).countDistinct產生COUNT(DISTINCT p.id)這是有點什麼我要找的,但試圖做其中的兩個產生這個畸形:

select x2.x3, x4.x5 
    from (select count(distinct x6.`id`) as x3 
    from `posts` x6 
    left outer join `files` x7 on x6.`id` = x7.`post_id` 
    where x6.`thread` = 1) x2, 
    (select 
    count(distinct (case when (x8.`id` is null) then null else 1 end)) as x5 
    from `posts` x9 
    left outer join `files` x8 on x9.`id` = x8.`post_id` 
    where x9.`thread` = 1) x4 

這裏的雙countDistinct代碼:

val q = (threadId: Rep[Long]) => { 
    val join = joinQ(threadId) 
    val q1 = join.map(_._1.id).countDistinct // map arg type is 
    val q2 = join.map(_._2).countDistinct // (Post, Rep[Option[FileRecord]]) 
    (q1, q2) 
} 

任何想法? :)

回答

0

計數是聚合函數,所以您還需要通過某個字段(e.x. id)進行分組。試試下面的查詢:

def joinQ(threadId: Long) = (postDAO.posts joinLeft fileRecordDAO.fileRecords on (_.id === _.postId)) 
.filter(_._1.thread === threadId) 

val q = (threadId: Long) => { 
    joinQ(threadId).groupBy(_._1.id).map { 
    case (id, qry) => (id, qry.map(_._1.id).countDistinct, qry.map(_._2.map(_.id)).countDistinct) 
    } 
} 

它產生下一個SQL:

SELECT x2.`id`, 
     Count(DISTINCT x2.`id`), 
     Count(DISTINCT x3.`id`) 
FROM `posts` x2 
     LEFT OUTER JOIN `files` x3 
        ON x2.`id` = x3.`post_id` 
WHERE x2.`thread` = 10 
GROUP BY x2.`id` 
+0

感謝您的時間,但不幸的是GROUP BY中斷整個查詢 – Egregore

+0

它打破了由拆分結果整個查詢設置爲行數相匹配的數基表(在這個例子中是帖子)與WHERE子句匹配的行。這會導致COUNT(DISTINCT _)子句爲現有行返回1,爲空行返回0(顯然只用於左連接的表)而不是計數聚合。我去了原始的sql插入器,它的工作就像魅力。 – Egregore

+0

而不是使用'countDistinct'嘗試使用'countDefined'來計算非空值。 –