生成JSON字符串而不在结果集中重复结果

时间:2019-11-11 17:02:26

标签: json sql-server tsql

在TSQL中构建JSON字符串时,我不知道如何停止重复通用值。我需要在JSON结构的根目录中进行子选择的总计数,而不是在数据部分中不断重复。我不知道如何重新排列SELECT语句以获取所需的JSON字符串。

“ recordsFiltered”表示从用户启动的搜索中过滤并返回的记录总数。我只需要在JSON字符串中一次使用此数字即可。

这是所需的结果:

    {
    "draw": 1,
    "recordsTotal": 137920,
    "recordsFiltered": 55,
    "data": [
        {
            "DT_RowId": 1029833,
            "PositionTitle": "Total SQL Chad",
            "Department": "Nice Suburbs",
        },
        {
            "DT_RowId": 1029834,
            "PositionTitle": "Beta SQL Programmer",
            "Department": "Still Lives with Mom",
        },

    ...
    ]
}

如您所见,这是一个非常标准的查询,其结果如下。 “ recordsFiltered”经常重复。这是不可取的。

--QUERY BASELINE
select
    count(RowID) over() as recordsFiltered
    ,RowID as DT_RowID
    ,LastName
    ,PositionTitle
from
    badges
where
    LastName = 'Dean'
for json path, root ('data'), include_null_values

--RESULT
{
    "data": [
    {
        "recordsFiltered": 55,
        "DT_RowID": 1005791,
        "LastName": "Dean",
        "PositionTitle": ""
    },
    {
        "recordsFiltered": 55,
        "DT_RowID": 1011253,
        "LastName": "Dean",
        "PositionTitle": "Instructional Assistant"
    },

    ...
    ]
}

这里是个人尝试号码187。看到我试图将计数添加到“较高”的SELECT语句中,但是“ recordsFiltered”仍然是数据部分的一部分...我需要做什么才能停止或排除最终JSON字符串中重复的条目?这非常接近...

--ATTEMPT 187
select

    json_value(_.data, '$[0].recordsFiltered') as recordsFiltered
    ,_.data

from
    (
        select
            isnull((
                select
                    count(RowID) over() as recordsFiltered
                    ,RowID as DT_RowID
                    ,LastName
                    ,PositionTitle
                from
                    badges
                where
                    LastName = 'Dean'
                for json path, include_null_values
            ), '[]') as data

    ) _

for json path, include_null_values, without_array_wrapper

--RESULT
{
"recordsFiltered": "55",
"data": [
    {
        "recordsFiltered": 55,
        "DT_RowID": 1005791,
        "LastName": "Dean",
        "PositionTitle": ""
    },
    {
        "recordsFiltered": 55,
        "DT_RowID": 1011253,
        "LastName": "Dean",
        "PositionTitle": "Instructional Assistant"
    },
    ...
    ]
}

============样本数据/表格=============

这是一个简单的“平面”表,我排除了“隐私”的某些列。

create table [dbo].[Badges](
[RowID] [int] identity(1000001,1) not null,
[LastName] [varchar](32) not null,
[PositionTitle] [varchar](64) not null,
)

2 个答案:

答案 0 :(得分:1)

下一个查询应满足您的要求。

1-过滤记录并将其保存到临时表中。

2-计算受影响的记录。

3-使用所需信息生成json。

DROP TABLE IF EXISTS [#Filtered];

;WITH
[Filtered]
AS
(
    SELECT
         [RowID]
        ,[LastName]
        ,[PositionTitle]
        ,[Department]
    FROM [dbo].[Badges]
    WHERE ([LastName] = 'Dean')
)
SELECT
    *
INTO [#Filtered]
FROM [Filtered];

DECLARE @RecordsFiltered INT = @@ROWCOUNT;

SELECT
     [draw] = 1
    ,[recordsTotal] = COUNT(1)
    ,[recordsFiltered] = @RecordsFiltered
    ,[data] =
    (
        SELECT
             [DT_RowId] = [F].[RowID]
            ,[F].[PositionTitle]
            ,[F].[Department]
        FROM [#Filtered] AS [F]
        FOR JSON PATH
    )
FROM [dbo].[Badges] AS [B]
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER;

-这里是不使用临时表的另一个版本

;WITH
[Filtered]
AS
(
    SELECT
         [RowID]
        ,[LastName]
        ,[PositionTitle]
        ,[Department]
    FROM [dbo].[Badges]
    WHERE ([LastName] = 'Dean')
)
SELECT
     [draw] = 1
    ,[recordsTotal] = COUNT(1)
    ,[recordsFiltered] = (SELECT COUNT(1) FROM [Filtered])
    ,[data] =
    (
        SELECT
             [DT_RowId] = [F].[RowID]
            ,[F].[PositionTitle]
            ,[F].[Department]
        FROM [Filtered] AS [F]
        FOR JSON PATH
    )
FROM [dbo].[Badges] AS [B]
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER;

答案 1 :(得分:1)

如果我对您的理解正确,那么下一种方法可能会有所帮助:

表格:

CREATE TABLE Badges (
   [RowID] [int] identity(1000001,1) not null,
   [LastName] [varchar](32) not null,
   [PositionTitle] [varchar](64) not null,
)
INSERT INTO Badges
   ([LastName], [PositionTitle])
VALUES
   ('Dean', 'Instructional Assistant'),
   ('Dean', 'Instructional Assistant'),
   ('Luke', 'Instructional Assistant')

声明:

SELECT
   Draw = 1,
   recordsTotals = (SELECT COUNT(*) FROM Badges),
   recordsFiltered = (SELECT COUNT(*) FROM Badges WHERE LastName = 'Dean'),
   Data = (
      SELECT RowID, LastName, PositionTitle
      FROM Badges
      WHERE LastName = 'Dean'
      FOR JSON AUTO
   )
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER     

结果:

{
   "Draw":1,
   "recordsTotal":3,
   "recordsFiltered":2,
   "Data":[
      {
         "RowID":1000001,
         "LastName":"Dean",
         "PositionTitle":"Instructional Assistant"
      },
      {
         "RowID":1000002,
         "LastName":"Dean",
         "PositionTitle":"Instructional Assistant"
      }
   ]
}

注意:

您需要检查此语句的性能。

相关问题