I have these 4 tables: Scorecard, Section, Topic, Answer.
Each scorecard can have many sections. Each Section can have many topics and each Topic can have many answers.
I am looking to retrieve the data in the following form. Get all sections where scorecard id is equal to to a certain id i do this by left joining and it works so far. Then for each section I want to get of all it's topics and answers as well.
=> Expected Output
[{section1,
topics:[{topicName, answers:[{answerName}]}]},
{section2,
topics:[{topicName, answers:[{answerName}]}]}]
I made adjustments to my query and joint the tables correctly but the output data is not correctly organized as I was It to be.
Query:
SELECT sec."id",
sec."name" AS "sectionName",
to_json(topics) as "topics"
FROM "scorecard" sc
LEFT JOIN "section" sec ON sc."id" = sec."scorecardId"
LEFT JOIN (SELECT tp.*, to_json(answers.*) as "answers"
FROM "topic" tp
LEFT JOIN (SELECT ans."name" as "answerName", ans."topicId"
FROM "answer" ans) answers ON answers."topicId" = tp."id"
) topics
ON topics."sectionId" = sec."id"
WHERE sc."id" = $1
The current output:
[ id: 85,
sectionName: 'Consultation',
topics: {
id: 109,
name: 'Was the information correct?',
answers: [{ answerName: 'Yes', topicId: 109 }, answers: { answerName: 'NO', topicId: 109 }
]
},
id: 85,
sectionName: 'Consultation',
topics: {
id: 109,
name: 'Was the information correct?',
answers: { answerName: 'NO', topicId: 109 }
}]
My expected output:
[ {id: 85,
sectionName: 'Consultation',
topics: [{
id: 109,
name: 'Was the information correct?',
answers: [{ answerName: 'Yes', topicId: 109 },
{ answerName: 'NO', topicId: 109 }]
}]
} ]
I have also tried JOINING all entites as such:
SELECT sec."id",
sec."name" AS "sectionName",
tp."name" AS topics, ans."name" AS answers
FROM "scorecard" sc
LEFT JOIN "section" sec ON sc."id" = sec."scorecardId"
LEFT JOIN "topic" tp ON tp."sectionId" = sec."id"
LEFT JOIN "answer" ans ON ans."topicId"= tp."id"
WHERE sc."id" = $1
Output is not organized as it should be.
[
{
id: 91,
sectionName: 'Politeness',
topics: 'Was the agent polite with the client?',
answers: 'No'
},
{
id: 91,
sectionName: 'Politeness',
topics: 'Was the agent polite with the client?',
answers: 'Not everytime'
},
{
id: 91,
sectionName: 'Politeness',
topics: 'Was the agent polite with the client?',
answers: 'Yes'
}
]
You can join all four tables to get your result.
SELECT sec."id",
sec."name" AS "sectionName",
tp."name" AS topics, ans."name" AS answers
FROM "scorecard" sc
LEFT JOIN "section" sec ON sc."id" = sec."scorecardId"
LEFT JOIN "topic" tp on tp."sectionId" = sec."id"
LEFT JOIN "answer" ans on ans."topicId"=tp."id"
WHERE sc."id" = 30
Thanks #Luuk for creating the dbfiddle link.
select json_agg(x) AS result
from
(
SELECT sec."id",
sec."name" AS "sectionName",
json_agg(topics) as "topics"
FROM "scorecard" sc
LEFT JOIN "section" sec ON sc."id" = sec."scorecardId"
LEFT JOIN (SELECT tp.id,tp.name,tp."sectionId", json_agg(answers.*) as "answers"
FROM "topic" tp
LEFT JOIN (SELECT ans."name" as "answerName", ans."topicId"
FROM "answer" ans) answers ON answers."topicId" = tp."id"
group by tp.id,tp.name,tp."sectionId"
) topics
ON topics."sectionId" = sec."id"
WHERE sc."id" = 85
group by sec."id", sec."name"
)x
Output:
result
[{"id":85,"sectionName":"Consulation","topics":[{"id":109,"name":"Was the information correct?","sectionId":85,"answers":[{"answerName":"Yes","topicId":109}, <br> {"answerName":"NO","topicId":109}]}]}]
*db<>fiddle here149)
You are missing a JOIN condition to the table topics
SELECT sec."id",
sec."name" AS "sectionName",
topics
FROM "scorecard" sc
LEFT JOIN "section" sec ON sc."id" = sec."scorecardId"
LEFT JOIN (SELECT tp.*
FROM "topic" tp
WHERE tp."sectionId" = sec."id"
(SELECT tp.*
FROM "topic" tp
WHERE tp."sectionId" = sec."id"
)
) as topics ON topics.??? = ??? -- Here you should enter the relation
-- from topics to your section.
WHERE sc."id" = 30
EDIT:
With you (current) input I creates this DBFIDDLE
The output:
[
{
"id": 85,
"sectionName": "Consulation",
"topics": {
"id": 109,
"name": "Was the information correct?",
"sectionId": 85,
"answers": {
"answerName": "Yes",
"topicId": 109
}
}
},
{
"id": 85,
"sectionName": "Consulation",
"topics": {
"id": 109,
"name": "Was the information correct?",
"sectionId": 85,
"answers": {
"answerName": "NO",
"topicId": 109
}
}
}
]
Is there a way to query a nested object within a document in CosmosDB when there are multiple nested items with same id:
{
id: "GUID",
"items"[
{
"item": {
"item_id": "123456",
"order_name": "name1"
},
"item": {
"item_id": "123456",
"order_name": "name2",
}
}]
}
Id be looking to check the item_id and pull back that item object. Using the query SELECT c.item FROM c WHERE c.item.item_id = '123456' will only work if there is only one item but with more than one the query does not return anything. Using the query SELECT * FROM c WHERE c.item.item_id = '123456' doesn't bring back anything either.
I'm not sure I fully understand your question but here a couple of ways to work with nested queries:
Option 1:
SELECT
c.id,
items
FROM c
JOIN (SELECT
b.item_id,
b.order_name
FROM b WHERE b.parentID = c.id) AS items
The query will return the "items" field as an object
Option 2:
SELECT
c.id,
ARRAY (
SELECT
b.item_id,
b.order_name
FROM b WHERE b.parentID = c.id)
) AS items
FROM c
The query will return the "items" field as an array of objects
Hello everyone, I have the following query below which contains a sub query:
SELECT g.id, g.name, data.permissions, gp.has_permission
FROM groups g
RIGHT JOIN groups_permissions gp ON gp.group_id = g.id
RIGHT JOIN (SELECT p.id, array_to_json(array_agg(to_json(p.*)))
FROM permissions p
GROUP BY p.id) AS data (id, permissions) ON (gp.permission_id = data.id)
WHERE g.id=1
This query returns the result bellow:
[
{
"id": "7a588463-1780-459a-9646-8f19e9cb6ded",
"name": "Administradores",
"permissions": [
{
"id": "bf9d5ee3-d554-4faa-9cf4-9c60acb79801",
"name": "Criar Grupos",
"slug": "criar-grupos",
"created_at": "2020-12-07T00:50:05.017783",
"updated_at": "2020-12-07T00:50:05.017783"
}
],
"has_permission": true
}
]
I would like to have the has_permission field inside the object in the permissions array.
Could someone help merge that field with the object?
Thank you for now.
Don't you just need to add has_permission to the json subrecord?
SELECT g.id, g.name, data.permissions
FROM groups g
RIGHT JOIN groups_permissions gp ON gp.group_id = g.id
RIGHT JOIN (SELECT p.id, array_to_json(array_agg(to_json(p.*, gp.has_permission)))
FROM permissions p
GROUP BY p.id) AS data (id, permissions) ON (gp.permission_id = data.id)
WHERE g.id=1
I'm primarily trying to see how would you perform inner join here.
SELECT * From "Users" as biz
INNER JOIN "Deals" as d
ON biz.id = d."UserId"
WHERE (biz.latitude BETWEEN 18 AND 21)
AND (biz.longitude BETWEEN -78 AND -73);
this is what I got from documentation... but not sure how to proceed further
Deals.find({ where: { }, include: [User]})
For inner join all you need is required : true :
Deals.find({
where: { },
include: [{
model : User ,
required : true // This will make your inner join
}]})
NOTE : Use findAll or findOne instead of just find
I want to get a JSON object formatted similar to this:
{
"username": "USERNAME",
"teamname": "TEAMNAME",
"logs": [
{
"log": {
"log_id": 29,
"person_id": 3,
"activity_id": 3,
"shoe_id": null,
"logdate": "2016-11-29",
"distance": null,
"activitytime": null,
"sleep": null,
"heartrate": null,
"logtitle": null,
"description": null
},
"activity": "Swim",
"comments": {
"comment_id": 1,
"description": "This is a comment",
"person_id": 1,
"log_id": 29
}
}]
}
Currently I have everything formatted correctly except the comments. Here is the SQL query I am using:
SELECT p.username, t.teamname, json_agg(json_build_object('log', l.*, 'comments', c.*, 'activity', a.activity)) as logs
FROM person_tbl p
INNER JOIN log_tbl l ON p.person_id = l.person_id
INNER JOIN activity_tbl a ON l.activity_id = a.activity_id
INNER JOIN comment_tbl c ON c.log_id = l.log_id
INNER JOIN person_team_tbl pt ON p.person_id = pt.person_id
INNER JOIN team_tbl t on t.team_id = pt.team_id
WHERE t.team_id = 5
AND l.logdate > NOW()::date - 7
GROUP BY p.username, t.teamname
ORDER BY p.username
I'm having trouble getting the comments of each log. Right now, it is returning every comment and repeating the logs (they are not associated).
Also, how could I get this query to return the username and teamname when everything else is null (like when there are no logs in the past week)?
Without an SQLfiddle we do not know what your data (and structure) is so it is difficult to answer your question.
For the NULL case - please modify the WHERE clause like this (deliberately not using COALESCE)
WHERE t.team_id = 5 AND (l.logdate IS NULL OR l.logdate > NOW()::date - INTERVAL '7 day')