AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 266738
Accepted
youcantryreachingme
youcantryreachingme
Asked: 2020-05-08 21:26:04 +0800 CST2020-05-08 21:26:04 +0800 CST 2020-05-08 21:26:04 +0800 CST

外部查询是 UNION 一部分的 JSON 路径的子查询导致字符串而不是 JSON

  • 772

请耐心等待 - 示例代码已经发生了一些事情,我将尽我所能在下面解释它。

with ENTITIES as (
select [name] as entityName from (values ('A'), ('B'), ('C')) X([name])
),
PROPERTIES as (
select [propName] as entityName, [propValue] as propertyValue from (values ('A','1'),('A','2'),('B','3'),('UNIVERSAL','999')) Y([propName], [propValue])
),
SUBPROPERTIES as (
select [propValue] as propertyValue, [subPropValue] as subPropertyValue from (values ('1','x'),('1','y'),('2','z'),('999','xyz')) Y([propValue], [subPropValue])
)
--select * from ENTITIES
--select * from PROPERTIES

select (

    select entityName as 'entityName',
    (
        select * from 
            (
                select propertyValue as 'propertyValue',
                (
                    select subPropertyValue from SUBPROPERTIES where SUBPROPERTIES.propertyValue = PROPERTIES.propertyValue
                    FOR JSON PATH, INCLUDE_NULL_VALUES
                ) Y
                from PROPERTIES where PROPERTIES.entityName = ENTITIES.entityName 

-- For testing, comment out from here -------------------------------------------------------------------------------------
                UNION
    
                select propertyValue as 'propertyValue',
                (
                    select subPropertyValue from SUBPROPERTIES where SUBPROPERTIES.propertyValue = PROPERTIES.propertyValue
                    FOR JSON PATH, INCLUDE_NULL_VALUES
                ) Y
                from PROPERTIES where PROPERTIES.entityName = 'UNIVERSAL' 
-- For testing, stop commenting out here ----------------------------------------------------------------------------------

            ) X
        FOR JSON PATH, INCLUDE_NULL_VALUES
    ) as entityProperties
    
    from ENTITIES
    FOR JSON PATH, INCLUDE_NULL_VALUES

) jsondata

我设置了 3 个 CTE - 代表 3 个相互链接的表。一个实体记录(如“A”)可以有多个属性(如“1”和“2”),每个属性记录可以有多个子属性(如“1”有子属性“x”和“y”)。

现在主查询只是尝试构建一个 JSON 对象,该对象将返回所有实体及其所有链接的属性和链接的子属性。

所以第一个选择列只给你 entityName - 一个顶级查询。

下一列是子查询,用于获取与给定 ENTITIES 记录相关的所有 PROPERTIES 值。您会看到它返回带有别名“propertyValue”的东西——当然这将是一组值——链接到当前实体记录的每个 PROPERTIES 记录的一个值。

子查询有第二列,它是另一个子查询 - 到 SUBPROPERTIES 表 - 类似于上面。

现在问题来了——在这个中间级别(报告属性),我实际上想从 UNION 获取数据。

(在这个例子中,联合中的第二个查询是查询同一个源表——所以我可以通过改变 WHERE 子句来避免联合or PROPERTIES.entityName = 'UNIVERSAL'——但在现实世界中,我从两个不同的表中获取数据,所以我想与 UNION 聚合)。

我知道,当FOR XML PATH与 UNION 一起使用时,您需要将所有 UNION-ed SELECT 包装在括号中并给它一个别名(在本例中为 X),然后从中选择 - 我已经用select * from. (忽略这select *是不好的做法 - 这不是重点)。

这种对 UNION 的方法很好用——只要 UNION-ed 的查询不包含子查询——但正如您在此处看到的,我有子查询。

所以 - 看看我试图说明什么,如果您注释掉 UNION(和第二个选择),您将根据下图获得结构良好的 JSON。我已经强调了在结构化 JSON 中正确显示 SUBPROPERTIES 的位置。

在此处输入图像描述

但是,当我添加 UNION 时,这些子查询返回字符串,而不是 JSON,如下图所示。我已经突出显示了字符串的位置。

在此处输入图像描述

