Kotlin Exposed - 根据子查询计数进行选择
Kotlin Exposed - selecting based on sub-query count
在我的数据模型中,挑战和白名单项目.[=15之间有一个非常简单的一对多关系=]
我正在尝试 select 通过白名单过滤的挑战。基本上,挑战 selection 标准是当挑战本身在白名单中没有任何条目或白名单按名称匹配时。
这可以通过非常简单的 SQL 查询来实现:
select c.* from challenge c, challenge_whitelist w where (c.id = w."challengeId" and w."userName" = 'testuser') or ((select count(*) where c.id = w."challengeId") = 0);
不过我无法将其翻译成 Exposed
:
// will not compile
fun listAll(userName: String) {
ExposedChallenge.wrapRows(
ChallengeTable.innerJoin(ChallengeWhitelistTable)
.slice(ChallengeTable.columns)
.select((ChallengeWhitelistTable.userName eq userName) or (ChallengeTable.innerJoin(ChallengeWhitelistTable).selectAll().count() eq 0))
).toList()
}
userName 检查工作正常,但 ChallengeTable.innerJoin(ChallengeWhitelistTable).selectAll().count() eq 0)
不符合有效表达式的条件(不会编译)。
请注意映射非常简单:
object ChallengeTable : IntIdTable() {
val createdAt = datetime("createdAt")
}
class ExposedChallenge(id: EntityID<Int>) : IntEntity(id) {
companion object : IntEntityClass<ExposedChallenge>(ChallengeTable)
var createdAt by ChallengeTable.createdAt
val whitelist by ExposedChallengeWhitelist referrersOn ChallengeWhitelistTable.challenge
}
object ChallengeWhitelistTable : IntIdTable(name = "challenge_whitelist") {
var userName = varchar("userName", 50)
var challengeId = integer("challengeId")
val challenge = reference("challengeId", ChallengeTable).uniqueIndex()
}
class ExposedChallengeWhitelist(id: EntityID<Int>) : IntEntity(id) {
companion object : IntEntityClass<ExposedChallengeWhitelist>(ChallengeWhitelistTable)
val challengeId by ChallengeWhitelistTable.challengeId
val challenge by ExposedChallenge referencedOn ChallengeWhitelistTable.challenge
}
如有任何帮助,我们将不胜感激。
您的 SQL 查询无效,因为您使用 select count(*)
而没有 from
部分。
但它可以用 Exposed DSL 重写,如:
ChallengeTable.leftJoin(ChallengeWhitelistTable).
slice(ChallengeTable.columns).
selectAll().
groupBy(ChallengeTable.id, ChallengeWhitelistTable.userName).having {
(ChallengeWhitelistTable.userName eq "testUser") or
(ChallengeWhitelistTable.id.count() eq 0)
}
另一种方法是使用 just left join:
ChallengeTable.leftJoin(ChallengeWhitelistTable).
slice(ChallengeTable.columns).
select {
(ChallengeWhitelistTable.userName eq "testUser") or
(ChallengeWhitelistTable.id.isNull())
}
在我的数据模型中,挑战和白名单项目.[=15之间有一个非常简单的一对多关系=]
我正在尝试 select 通过白名单过滤的挑战。基本上,挑战 selection 标准是当挑战本身在白名单中没有任何条目或白名单按名称匹配时。
这可以通过非常简单的 SQL 查询来实现:
select c.* from challenge c, challenge_whitelist w where (c.id = w."challengeId" and w."userName" = 'testuser') or ((select count(*) where c.id = w."challengeId") = 0);
不过我无法将其翻译成 Exposed
:
// will not compile
fun listAll(userName: String) {
ExposedChallenge.wrapRows(
ChallengeTable.innerJoin(ChallengeWhitelistTable)
.slice(ChallengeTable.columns)
.select((ChallengeWhitelistTable.userName eq userName) or (ChallengeTable.innerJoin(ChallengeWhitelistTable).selectAll().count() eq 0))
).toList()
}
userName 检查工作正常,但 ChallengeTable.innerJoin(ChallengeWhitelistTable).selectAll().count() eq 0)
不符合有效表达式的条件(不会编译)。
请注意映射非常简单:
object ChallengeTable : IntIdTable() {
val createdAt = datetime("createdAt")
}
class ExposedChallenge(id: EntityID<Int>) : IntEntity(id) {
companion object : IntEntityClass<ExposedChallenge>(ChallengeTable)
var createdAt by ChallengeTable.createdAt
val whitelist by ExposedChallengeWhitelist referrersOn ChallengeWhitelistTable.challenge
}
object ChallengeWhitelistTable : IntIdTable(name = "challenge_whitelist") {
var userName = varchar("userName", 50)
var challengeId = integer("challengeId")
val challenge = reference("challengeId", ChallengeTable).uniqueIndex()
}
class ExposedChallengeWhitelist(id: EntityID<Int>) : IntEntity(id) {
companion object : IntEntityClass<ExposedChallengeWhitelist>(ChallengeWhitelistTable)
val challengeId by ChallengeWhitelistTable.challengeId
val challenge by ExposedChallenge referencedOn ChallengeWhitelistTable.challenge
}
如有任何帮助,我们将不胜感激。
您的 SQL 查询无效,因为您使用 select count(*)
而没有 from
部分。
但它可以用 Exposed DSL 重写,如:
ChallengeTable.leftJoin(ChallengeWhitelistTable).
slice(ChallengeTable.columns).
selectAll().
groupBy(ChallengeTable.id, ChallengeWhitelistTable.userName).having {
(ChallengeWhitelistTable.userName eq "testUser") or
(ChallengeWhitelistTable.id.count() eq 0)
}
另一种方法是使用 just left join:
ChallengeTable.leftJoin(ChallengeWhitelistTable).
slice(ChallengeTable.columns).
select {
(ChallengeWhitelistTable.userName eq "testUser") or
(ChallengeWhitelistTable.id.isNull())
}