在Kotlin公开框架中处理子查询
Exposed 0.27.1是否能够翻译以下SQL语句在Kotlin公开框架中处理子查询,kotlin,kotlin-exposed,Kotlin,Kotlin Exposed,Exposed 0.27.1是否能够翻译以下SQL语句 SELECT FirstName, LastName, (SELECT COUNT(O.Id) FROM "Order" O WHERE O.CustomerId = C.Id) AS OrderCount FROM Customer C; 下面是我尝试过的,但不幸的是,子查询独立于查询的其余部分工作 val query = Customer .leftJoin(Order, { Cust
SELECT FirstName, LastName,
(SELECT COUNT(O.Id)
FROM "Order" O
WHERE O.CustomerId = C.Id) AS OrderCount
FROM Customer C;
下面是我尝试过的,但不幸的是,子查询独立于查询的其余部分工作
val query = Customer
.leftJoin(Order, { Customer.id }, { Order.customerId })
.slice(
Customer.firstName,
Customer.lastName,
intLiteral(Order
.innerJoin(Customer, { Order.customerId }, { Customer.id })
.slice(Order.id.count())
.select { Order.customerId eq Customer.id }
.first()[Order.id.count()].toInt())//.alias("OrderCount")
)
.selectAll()
此外,如果可能的话,我如何使用别名从ResultRow获取结果?接下来的解决方案似乎是使用
alias()
方法调用将整个子查询存储在单个变量中,但这看起来很难看。有更好的方法吗?官方F.A.Q.表示,拥有子查询的唯一方法是:
val orderCount=Order.customerId.count().alias(“orderCount”)
val子查询=Order.slice(Order.customerId,orderCount)
.selectAll()
.groupBy(Order.customerId)
.alias(“子查询”)
val查询=加入(客户)
.join(子查询,JoinType.LEFT,子查询[Order.customerId],Customer.id)
.slice(Customer.firstName、Customer.lastName、子查询[orderCount])
.selectAll()
但也许您不需要在这里使用子查询?这一个生成了一个稍有不同的SQL查询,查询结果几乎相同(与前一个不同,如果没有客户订单,它将返回0而不是null):
val query=Customer
.leftJoin(订单,{Customer.id},{Order.customerId})
.slice(Customer.firstName、Customer.lastName、Order.id.count().alias(“OrderCount”))
.selectAll()
.groupBy(Customer.id)
生成的SQL:
选择客户。“名字”,
顾客:“姓氏”,
计数(“ORDER”.ID)OrderCount
来自客户
在CUSTOMER.ID=“ORDER”“customerId”上左键加入“ORDER”
按CUSTOMER.ID分组
官方F.A.Q.声明,拥有子查询的唯一方法是:
val orderCount=Order.customerId.count().alias(“orderCount”)
val子查询=Order.slice(Order.customerId,orderCount)
.selectAll()
.groupBy(Order.customerId)
.alias(“子查询”)
val查询=加入(客户)
.join(子查询,JoinType.LEFT,子查询[Order.customerId],Customer.id)
.slice(Customer.firstName、Customer.lastName、子查询[orderCount])
.selectAll()
但也许您不需要在这里使用子查询?这一个生成了一个稍有不同的SQL查询,查询结果几乎相同(与前一个不同,如果没有客户订单,它将返回0而不是null):
val query=Customer
.leftJoin(订单,{Customer.id},{Order.customerId})
.slice(Customer.firstName、Customer.lastName、Order.id.count().alias(“OrderCount”))
.selectAll()
.groupBy(Customer.id)
生成的SQL:
选择客户。“名字”,
顾客:“姓氏”,
计数(“ORDER”.ID)OrderCount
来自客户
在CUSTOMER.ID=“ORDER”“customerId”上左键加入“ORDER”
按CUSTOMER.ID分组
谢谢,虽然第一个解决方案很难理解,请对应用的逻辑进行一些文本解释
我设法从中提取数据:
assertEquals(“Manuel”,query.andWhere{subQuery[orderCount]eq intLiteral(2)}.first()[Customer.firstName])
但我无法从第二个解决方案中提取数据。以下是我所做的:
val orderCount=Order.id.count().alias(“orderCount”)
val查询=客户
.leftJoin(订单,{Customer.id},{Order.customerId})
.slice(Customer.firstName、Customer.lastName、orderCount)
.selectAll()
.groupBy(Customer.id)
assertEquals(“Manuel”,query.andWhere{orderCount eq intLiteral(2)}.first()[Customer.firstName])
谢谢,虽然第一个解决方案很难理解,请对应用的逻辑进行一些文本解释
我设法从中提取数据:
assertEquals(“Manuel”,query.andWhere{subQuery[orderCount]eq intLiteral(2)}.first()[Customer.firstName])
但我无法从第二个解决方案中提取数据。以下是我所做的:
val orderCount=Order.id.count().alias(“orderCount”)
val查询=客户
.leftJoin(订单,{Customer.id},{Order.customerId})
.slice(Customer.firstName、Customer.lastName、orderCount)
.selectAll()
.groupBy(Customer.id)
assertEquals(“Manuel”,query.andWhere{orderCount eq intLiteral(2)}.first()[Customer.firstName])
在查询中使用groupby
时,必须使用having
而不是where
来过滤分组后的结果。你可以读更多。在Exposed中,它看起来像:query.having{orderCount eq 2}
。但是请记住,和where
以及具有
会使查询实例状态发生变化。谢谢,但为了使其正常工作,我必须将别名(“OrderCount”)
从变量OrderCount
移动到使用它的位置,即在切片
函数中@Tapac,现在,考虑到前两个示例,我完全搞不清楚如何正确使用别名。要从查询结果中“提取数据”,可以使用纯Kotlin:Query.first{it[orderCount]==2L}[Customer.firstName]和where
以及have
都不是从查询结果中“提取数据”,但是继续构造SQL查询。SQL中添加了having
子句,因为where
子句不能与聚合函数一起使用。不能使用having子句中的列别名(因为子句与聚合函数相关,而不是列)-这是SQL的限制,不是公开的。但通常,当您有group by
子句(或where
和having
)时,您可以在查询中使用where
。请参见使用其委托将ExpressionIAS转换回Expression