我正在处理以下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
}
]
]目标
现在,我需要合并这两个结果,这样每个trip ID都有一个JSON对象,包含问答对(键:“众包”;数组)和旅行点(键:" 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。然而,它返回两个数组中的重复记录(问答对、trip点)。我在想,它必须对JOIN做些什么,但我所有的试验都失败了。
发布于 2018-11-02 16:03:59
在您的子查询中,您已经将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的名称。这样就不需要额外的"字符了。
https://stackoverflow.com/questions/53121601
复制相似问题