我在使用 SQL 生成 JSON 时遇到了一些困难。
当使用 ORDER BY exercise_instruction.rank 结果看起来像
with activities_result AS (
SELECT
activities.id,
json_strip_nulls(
json_build_object (
'id',
activities.id,
'activity_type',
activities.activity_type,
'exercise_id',
activities.exercise_id,
'exercise_type',
exercises.exercise_type,
'name',
exercises.name,
'videos',
json_agg(
DISTINCT jsonb_build_object(
'id',
exercise_video_assets.id,
'url',
exercise_video_assets.url,
'quality',
exercise_video_assets.quality,
'asset_type',
exercise_video_assets.asset_type
)
) FILTER (
WHERE
exercise_video_assets.id IS NOT NULL
),
'instructions',
json_agg( -- Order by exercise_instruction.rank:
DISTINCT jsonb_build_object (
'id',
instructions.id,
'detail',
instructions.detail,
'rank',
exercise_instruction.rank
)
) FILTER (
WHERE
instructions.id IS NOT NULL
),
'images',
json_agg(
DISTINCT jsonb_build_object(
'id',
exercise_image_assets.id,
'url',
exercise_image_assets.url,
'quality',
exercise_image_assets.quality,
'asset_type',
exercise_image_assets.asset_type,
'width',
exercise_image_assets.width,
'height',
exercise_image_assets.height
)
) FILTER (
WHERE
exercise_image_assets.id IS NOT NULL
),
'name_cue',
json_build_object (
'id',
exercise_audio_assets.id,
'url',
exercise_audio_assets.url,
'asset_type',
exercise_audio_assets.asset_type,
'delay',
exercise_audio_assets.delay,
'duration',
exercise_audio_assets.duration
),
'volume',
json_build_object(
'id',
volumes.id,
'volume_type',
volumes.volume_type,
'time',
volumes.time,
'volume_cue',
CASE WHEN volume_audio_assets.id IS NULL THEN NULL ELSE json_build_object (
'id',
volume_audio_assets.id,
'url',
volume_audio_assets.url,
'asset_type',
volume_audio_assets.asset_type,
'delay',
volume_audio_assets.delay,
'duration',
volume_audio_assets.duration
) END
)
)
) as activities
FROM
activities
INNER JOIN exercises ON exercises.id = activities.exercise_id
INNER JOIN volumes ON volumes.id = activities.volume_id
LEFT JOIN exercise_audio_assets ON exercises.name_cue_id = exercise_audio_assets.id
LEFT JOIN exercise_video_assets ON exercises.id = exercise_video_assets.exercise_id
LEFT JOIN exercise_image_assets ON exercises.id = exercise_image_assets.exercise_id
LEFT JOIN exercise_instruction ON exercises.id = exercise_instruction.exercise_id
LEFT JOIN instructions ON exercise_instruction.instruction_id = instructions.id
LEFT JOIN volume_audio_assets ON volumes.id = volume_audio_assets.volume_id
GROUP BY
activities.id,
exercises.exercise_type,
exercises.name,
exercise_audio_assets.id,
volumes.id,
volume_audio_assets.id
)
SELECT * FROM activities_result WHERE activities_result.id = 2
输出看起来像这样:
{
"id": 2,
"activity_type": "ex",
"exercise_id": 1,
"exercise_type": "ex",
"name": "Exercise Name",
"videos": [
{
"id": 1,
"url": "***",
"quality": "low",
"asset_type": "video"
},
{
"id": 2,
"url": "***",
"quality": "medium",
"asset_type": "video"
},
{
"id": 3,
"url": "***",
"quality": "high",
"asset_type": "video"
}
],
"instructions": [
{
"id": 3,
"rank": 0,
"detail": "text1"
},
{
"id": 4,
"rank": 1,
"detail": "text2"
},
{
"id": 5,
"rank": 2,
"detail": "text3"
}
],
"images": [
{
"id": 1,
"url": "***",
"quality": "low",
"asset_type": "image"
},
{
"id": 2,
"url": "***",
"quality": "medium",
"asset_type": "image"
},
{
"id": 3,
"url": "***",
"quality": "high",
"asset_type": "image"
}
],
"name_cue": {
"id": 1,
"url": "***",
"asset_type": "audio",
"delay": 0,
"duration": 1.46
},
"volume": {
"id": 1,
"volume_type": "time",
"time": 45
}
}