【发布时间】:2021-10-25 12:40:18
【问题描述】:
我正在尝试创建一个以漂亮的 json 格式返回数据的 psql 查询。最初对于我们使用 sequelize 的项目,我正在尝试将其转换为纯 psql。我要找的格式如下-
...
vehicles:
[
{
services:
[
{
name: "example"
duration: "example"
}
]
id: 1
registration: "example"
}
]
...
以下是我首先尝试但得到错误的方法。 错误:聚合函数调用不能嵌套
SELECT
"Bookings"."id",
"Bookings"."startTime",
"Bookings"."code",
"Bookings"."statusId",
"Bookings"."address",
"Bookings"."latitude",
"Bookings"."longitude",
"Bookings"."createdAt",
"Bookings"."overridePrice",
json_build_object(
'fullName', "customer"."fullName",
'id', "customer"."id"
) AS "customer",
json_agg(json_build_object(
'fullName', "serviceProvider"."fullName",
'id', "serviceProvider"."id"
)) AS "serviceProvider",
-- Array of vehicles, this is where the issue lies
json_agg(
json_build_object(
'services', json_agg(
json_build_object(
'name', "ServiceHistories"."name",
'duration', "ServiceHistories"."duration"
)
),
'id', "Vehicles"."id",
'registration', "Vehicles"."registration"
)) AS "vehicles",
-- Everything else works fine
json_agg(
json_build_object(
'amount', "payments"."amount",
'amountFromGiftCard', "payments"."amountFromGiftCard"
)
) AS "payments"
FROM
"Bookings",
"Users" AS "customer",
"Users" AS "serviceProvider",
"BookingServiceProviders",
"BookingVehicleServices",
"BookingVehicles",
"Vehicles",
"Payments" AS "payments",
"ServiceHistories"
WHERE
"Bookings"."isDeleted" IS NOT true AND
"Bookings"."statusId" != 4 AND
"Bookings"."customerId" = "customer"."id" AND "customer"."userTypeId" = 1 AND
"Bookings"."id" = "BookingServiceProviders"."BookingId" AND
"BookingServiceProviders"."UserId" = "serviceProvider"."id" AND
"Bookings"."id" = "BookingVehicles"."BookingId" AND
"Vehicles"."id" = "BookingVehicles"."VehicleId" AND
"Bookings"."id" = "payments"."bookingId" AND
"BookingVehicles"."id" = "BookingVehicleServices"."BookingVehicleId" AND
"ServiceHistories"."bookingId" = "Bookings"."id"
GROUP BY
"Bookings"."id",
"customer"."id",
"customer"."fullName"
Order by "startTime" ASC
做了一些谷歌搜索后,我发现我可能需要对服务数组进行子查询。以下是我尝试过的,但查询会无限期运行。
SELECT
"Bookings"."id",
"Bookings"."startTime",
"Bookings"."code",
"Bookings"."statusId",
"Bookings"."address",
"Bookings"."latitude",
"Bookings"."longitude",
"Bookings"."createdAt",
"Bookings"."overridePrice",
json_build_object(
'fullName', "customer"."fullName",
'id', "customer"."id"
) AS "customer",
json_agg(json_build_object(
'fullName', "serviceProvider"."fullName",
'id', "serviceProvider"."id"
)) AS "serviceProvider",
-- Issue lies here
json_agg(
json_build_object(
'services', (
SELECT
json_agg(json_build_object(
'name', "ServiceHistories"."name",
'duration', "ServiceHistories"."duration"
))
FROM
"ServiceHistories"
WHERE
"ServiceHistories"."bookingId" = "Bookings"."id"
),
'id', "Vehicles"."id",
'registration', "Vehicles"."registration"
)) AS "vehicles",
-- End of issue
json_agg(
json_build_object(
'amount', "payments"."amount",
'amountFromGiftCard', "payments"."amountFromGiftCard"
)
) AS "payments"
FROM
"Bookings",
"Users" AS "customer",
"Users" AS "serviceProvider",
"BookingServiceProviders",
"BookingVehicleServices",
"BookingVehicles",
"Vehicles",
"Payments" AS "payments"
WHERE
"Bookings"."isDeleted" IS NOT true AND
"Bookings"."statusId" != 4 AND
"Bookings"."customerId" = "customer"."id" AND "customer"."userTypeId" = 1 AND
"Bookings"."id" = "BookingServiceProviders"."BookingId" AND
"BookingServiceProviders"."UserId" = "serviceProvider"."id" AND
"Bookings"."id" = "BookingVehicles"."BookingId" AND
"Vehicles"."id" = "BookingVehicles"."VehicleId" AND
"Bookings"."id" = "payments"."bookingId" AND
"BookingVehicles"."id" = "BookingVehicleServices"."BookingVehicleId"
GROUP BY
"Bookings"."id",
"customer"."id",
"customer"."fullName"
Order by "startTime" ASC
如果有人可以帮助或指出正确的方向,我将不胜感激。
** 编辑 **
我通过添加更多关于表如何关联的 where 子句来使其工作,现在服务在车辆数组中正确返回。可悲的是它的超级慢。我让它工作得更快,但是当它应该只是与特定预订相关的服务时,却出现了重复的服务。
SELECT
bookings."id",
bookings."startTime",
bookings."code",
bookings."statusId",
bookings."address",
bookings."latitude",
bookings."longitude",
bookings."createdAt",
bookings."overridePrice",
json_build_object(
'fullName', "customer"."fullName",
'id', "customer"."id"
) AS "customer",
json_agg(json_build_object(
'fullName', "serviceProvider"."fullName",
'id', "serviceProvider"."id"
)) AS "serviceProvider",
json_agg(
json_build_object(
'amount', "payments"."amount",
'amountFromGiftCard', "payments"."amountFromGiftCard"
)
) AS "payments",
(
SELECT
(nested_vehicles)
FROM (
SELECT
"Vehicles".id as vehicle_id,
"Vehicles".registration,
(
SELECT
json_agg(nested_services)
FROM (
SELECT
"ServiceHistories"."id",
"ServiceHistories"."name",
"ServiceHistories"."duration"
FROM
"ServiceHistories", "BookingVehicleServices", "BookingVehicles"
WHERE
"ServiceHistories"."vehicleId" = "Vehicles"."id" AND
"ServiceHistories"."id" = "BookingVehicleServices"."ServiceHistoryId" AND
bookings.id = "BookingVehicles"."BookingId" AND
"Vehicles"."id" = "BookingVehicles"."VehicleId" AND
"ServiceHistories"."bookingId" = bookings.id
) AS nested_services
) AS services
FROM
"Vehicles", "BookingVehicles"
WHERE "Vehicles"."id" = "BookingVehicles"."VehicleId" AND bookings.id = "BookingVehicles"."BookingId"
GROUP BY "Vehicles"."id"
) AS nested_vehicles
) AS vehicles
FROM
"Bookings" as bookings,
"Users" AS "customer",
"Users" AS "serviceProvider",
"BookingServiceProviders",
"Payments" AS "payments"
WHERE
bookings."isDeleted" IS NOT true AND
bookings."statusId" != 4 AND
bookings."customerId" = "customer"."id" AND "customer"."userTypeId" = 1 AND
bookings."id" = "BookingServiceProviders"."BookingId" AND
"BookingServiceProviders"."UserId" = "serviceProvider"."id" AND
bookings."id" = "payments"."bookingId"
GROUP BY
bookings."id",
"customer"."id",
"customer"."fullName"
Order by "startTime" ASC
不太确定在这里做什么。我可能只是单独返回服务,然后在外部格式化它们:/
【问题讨论】:
标签: sql json postgresql aggregate