如何使用2个联接进行“ FOR JSON”

Yol*_*ofy 2 sql-server json

我无法使它正常工作。我有4个表格:产品,供应商,X_Product_Suppliers和注释。我想全部查询它们,并使用以下查询将它们放入JSON:

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
Run Code Online (Sandbox Code Playgroud)

由于某些原因,sql-server会将注释嵌套在供应商而不是产品下面:

   {  
      "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
               }
            ]
         }
      ]
   }
Run Code Online (Sandbox Code Playgroud)

我真正想要的是:

   {  
      "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
               }
            ]
   }
Run Code Online (Sandbox Code Playgroud)

我该怎么做呢?

Muh*_*eeb 7

如果有人在寻找答案,这是我写的简单查询。根据您的架构更改查询,它应提供适当的结构化结果。

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
Run Code Online (Sandbox Code Playgroud)


Y.B*_*.B. 0

SQL Server 会将结果表转换为 JSON,其中列的顺序与语句中出现的顺序相同SELECT。它不会对列分组做出任何假设。为了帮助它,供应商和评论可以预先排列成每个产品的 JSON 对象:

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.*,
    (SELECT Suppliers.*
     FROM Suppliers
     INNER JOIN X_Product_Supplier ON X_Product_Supplier.SupplierId = Suppliers.Id
     WHERE X_Product_Supplier.ProductId = Products.Id
     FOR JSON AUTO, TYPE) As Suppliers,
    (SELECT Comments.*
     FROM Comments
     WHERE Comments.ProductId = Products.Id
     FOR JSON AUTO, TYPE) As Comments
FROM Products
FOR JSON AUTO
Run Code Online (Sandbox Code Playgroud)
  • 在 XML 上进行测试,因为我目前无法访问 SQL Server 2016。如果这不起作用,请告诉我。