Adr*_*zin 7 activerecord scala join group-by
I am trying to write a specific query in scala Active record. But it always returns nothing. I have read the wiki on the github page but it does not contain a lot of info on it. The query I am trying to write is
SELECT e.name, e.id, COUNT(pt.pass_id) as pass_count, e.start_date, e.total_passes_to_offer
FROM events e inner join passes p on e.id = p.event_id inner join pass_tickets pt on p.id = pt.pass_id where e.partner_id = 198 group by e.name, e.id
Run Code Online (Sandbox Code Playgroud)
What I have tried is
Event.joins[Pass, PassTicket](
(event, pass, passTicket) => (event.id === pass.eventId, pass.id === passTicket.passId)
).where(
(event, _, _) => event.partnerId === partnerId
).select(
(event, pass, _) => (event.name, event.id, PassTicket.where(_.passId === pass.id).count, event.startDate, event.totalPassesToOffer)
).groupBy( data => data._2)
Run Code Online (Sandbox Code Playgroud)
But first, the return type becomes a map, not a list. And second when executed, it doesnt return anything even though the data exists. When running the SQL query directly against the database, the expected results return.
scala-activerecorddsl 基于squeryl,因此当计算出复杂的查询时,我们可以下降到 squeryl 级别并使用其statement功能来漂亮地打印 SQL 语句。这样我们就可以迭代地调整 dsl,直到获得所需的 SQL 语句。例如,假设我们有以下模式:
object Tables extends ActiveRecordTables {\n val persons = table[Person]\n val tickets = table[Ticket]\n}\n\ncase class Person(name: String, email: String, age: Int) extends ActiveRecord\ncase class Ticket(price: Float, priority: Boolean) extends ActiveRecord {\n lazy val person = belongsTo[Person]\n}\n\nobject Person extends ActiveRecordCompanion[Person]\nobject Ticket extends ActiveRecordCompanion[Ticket]\nRun Code Online (Sandbox Code Playgroud)\n\n然后我们转到 squeryl dsl 来定义以下查询
\n\n val query =\n dsl.join(Person.toQuery, Ticket.toQuery)((person, ticket) =>\n groupBy(person.name, person.age)\n compute(count(ticket.id))\n on(person.id === ticket.id)\n )\nRun Code Online (Sandbox Code Playgroud)\n\n然后我们可以使用以下命令漂亮地打印语句
\n\nprintln(Person.inTransaction(query.statement))\nRun Code Online (Sandbox Code Playgroud)\n\n输出实际的 SQL 语句
\n\nSelect\n q1.people6_name as g0,\n q1.people6_age as g1,\n count(q7.tickets11_id) as c0\nFrom\n(Select\n people6.name as people6_name,\n people6.email as people6_email,\n people6.age as people6_age,\n people6.id as people6_id\n From\n people people6\n) q1\n inner join (Select\n tickets11.priority as tickets11_priority,\n tickets11.price as tickets11_price,\n tickets11.id as tickets11_id\n From\n tickets tickets11\n) as q7 on (q1.people6_id = q7.tickets11_id)\nGroup By\n q1.people6_name,\n q1.people6_age\nRun Code Online (Sandbox Code Playgroud)\n\n一旦我们在 squeryl 中找出正确的 dsl,那么我们至少知道它是可能的,然后我们可以尝试将它也写入 scala-activerecord 中。这种方法的潜在优势是 squirly 似乎有更多文档。请注意它在“组查询”和“聚合查询”上的说明,这也应该间接适用于 scala-activerecord:
\n\n\n\n\nSqueryl 与 SQL 略有不同,因为select 中不允许使用聚合函数。相反,它们是在 \xe2\x80\x98compute\xe2\x80\x99\n 子句中声明的,这实际上是一个变相的选择,因为它\xe2\x80\x99s 参数最终\n 出现在生成的 SQL\xe2\ 中。 x80\x99s 选择子句。这种设计选择的动机是让编写无效的 Select 语句变得更加困难,因为 DSL强制使用 \xe2\x80\x98compute\xe2\x80\x99 子句来替换\na select 或跟随一个groupBy。
\n
根据我的理解,这意味着我们不应该PassTicket.where(_.passId === pass.id).count在select子句中写入。
关于groupBy返回 a Map,我们可以调用values.toList它来获取列表,例如,假设我们有
Person("Picard", "picard@starfleet.org", 34).save\n Person("Data", "data@starfleet.org", 40).save\n Person("Geordi", "geordi@starfleet.org", 40).save\nRun Code Online (Sandbox Code Playgroud)\n\n那么println(Person.groupBy(person => person.age).values.toList)应该给
List(\n List(Person(Data,data@starfleet.org,40), Person(Geordi,geordi@starfleet.org,40)), \n List(Person(Picard,picard@starfleet.org,34))\n)\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
197 次 |
| 最近记录: |