Is there way to return null valued rows when when querying joined table - sql

I have two tables: users table with id, name columns and events table with id, content and userId columns.
I am trying to query a table that return joined information from these two tables with name and events columns where events would represent an array of content fields corresponding to a user.
This is the query I am running:
select
name, group_concat(content) as events
from
users
left join
events on id = userId
group by
userId
order by
id
However rows with null values are not being returned except of just one row. What am I doing wrong?
Users table
[
{
"id": 1,
"name": "Hugo Powlowski"
},
{
"id": 2,
"name": "Jeremy Littel II"
},
{
"id": 3,
"name": "Eleanor King"
},
{
"id": 4,
"name": "Rogelio Jacobson"
},
{
"id": 5,
"name": "Jerald Rowe PhD"
},
{
"id": 6,
"name": "Robyn Tromp"
},
{
"id": 7,
"name": "Norman Zboncak"
},
{
"id": 8,
"name": "Mr. Kristy Orn"
},
{
"id": 9,
"name": "Mrs. Olivia Trantow"
},
{
"id": 10,
"name": "Daniel Lebsack"
}
]
Events table
[
{
"eventId": 3,
"content": "hello",
"userId": 7
},
{
"eventId": 12,
"content": "rulsan berden",
"userId": 1
}
]
Joined table
[
{
"name": "Hugo Powlowski",
"events": "rulsan berden"
},
{
"name": "Jeremy Littel II",
"events": null
},
{
"name": "Norman Zboncak",
"events": "hello"
}
]

You should group by the column in the parent table, not the table being left joined, so that the values will never be null.
So change GROUP BY userid to GROUP BY users.id.

Try to use a nested SELECT, this should return nullĀ for the users without any event:
select
u.name,
SELECT(
group_concat(content)
FROM
events
WHERE
userId = u.id
) as events
from
users u
order by
u.id

Related

Deserialise multiple objects into a select statment

In a table, I store multiple string records in several records.
declare #x nvarchar(max) = {
"totalSize": 1000,
"done": true,
"records": [
{
"attributes": {
"type": "Contract",
"url": ""
},
"Name": "Harpy",
"Job_Schedule_Date__c": null,
"EndDate": "2021-03-24",
"Account": {
"attributes": {
"type": "Account",
"url": ""
},
"Name": "Madison"
},
"ContractNumber": "12345",
"Related_Site__r": {
"attributes": {
"type": "Site__c",
"url": ""
},
"Name": "Jackson"
}
},
.
.
.
]
}
select * from openJson(#x, '$.records')
I am trying to use open JSON to unpack the records.
I am able to unpack a single record, but it doesn't unpack them into columns and need to unpack multiple records and join them.
Since each record only stores 1000 records, I need to join them up.
What I want is output like below as a Select
Name, Job_Schedule_Date__c, EndDate, AccountName, ContractNumber, RelatedSiteName
Harpy, null, 2021-03-24, Madison, 12345, Jackson

How to query in Array with Typeorm's Repository

This is the current repository code.
After joining the student and director tables in the attendance table, join the location table again in the student table, and join the schedule table in the director table to get the location information and date.
return await this.createQueryBuilder('tbl_attendance')
.leftJoin('tbl_attendance.student', 'student')
.leftJoin('student.location', 'location')
.select([
'student.gcn',
'student.id',
'student.name',
'tbl_attendance.period',
'location.name',
'tbl_attendance.state',
])
.leftJoin('tbl_attendance.director', 'director')
.leftJoin('director.schedule', 'schedule')
.where('location.floor= :floor', { floor: floor })
.andWhere('schedule.date= :date', { date: date })
.andWhere('tbl_attendance.state= :state', { state: state })
.getMany();
}
And this is the currently returned json
[
{
"state": "MOVE",
"period": 7,
"student": {
"id": 1,
"name": "anne",
"gcn": "1301",
"location": {
"name": "semina 2-1"
}
}
},
{
"state": "MOVE",
"period": 8,
"student": {
"id": 1,
"name": "anne",
"gcn": "1301",
"location": {
"name": "semina 2-1"
}
}
}
]
I wish it was returned like this.
[
{
"gcn": 1301,
"student_id": 3,
"student_name": "anne",
"student_attendance": [
{
"period" : 8
"location_name": null || "semina2-1",
"state": "MOVE"
},
{
"period": 9
"location_name": null || "semina2-1",
"state": "MOVE"
},
{
"period": 10
"location_name": null || "semina2-1",
"state":"MOVE"
}
]
}
]
How do I get the student's place id and status for each class separately as an array?
Perhaps you should query the student table and join the related entities onto that one. That way, your result would be an array of students, with each its own array of attendance object.
Now, when it comes to joining with TypeORM, joined tables will always be nested in the resulting object, as an array or an object for one-to-many and many-to-one relationships respectively. There is no straightforward way to control the shape of the resulting data other than mapping it manually.

Problem with using of FOR JSON AUTO in SQL Server

I am using FOR JSON AUTO in SQL server database, to convert my query's result to the JSON format.
in my query, I joined order table to two other tables.
SELECT
orders.[Code], orders.[Total], orders.[Discount],
customer.[Name], customer.[PhoneNumber],
store.[Name], store.[Address]
FROM
Orders orders
INNER JOIN
Customers customer ON (orders.[CustomerID] = customer.[ID])
INNER JOIN
Stores store ON (orders.[StoreID] = store.[ID])
FOR JSON AUTO
Result:
[
{
"Code": "1528",
"Total": 5000,
"Discount": 20,
"customer": [
{
"Name": "Alex",
"PhoneNumber": "(548) 123-5555",
"store": [
{
"Name": "Apple",
"Address": "E. Santa rd"
}
]
}
]
},
{
"Code": "1687",
"Total": 3000,
"Discount": 10,
"customer": [
{
"Name": "John",
"PhoneNumber": "(226) 354-7896",
"store": [
{
"Name": "Sony",
"Address": "W. Atlantic ave"
}
]
}
]
}
]
But it's not correct, because in this scenario customer and store are sibling and they have same parent, and both of them joined with the order table directly, correct JSON must be such as this:
[
{
"Code": "1528",
"Total": 5000,
"Discount": 20,
"customer": [
{
"Name": "Alex",
"PhoneNumber": "(548) 123-5555"
}
],
"store": [
{
"Name": "Apple",
"Address": "E. Santa rd"
}
]
},
{
"Code": "1687",
"Total": 3000,
"Discount": 10,
"customer": [
{
"Name": "John",
"PhoneNumber": "(226) 354-7896"
}
],
"store": [
{
"Name": "Sony",
"Address": "W. Atlantic ave"
}
]
}
]
how can I do that? Are there any option for this in SQL? (I don't want to use inner select.)
If there are one-to-one relationships between Orders and Customer and between Orders and Store then you can make the desired output by using PATH option and dot-separated column names:
SELECT
orders.[Code], orders.[Total], orders.[Discount],
customer.[Name] AS [Customer.Name], customer.[PhoneNumber] AS [Customer.PhoneNumber],
store.[Name] AS [Store.Name], store.[Address] AS [Store.Address]
FROM
Orders orders
INNER JOIN
Customers customer ON (orders.[CustomerID] = customer.[ID])
INNER JOIN
Stores store ON (orders.[StoreID] = store.[ID])
FOR JSON PATH
But if there are one-to-many relationships then you have to use nested queries:
SELECT
orders.[Code], orders.[Total], orders.[Discount],
(SELECT [Name], [PhoneNumber] FROM Customers WHERE Customers.ID=Orders.CustomerID FOR JSON AUTO) AS Customers,
(SELECT [Name], [Address] FROM Stores WHERE Stores.ID=Orders.StoreID FOR JSON AUTO) AS Stores
FROM
Orders orders
FOR JSON AUTO

How to limit results of preload of gorm

type Item struct {
TopicId int `json:"topic_id"`
Topic *Topic `json:"topic,omitempty"`
BotId int `json:"bot_id"`
URL string `gorm:"varchar(250);unique" json:"url"`
Title string `gorm:"varchar(250)" json:"title"`
}
type Topic struct {
Title string `gorm:"varchar(250)" json:"title"`
Items []*Item `json:"items,omitempty"`
}
Here is the two models. I want to query the Topics with each have 5 latest items.
Without the limit for items, I could do this by,db.Model(&Topic{}).Preload("Items").
When I try to add some limit conditions to items:
db.Model(&Topic{}).Preload("Items", func(db *gorm.DB) *gorm.DB {
return db.Order("title DESC").Limit(5)
})
It will return 5 items in total, not 5 items for each topic.
Actual result:
"records": [
{
"id": 4,
"created_on": "2019-08-11T10:28:54.910022Z",
"title": "Topic 1",
},
{
"id": 5,
"created_on": "2019-08-11T10:29:26.952614Z",
"title": "Programming",
},
{
"id": 6,
"created_on": "2019-08-11T10:34:16.040229Z",
"title": "Topic 3",
"items": [
{
"id": 1,
"created_on": "2019-08-27T14:23:17.766055Z",
"topic_id": 6,
"title": "Title One",
},
......
{
"id": 5,
"created_on": "2019-08-27T14:23:17.766055Z",
"topic_id": 6,
"title": "Title five",
}
]
Expected results:
"records": [
{
"id": 4,
"created_on": "2019-08-11T10:28:54.910022Z",
"title": "Topic 1",
},
{
"id": 5,
"created_on": "2019-08-11T10:29:26.952614Z",
"title": "Programming",
"items": [
{
"id": 6,
"created_on": "2019-08-27T14:23:17.766055Z",
"topic_id": 5,
"title": "Title six",
},
......
{
"id": 10,
"created_on": "2019-08-27T14:23:17.766055Z",
"topic_id": 5,
"title": "Title ten",
}]
},
{
"id": 6,
"created_on": "2019-08-11T10:34:16.040229Z",
"title": "Topic 3",
"items": [
{
"id": 1,
"created_on": "2019-08-27T14:23:17.766055Z",
"topic_id": 6,
"title": "Title One",
},
......
{
"id": 5,
"created_on": "2019-08-27T14:23:17.766055Z",
"topic_id": 6,
"title": "Title five",
}
]
The actual sql it generated is SELECT * FROM "item" WHERE "topic_id" IN (6,4,5) DESC LIMIT 5
It's obvious not the results I want, so how should I get the expected result with gorm?
For postgresql only.
type Topic struct {
Title string `gorm:"varchar(250);PRIMARY KEY" json:"title"`
// assume the foreign key between two tables are both Title.
Items []*Item `gorm:"foreignkey:Title;association_foreignkey:Title" json:"items,omitempty"`
}
var topics []Topic
db.Model(&Topic{}).Preload("Items", func(tx *gorm.DB) *gorm.DB {
return tx.Joins(`JOIN LATERAL (
SELECT i.url FROM items i WHERE i.title = items.title ORDER BY i.topic_id DESC LIMIT 5
) AS foo ON foo.url = items.url`)
}).Find(&topics)
You could use lateral join to limit the rows for each different value. After retrieving the rows of topics, gorm then send the following query to get the related rows from items:
SELECT "items".*
FROM "items"
JOIN LATERAL
(SELECT i.url
FROM items i
WHERE i.title = items.title
ORDER BY i.topic_id DESC
LIMIT 5) AS foo ON foo.url = items.url
WHERE ("title" IN (?))

How to filter Cosmos DB data based on value of an element in an array of values Using SQL API

I have a cosmosDB collection with below Data in it.
I have to find out the data only for EVENT named ABC and its value using SQL query.
[
{
"ID": "01XXXXX",
"EVENTS": [
{
"Name": "ABC",
"Value": 0
},
{
"Name": "XYZ",
"Value": 4
},
{
"Name": "PQR",
"Value": 5
}
]
},
{
"ID": "02XXXXX",
"EVENTS": [
{
"Name": "ABC",
"Value": 1
},
{
"Name": "XYZ",
"Value": 2
},
{
"Name": "PQR",
"Value": 3
}
]
}
]
I have tried the below code but it is not working since EVENT is an array.
SELECT * FROM c where c.EVENTS.Name = 'ABC'
Is there any way to find filter out the data only with Event Name as ABC using SQL?
Try using join
SELECT c FROM c
join l in c.EVENTS
where l.Name = 'ABC'