I can't get this to work properly. I have 4 tables: Products, Suppliers, X_Product_Suppliers and Comments. I want to query them all and put them into JSON using the following query:
WITH Products (Id, Name, Price) As (
SELECT 1, 'First Product', 10
), Suppliers (Id, Name) As (
SELECT 1, 'Factory1' UNION ALL
SELECT 2, 'Factory2'
), Comments (Id, [Text], ProductId) As (
SELECT 1, 'Good Product', 1 UNION ALL
SELECT 2, 'Fantastic!' , 1
), X_Product_Supplier (ProductId, SupplierId) As (
SELECT 1, 1 UNION ALL
SELECT 1, 2
)
SELECT Products.*, Suppliers.*, Comments.* FROM Products
LEFT OUTER JOIN X_Product_Supplier ON X_Product_Supplier.ProductId = Products.Id
LEFT OUTER JOIN Suppliers ON X_Product_Supplier.SupplierId = Suppliers.Id
LEFT OUTER JOIN Comments ON Comments.ProductId = Products.Id
FOR JSON AUTO
For some reason sql-server will nest the comments under the supplier instead of under the product:
{
"Id":1,
"Name":"First Product",
"Price":"10",
"Suppliers":[
{
"Id":1,
"Name":"Factory1",
"Comments":[ //THIS SHOULD BE UNDER PRODUCT, NOT SUPPLIER
{
"Id":1,
"Text":"Good Product",
"ProductId":1
},
{
"Id":2,
"Text":"Fantastic!",
"ProductId":1
}
]
},
{
"Id":2,
"Name":"Factory2",
"Comments":[ //THIS IS NOW DUPLICATE
{
"Id":1,
"Text":"Good Product",
"ProductId":1
},
{
"Id":2,
"Text":"Fantastic!",
"ProductId":1
}
]
}
]
}
What I actually want is this:
{
"Id":1,
"Name":"First Product",
"Price":"10",
"Suppliers":[
{
"Id":1,
"Name":"Factory1"
},
{
"Id":2,
"Name":"Factory2"
}
],
"Comments":[
{
"Id":1,
"Text":"Good Product",
"ProductId":1
},
{
"Id":2,
"Text":"Fantastic!",
"ProductId":1
}
]
}
How do I do this?
Multiple joins can be described as a query containing joins of the same or different types used more than once, thus giving them the ability to combine multiple tables.
A JOIN clause is used to combine rows from two or more tables, based on a related column between them. Notice that the "CustomerID" column in the "Orders" table refers to the "CustomerID" in the "Customers" table. The relationship between the two tables above is the "CustomerID" column.
The simplest way to combine two tables together is using the keywords UNION or UNION ALL. These two methods pile one lot of selected data on top of the other. The difference between the two keywords is that UNION only takes distinct values, but UNION ALL keeps all of the values selected.
SQL Server supports many kinds of different joins including INNER JOIN, SELF JOIN, CROSS JOIN, and OUTER JOIN. In fact, each join type defines the way two tables are related in a query. OUTER JOINS can further be divided into LEFT OUTER JOINS, RIGHT OUTER JOINS, and FULL OUTER JOINS.
If anyone else is looking for answer here is simple query I have written. Change the query as per your schema and it should give your proper structured result.
SELECT Products.*,
(SELECT Suppliers.*
FROM Suppliers
WHERE Suppliers.Id = Products.SuppliersId
FOR JSON AUTO) As Suppliers,
(SELECT Comments.*
FROM Comments
WHERE Comments.ProductId = Products.Id
FOR JSON AUTO) As Comments
FROM Products
FOR JSON AUTO
I know its late, but i faced with same problem but the answers could not help in filtering the null values in where clause, my solution below
SELECT Products.*,
Suppliers.Id as [Suppliers.Id],
Suppliers.Name as [Suppliers.Name],
Comments.Id as [Comments.Id],
Comments.Text as [Comments.Text],
Comments.ProductId as [Comments.ProductId]
FROM Products
LEFT OUTER JOIN X_Product_Supplier ON X_Product_Supplier.ProductId = Products.Id
LEFT OUTER JOIN Suppliers ON X_Product_Supplier.SupplierId = Suppliers.Id
LEFT OUTER JOIN Comments ON Comments.ProductId = Products.Id
FOR JSON PATH
Tested and working on SQL SERVER 2017
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With