我尝试了各种方法来添加 JSON_QUERY 函数(在某些情况下建议将字符串解析为 JSON),但是 a) 未能解决问题,并且 b) 没有实际需要完全相同的数据时存在不是联合。

我也尝试过各种方法来select * from处理最低级别的子查询 - 无济于事。

提前致谢。

t-sql sql-server-2016
  • 1 1 个回答
  • 3215 Views

1 个回答

  • Voted
  1. Best Answer
    HandyD
    2020-05-11T17:13:28+08:002020-05-11T17:13:28+08:00

    问题似乎是 SQL 在合并时将内部 SELECT 中的伪字段视为文本而不是 JSON。当外部 FOR JSON 应用于此伪字段时,它会尝试转义文本字段中的特殊字符。有关更多信息,请参阅此链接。

    您可以使用JSON_QUERY函数来否定这一点,本质上是强制 SQL Server 将 JSON 字段视为 JSON 而不是文本。请参阅此小提琴以获取工作示例。

    查询(注意两次使用 JSON_QUERY,每个内部 SELECT 一次):

    with ENTITIES as (
    select [name] as entityName from (values ('A'), ('B'), ('C')) X([name])
    ),
    PROPERTIES as (
    select [propName] as entityName, [propValue] as propertyValue from (values ('A','1'),('A','2'),('B','3'),('UNIVERSAL','999')) Y([propName], [propValue])
    ),
    SUBPROPERTIES as (
    select [propValue] as propertyValue, [subPropValue] as subPropertyValue from (values ('1','x'),('1','y'),('2','z'),('999','xyz')) Y([propValue], [subPropValue])
    )
    
    select entityName as 'entityName',
    JSON_QUERY(
        (select propertyValue, JSON_QUERY(Y) AS subPropertyValue from 
            (
                select propertyValue as 'propertyValue',
                (
                    select subPropertyValue from SUBPROPERTIES where SUBPROPERTIES.propertyValue = PROPERTIES.propertyValue
                    FOR JSON PATH, INCLUDE_NULL_VALUES
                ) Y
                from PROPERTIES where PROPERTIES.entityName = ENTITIES.entityName 
    
    -- For testing, comment out from here -------------------------------------------------------------------------------------
                UNION
    
                select propertyValue as 'propertyValue',
                (
                    select subPropertyValue from SUBPROPERTIES where SUBPROPERTIES.propertyValue = PROPERTIES.propertyValue
                    FOR JSON PATH, INCLUDE_NULL_VALUES
                ) Y
                from PROPERTIES where PROPERTIES.entityName = 'UNIVERSAL' 
    -- For testing, stop commenting out here ----------------------------------------------------------------------------------
    
            ) X
        FOR JSON PATH, INCLUDE_NULL_VALUES
    )
    ) as entityProperties
    from ENTITIES
    FOR JSON PATH, INCLUDE_NULL_VALUES
    

    结果

    [
      {
        "entityName": "A",
        "entityProperties": [
          {
            "propertyValue": "1",
            "subPropertyValue": [
              {
                "subPropertyValue": "x"
              },
              {
                "subPropertyValue": "y"
              }
            ]
          },
          {
            "propertyValue": "2",
            "subPropertyValue": [
              {
                "subPropertyValue": "z"
              }
            ]
          },
          {
            "propertyValue": "999",
            "subPropertyValue": [
              {
                "subPropertyValue": "xyz"
              }
            ]
          }
        ]
      },
      {
        "entityName": "B",
        "entityProperties": [
          {
            "propertyValue": "3",
            "subPropertyValue": null
          },
          {
            "propertyValue": "999",
            "subPropertyValue": [
              {
                "subPropertyValue": "xyz"
              }
            ]
          }
        ]
      },
      {
        "entityName": "C",
        "entityProperties": [
          {
            "propertyValue": "999",
            "subPropertyValue": [
              {
                "subPropertyValue": "xyz"
              }
            ]
          }
        ]
      }
    ]
    
    • 2

相关问题

  • 如何使用 TSQL 更改 SQL 服务器配置管理器设置?

  • 如何从结果集中获取列名和类型的列表?

  • MS SQL:使用计算值计算其他值

  • 如何判断 SQL Server 数据库是否仍在使用?

  • 实施 PIVOT 查询

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve