我正在努力执行以下SQL查询:
有一个表格 data_tracks ,其中包含描述行程的坐标。每个旅程都由 trip_log_id 唯一标识。到达旅程的目的地后,用户需要参与调查。调查的答案存储在表 crowd_sourcing_answers 中。每个答案都属于一个问题,位于表 crowd_sourcing_questions 中。
我编写了两个SQL查询-一个以JSON的形式获取旅程的所有要点,另一个是获取所有的问题-答案对:
查询获取旅行的所有问题答案对:
SELECT json_agg(answer_single_trip)
FROM (SELECT json_agg(
json_build_object(
'tripId', trip_log_id,
'question', qt.question,
'answeringOption', qt."answeringOptions",
'answer', at.answer
)
) as crowdsourcing
FROM crowd_sourcing_questions as qt
INNER JOIN crowd_sourcing_answers as at ON at.crowd_sourcing_question_id = qt.id
GROUP BY trip_log_id) answer_single_trip;
及其输出:
[
{
"crowdsourcing": [
{
"tripId": 92,
"question": "Gab es auf der Strecke teilweise schlecht befahrbare Streckenabschnitte?",
"answeringOption": [
"Ja",
"Nein"
],
"answer": "2"
}
]
},
{
"crowdsourcing": [
{
"tripId": 91,
"question": "Gab es auf der Strecke teilweise schlecht befahrbare Streckenabschnitte?",
"answeringOption": [
"Ja",
"Nein"
],
"answer": "1"
}
]
},
{
"crowdsourcing": [
{
"tripId": 90,
"question": "Gab es auf der Strecke teilweise schlecht befahrbare Streckenabschnitte?",
"answeringOption": [
"Ja",
"Nein"
],
"answer": "0"
}
]
}
]
查询获取属于旅行的所有点:
SELECT json_agg(
json_build_object(
'tripId', trip_log_id,
'trackId', id,
'recorded_at', created_at,
'latitude', latitude,
'longitude', longitude
)
) as trips
FROM data_tracks
GROUP by trip_log_id;
及其输出:
[
[
{
"trip_log_id": 91,
"recorded_at": "2018-10-05T14:11:44.847",
"latitude": 52.5242370846803,
"longitude": 13.3443558528637
},
{
"trip_log_id": 91,
"recorded_at": "2018-10-05T14:11:44.911",
"latitude": 52.5242366166393,
"longitude": 13.3443558656828
}
],
[
{
"trip_log_id": 90,
"recorded_at": "2018-10-05T13:28:24.452",
"latitude": 52.5242370846803,
"longitude": 13.3443558528637
},
{
"trip_log_id": 90,
"recorded_at": "2018-10-05T13:28:24.489",
"latitude": 52.5242366166393,
"longitude": 13.3443558656828
}
]
]
现在,我需要合并这两个结果,以便每个旅程ID都有一个JSON对象,其中包含问答对(键:“ crowdsourcing”;数组)和旅程点(键:“ trip”) ;数组)。举一个例子:
[
{ // DATA FOR TRIP 1
"crowdsourcing": [
{
"question": "Bitte bewerten Sie die Sicherheit der Radroute!",
"answeringOption": [
"Sehr sicher",
"Eher sicher",
"Neutral",
"Eher unsicher",
"Sehr unsicher"
],
"answer": "2"
},
{
"question": "Würden Sie die gefahrene Route anderen Radfahrenden weiterempfehlen?",
"answeringOption": [
"Ja",
"Nein"
],
"answer": "1"
}
],
"trip": [
{
"recorded_at": "2018-10-11T15:16:33",
"latitude": 52.506785999999998,
"longitude": 13.398065000000001
},
{
"recorded_at": "2018-10-11T15:16:32.969",
"latitude": 52.50647,
"longitude": 13.397856000000001
},
{
"recorded_at": "2018-10-11T15:16:32.936",
"latitude": 52.506166,
"longitude": 13.397593000000001
}
]
},
{ // DATA FOR TRIP 2
"crowdsourcing": [
{
"question": "Bitte bewerten Sie die Sicherheit der Radroute!",
"answeringOption": [
"Sehr sicher",
"Eher sicher",
"Neutral",
"Eher unsicher",
"Sehr unsicher"
],
"answer": "2"
}
],
"trip": [
{
"recorded_at": "2018-10-11T15:33:33.971999",
"latitude": 52.506785999999998,
"longitude": 13.398065000000001
},
{
"recorded_at": "2018-10-11T15:33:33.929",
"latitude": 52.50647,
"longitude": 13.397856000000001
}
]
}
]
我创建了一个查询,请参阅DB Fiddle。但是,它返回两个数组(问题-答案对,行程点)内的重复记录。我以为它必须与JOIN
做些事情,但是我所有的尝试都失败了。
答案 0 :(得分:2)
在子查询中,您已经将trip_log_id
包含在json部分中。但是,如果将它们放在单独的列中,您将有机会将两个部分都对着它:
SELECT
json_agg(
json_build_object('crowdsourcing', cs.json_agg, 'trip', t.json_agg)
)
FROM
(
SELECT
trip_log_id, -- 1
json_agg(
json_build_object('question', question, 'answeringOption', "answeringOptions", 'answer', answer)
)
FROM
crowd_sourcing_answers csa
JOIN crowd_sourcing_questions csq ON csa.crowd_sourcing_question_id = csq.id
GROUP BY trip_log_id
) cs
JOIN -- 2
(
SELECT
trip_log_id, -- 1
json_agg(
json_build_object('recorded_at', created_at, 'latitude', latitude, 'longitude', longitude)
)
FROM data_tracks
GROUP by trip_log_id
) t
USING (trip_log_id) -- 2
trip_log_id
其他:请注意,在postgres中,所有列名称均应不包含任何大写字母。我建议将addionalOptions
重命名为additional_options
之类。这样就不需要额外的"
字符了。