将普通 PostgreSQL 查询转换为 Slick 查询的麻烦
Troublesome conversion of plain PostgreSQL query to Slick query
我有一个普通的 PostgreSQL 查询,但在转换为流畅的查询时遇到了问题。使用 groupBy
子句时,我陷入语法困境。
SELECT u.id AS investor_id,
u.account_type,
i.first_name,
issuer_user.display_name AS issuer_name,
p.legal_name AS product_name,
v.investment_date,
iaa.as_of AS CCO_approval_date,
v.starting_investment_amount,
v.maturity_date,
v.product_interest_rate,
v.product_term_length,
i.user_information_id,
v.id AS investment_id
FROM investors u
JOIN
( SELECT ipi.investor_id,
ipi.first_name,
ipi.user_information_id
FROM investor_personal_information ipi
JOIN
( SELECT investor_id,
MAX(id) AS Max_Id
FROM investor_personal_information
GROUP BY investor_id ) M ON ipi.investor_id = m.investor_id
AND ipi.id = m.Max_Id ) i ON u.id = i.investor_id
JOIN investments v ON u.id = v.investor_id
JOIN sub_products AS sp ON v.sub_product_id = sp.id
JOIN products AS p ON p.id = sp.product_id
JOIN company AS c ON c.id = p.company_id
JOIN issuers AS issuer ON issuer.id = c.issuer_id
JOIN users AS issuer_user ON issuer.owner = issuer_user.id
JOIN investment_admin_approvals AS iaa ON iaa.investment_id = v.id
ORDER BY i.first_name DESC;
开始写了
val query = {
val investorInfoQuery = (for {
i <- InvestorPersonalInformation
} yield (i)).groupBy {
_.investorId
}.map {
case (id, rest) => {
id -> rest.map(_.id).max
}
}
}
我知道我必须将基本查询创建到一个大查询中并分别对它们应用联接。任何人都可以帮助指导我或提供一些例子吗?华而不实。
看起来写起来很简单。我不会帮你编写整个查询,我只会给你一个例子,你可以按照它来编写你的查询。
假设您有以下结构和相应的 table 查询定义为 employees
、emplayeePackages
和 employeeSalaryCredits
case class Employee(id: String, name: String)
case class EmployeePackage(id: String, employeeId: String, baseSalary: Double)
case class EmployeeSalaryCredit(id: String, employeeId: String, salaryCredited: Double, date: ZonedDateTime)
现在假设您想要所有具有 employee's id, employee's name, base salary, actual credited salary and date of salary credit
的员工的所有工资贷记,那么您的查询将类似于
val queryExample = employees
.join(employeePackages)
.on({ case (e, ep ) => e.id === ep.employeeId })
.join(employeeSalaryCredits)
.on({ case ((e, ep), esc) => e.id === esc.employeeId })
.map({ case ((e, ep), esc) =>
(e.id, e.name, ep.baseSalary, esc.salaryCredited, esc.date)
})
我有一个普通的 PostgreSQL 查询,但在转换为流畅的查询时遇到了问题。使用 groupBy
子句时,我陷入语法困境。
SELECT u.id AS investor_id,
u.account_type,
i.first_name,
issuer_user.display_name AS issuer_name,
p.legal_name AS product_name,
v.investment_date,
iaa.as_of AS CCO_approval_date,
v.starting_investment_amount,
v.maturity_date,
v.product_interest_rate,
v.product_term_length,
i.user_information_id,
v.id AS investment_id
FROM investors u
JOIN
( SELECT ipi.investor_id,
ipi.first_name,
ipi.user_information_id
FROM investor_personal_information ipi
JOIN
( SELECT investor_id,
MAX(id) AS Max_Id
FROM investor_personal_information
GROUP BY investor_id ) M ON ipi.investor_id = m.investor_id
AND ipi.id = m.Max_Id ) i ON u.id = i.investor_id
JOIN investments v ON u.id = v.investor_id
JOIN sub_products AS sp ON v.sub_product_id = sp.id
JOIN products AS p ON p.id = sp.product_id
JOIN company AS c ON c.id = p.company_id
JOIN issuers AS issuer ON issuer.id = c.issuer_id
JOIN users AS issuer_user ON issuer.owner = issuer_user.id
JOIN investment_admin_approvals AS iaa ON iaa.investment_id = v.id
ORDER BY i.first_name DESC;
开始写了
val query = {
val investorInfoQuery = (for {
i <- InvestorPersonalInformation
} yield (i)).groupBy {
_.investorId
}.map {
case (id, rest) => {
id -> rest.map(_.id).max
}
}
}
我知道我必须将基本查询创建到一个大查询中并分别对它们应用联接。任何人都可以帮助指导我或提供一些例子吗?华而不实。
看起来写起来很简单。我不会帮你编写整个查询,我只会给你一个例子,你可以按照它来编写你的查询。
假设您有以下结构和相应的 table 查询定义为 employees
、emplayeePackages
和 employeeSalaryCredits
case class Employee(id: String, name: String)
case class EmployeePackage(id: String, employeeId: String, baseSalary: Double)
case class EmployeeSalaryCredit(id: String, employeeId: String, salaryCredited: Double, date: ZonedDateTime)
现在假设您想要所有具有 employee's id, employee's name, base salary, actual credited salary and date of salary credit
的员工的所有工资贷记,那么您的查询将类似于
val queryExample = employees
.join(employeePackages)
.on({ case (e, ep ) => e.id === ep.employeeId })
.join(employeeSalaryCredits)
.on({ case ((e, ep), esc) => e.id === esc.employeeId })
.map({ case ((e, ep), esc) =>
(e.id, e.name, ep.baseSalary, esc.salaryCredited, esc.date)
})