自联接查询中的 JSON 聚合

sçu*_*uçu 5 sql-server aggregate json

我在 SQL Server 中有一个数据库。我需要对表本身进行连接查询,menutable.

但是,结果集中完全没有左表。我只从正确的表中得到结果。

此外,我无法像在 PostgreSQL 中那样将右表聚合到类似对象的数组中,并且不能有group byed左表 id结果集,我group by用于左表 id

我可以在 PostgreSQL 中实现这一点我执行以下查询并得到我期望和想要的。我使用 PostgreSQL 的json_agg聚合函数:

select mt1.*, json_agg(mt2.*) 
from menutable mt1
join menutable mt2 on mt1.id = mt2.üstmenuid
group by mt1.id;
Run Code Online (Sandbox Code Playgroud)

结果:

    {
      "results": [
        {
          "id": 4,
          "menuadi": "Ortak Haberler",
          "üstmenuid": null,
          "json_agg": [
            {
              "id": 5,
              "menuadi": "Lorem ipsum dolor sit amet, consectetur adipiscing elit",
              "üstmenuid": 4
            },
            {
              "id": 6,
              "menuadi": "Sed eget ipsum sit amet massa varius commodo",
              "üstmenuid": 4
            }
          ]
        },
        {
          "id": 1,
          "menuadi": "Ortak Konulu Mansetler",
          "üstmenuid": null,
          "json_agg": [
            {
              "id": 2,
              "menuadi": "In hac habitasse platea dictumst",
              "üstmenuid": 1
            },
            {
              "id": 3,
              "menuadi": "Nullam molestie augue sit amet magna bibendum imperdiet.",
              "üstmenuid": 1
            }
          ]
        }
      ]
    }
Run Code Online (Sandbox Code Playgroud)

在 SQL Server 中,我运行以下几乎相同的查询,除了表名案例,缺少右表行的聚合函数:

SELECT  mt1.*, mt2.* 
FROM dbo.MenuTable AS mt1
JOIN dbo.MenuTable AS mt2 ON mt1.ID = mt2.UstMenuID;
GROUP BY mt1.ID, mt1.MenuAdi, mt1.UstMenuID, mt2.ID, mt2.MenuAdi, mt2.UstMenuID
Run Code Online (Sandbox Code Playgroud)

结果集(左表完全丢失):

 {
  "results": [
    {
      "ID": 2,
      "MenuAdi": "In hac habitasse platea dictumst",
      "UstMenuID": 1
    },
    {
      "ID": 3,
      "MenuAdi": "Nullam molestie augue sit amet magna bibendum imperdiet.",
      "UstMenuID": 1
    },
    {
      "ID": 5,
      "MenuAdi": "Lorem ipsum dolor sit amet, consectetur adipiscing elit",
      "UstMenuID": 4
    },
    {
      "ID": 6,
      "MenuAdi": "Sed eget ipsum sit amet massa varius commodo",
      "UstMenuID": 4
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)

我应该采取什么聚合方法来获得我JOIN在上面的 PostgreSQL 示例中构建的预期结果?

注意:菜单名称在大小写方面略有不同。现在我正在尝试使用 Sequelize,但它发出警告 SQL Server 不支持将表与自身相关联,我需要将JOIN.

Sql*_*Zim 1

postgres:http://rextester.com/TAYO71756

\n\n
create table menutable (\n    id int primary key\n  , menuadi text\n  , ustmenuid int null references menutable (id)\n);\n  insert into menutable values\n (1,\'Ortak Konulu Mansetler\',null)\n,(2,\'Kayseri Deki Bombal\xc4\xb1 Sald\xc4\xb1r\xc4\xb1n\xc4\xb1n Yans\xc4\xb1malar\xc4\xb1\',1)\n,(3,\'Say\xc4\xb1n Cumhurba\xc5\x9fkan\xc4\xb1m\xc4\xb1z\xc4\xb1n Trabzon Daki A\xc3\xa7\xc4\xb1klamalar\xc4\xb1n\xc4\xb1n Yans\xc4\xb1malar\xc4\xb1\',1)\n,(4,\'Ortak Haberler\',null)\n,(5,\'Say\xc4\xb1n Han\xc4\xb1mefendinin Trabzonda \xc5\x9eehit Aileleriyle Bir Araya Gelmesinin Yans\xc4\xb1malar\xc4\xb1\',4)\n,(6,\'T\xc3\xbcrk Meslekta\xc5\x9flar\xc4\xb1m\xc4\xb1z\xc4\xb1n Yan\xc4\xb1nday\xc4\xb1z\',4);\n\nselect mt1.*, json_agg(mt2.*) \nfrom menutable mt1\njoin menutable mt2 on mt1.id = mt2.ustmenuid\ngroup by mt1.id;\n
Run Code Online (Sandbox Code Playgroud)\n\n

Postgres 结果

\n\n
+----+------------------------+-----------+-----------------------------------------------------------------------------------------------------------------------+\n| id |        menuadi         | ustmenuid |                                                       json_agg                                                        |\n+----+------------------------+-----------+-----------------------------------------------------------------------------------------------------------------------+\n|  1 | Ortak Konulu Mansetler | NULL      | [{"id":2,"menuadi":"Kayseri Deki Bombal\xc4\xb1 Sald\xc4\xb1r\xc4\xb1n\xc4\xb1n Yans\xc4\xb1malar\xc4\xb1","ustmenuid":1}                                       |\n|    |                        |           | , {"id":3,"menuadi":"Say\xc4\xb1n Cumhurba\xc5\x9fkan\xc4\xb1m\xc4\xb1z\xc4\xb1n Trabzon Daki A\xc3\xa7\xc4\xb1klamalar\xc4\xb1n\xc4\xb1n Yans\xc4\xb1malar\xc4\xb1","ustmenuid":1}]               |\n|  4 | Ortak Haberler         | NULL      | [{"id":5,"menuadi":"Say\xc4\xb1n Han\xc4\xb1mefendinin Trabzonda \xc5\x9eehit Aileleriyle Bir Araya Gelmesinin Yans\xc4\xb1malar\xc4\xb1","ustmenuid":4} |\n|    |                        |           | ,  {"id":6,"menuadi":"T\xc3\xbcrk Meslekta\xc5\x9flar\xc4\xb1m\xc4\xb1z\xc4\xb1n Yan\xc4\xb1nday\xc4\xb1z","ustmenuid":4}]                                             |\n+----+------------------------+-----------+-----------------------------------------------------------------------------------------------------------------------+\n
Run Code Online (Sandbox Code Playgroud)\n\n
\n\n

SQL Server 2014:http://rextester.com/DPK57600

\n\n

rextester 当前运行的是 sql server 2014,它没有本机 json 支持。\n相反,我将使用dbo.FlattenedJSON()通过TSQL 从 SQL Server 查询生成 JSON 文档 - Phil Factor

\n\n
create table menutable (\n    id int primary key\n  , menuadi nvarchar(128)\n  , ustmenuid int null references menutable (id)\n);\n  insert into menutable values\n (1,\'Ortak Konulu Mansetler\',null)\n,(2,\'Kayseri Deki Bombal\xc4\xb1 Sald\xc4\xb1r\xc4\xb1n\xc4\xb1n Yans\xc4\xb1malar\xc4\xb1\',1)\n,(3,\'Say\xc4\xb1n Cumhurba\xc5\x9fkan\xc4\xb1m\xc4\xb1z\xc4\xb1n Trabzon Daki A\xc3\xa7\xc4\xb1klamalar\xc4\xb1n\xc4\xb1n Yans\xc4\xb1malar\xc4\xb1\',1)\n,(4,\'Ortak Haberler\',null)\n,(5,\'Say\xc4\xb1n Han\xc4\xb1mefendinin Trabzonda \xc5\x9eehit Aileleriyle Bir Araya Gelmesinin Yans\xc4\xb1malar\xc4\xb1\',4)\n,(6,\'T\xc3\xbcrk Meslekta\xc5\x9flar\xc4\xb1m\xc4\xb1z\xc4\xb1n Yan\xc4\xb1nday\xc4\xb1z\',4);\n\nselect mt1.*, [json_agg]=dbo.FlattenedJson (\n      ( select mt2.*\n        from menutable mt2\n        where mt2.ustmenuid = mt1.id\n        for xml path, root\n        )\n    )\nfrom menutable mt1\nwhere mt1.ustmenuid is null\n
Run Code Online (Sandbox Code Playgroud)\n\n

结果:

\n\n
+----+------------------------+-----------+---------------------------------------------------------------------------------------------------------------------------+\n| id |        menuadi         | ustmenuid |                                                         json_agg                                                          |\n+----+------------------------+-----------+---------------------------------------------------------------------------------------------------------------------------+\n|  1 | Ortak Konulu Mansetler | NULL      | [                                                                                                                         |\n|    |                        |           | {"id":"2","menuadi":"Kayseri Deki Bombali Saldirinin Yansimalari","ustmenuid":"1"},                                       |\n|    |                        |           | {"id":"3","menuadi":"Sayin Cumhurbaskanimizin Trabzon Daki A\xc3\xa7iklamalarinin Yansimalari","ustmenuid":"1"}                  |\n|    |                        |           | ]                                                                                                                         |\n|  4 | Ortak Haberler         | NULL      | [                                                                                                                         |\n|    |                        |           | {"id":"5","menuadi":"Sayin Hanimefendinin Trabzonda Sehit Aileleriyle Bir Araya Gelmesinin Yansimalari","ustmenuid":"4"}, |\n|    |                        |           | {"id":"6","menuadi":"T\xc3\xbcrk Meslektaslarimizin Yanindayiz","ustmenuid":"4"}                                                 |\n|    |                        |           | ]                                                                                                                         |\n+----+------------------------+-----------+---------------------------------------------------------------------------------------------------------------------------+\n
Run Code Online (Sandbox Code Playgroud)\n