Postgres: How to select rows, grouping by rows with same column field into one row, with pagination
0
votes
0
answers
43
views
I've a table, with fields like
| id | batchId | senderId | recipientId|
| -------- | -------------- | ------- |------|
| uuid1 | uuid | uuid5 | uuid7 |
| uuid2 | uuid | uuid5 | uuid8 |
| uuid3 | uuid2 | uuid6 | uuid9 |
I need to select rows with pagination, but handling rows with same batchId as one row,
and joining it into array, like
| batchId | senderId | recipientIds|
| -------- | -------------- | ------- |
{uuid} | {uuid5} | {uuid7, uuid8}
{uuid2} | {uuid6}| {uuid9}
It's a simplified version of table
Currently I'm doing it with query but it's quite heavy, and takes like 5 second to execute on db about 2m records. I'm using indexes, but that doesn't help.
Here below is query
SELECT "sendData"."id" AS "id"
, "sendData"."pictureLink" AS "pictureLink"
, "sendData"."isPaid" AS "isPaid"
, "sendData"."createdAt" AS "createdAt"
, "sendData"."updatedAt" AS "updatedAt"
, "sendData"."senderId" AS "senderId"
, "sendData"."recipient" AS "recipient"
, "sendData"."isAnonymous" AS "isAnonymous"
, "sendData"."recipientAccountId" AS "recipientAccountId"
, "sendData"."senderAccountId" AS "senderAccountId"
, "sendData"."senderPhotoUrl" AS "senderPhotoUrl"
, "sendData"."recipientPhotoUrl" AS "recipientPhotoUrl"
, "sendData"."isDeleted" AS "isDeleted"
, "sendData"."oldCategory" AS "oldCategory"
, "sendData"."batchId" AS "batchId"
, CONCAT("sender"."firstName", ' ', "sender"."lastName", ' ', "sender"."patronymic") AS sender
, json_build_object('id', "category"."id"
, 'createdAt', "category"."createdAt"
, 'updatedAt', "category"."updatedAt"
, 'name', "category"."name"
, 'baseName', "category"."baseName"
, 'emojiId', "category"."emojiId"
, 'text', "category"."text"
, 'isVisible', "category"."isVisible"
, 'isLocked', "category"."isLocked"
, 'widgetText', "category"."widgetText"
, 'emoji', json_build_object('id', "emoji"."id"
, 'createdAt', "emoji"."createdAt"
, 'updatedAt', "emoji"."updatedAt"
, 'unicode', "emoji"."unicode")
) as category
, (SELECT COALESCE(json_agg(
json_build_object(
'id', "reaction"."id"
, 'userAccountId', "reaction"."userAccountId"
, 'sendDataId', "reaction"."sendDataId"
, 'type', "reaction"."type"
)
), '[]')
FROM sendData_reactions as reaction
where reaction."sendDataId" = ANY (ids)) as reactions
, "recipientIds"
, "recipients"
, "ids"
FROM sendData as sendData
JOIN (SELECT "batchId",
"senderId",
json_agg(tableName."recipientAccountId") AS "recipientIds",
json_agg(tableName."recipient") AS "recipients",
array_agg(tableName.id) as "ids",
min(tableName.id::text)::uuid as "id",
tableName."createdAt"
FROM sendData as tableName
LEFT JOIN "user" as "sender"
ON "sender"."id" = tableName."senderId"
AND "sender"."groupId" = 'id-here'
and sender."deletedAt" is null
WHERE tableName."isDeleted" = false
AND "sender"."groupId" = 'id-here'
and sender."deletedAt" is null
AND tableName."isAnonymous" = false
GROUP BY "batchId", tableName."createdAt", "senderId"
ORDER BY tableName."createdAt" DESC
OFFSET 0 LIMIT 100) as groupped
ON sendData."id" = groupped."id"
AND sendData."createdAt" = groupped."createdAt"
LEFT JOIN "user" as "sender"
ON "sender"."id" = sendData."senderId"
LEFT JOIN "sendData_categories" as category
ON "category"."id" = sendData."categoryId"
LEFT JOIN "sendData_categories_emoji" as "emoji"
ON "emoji"."id" = "category"."emojiId"
WHERE sendData."groupId" = 'uuid'
AND sendData."isAnonymous" = false
AND sendData."isDeleted" = false
ORDER BY sendData."createdAt" DESC
OFFSET 0 LIMIT 10;
Asked by Sendoff74
(1 rep)
Nov 15, 2024, 03:09 AM
Last activity: Nov 15, 2024, 09:06 AM
Last activity: Nov 15, 2024, 09:06 AM