AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 346133
Accepted
DevQt
DevQt
Asked: 2025-04-12 10:31:30 +0800 CST2025-04-12 10:31:30 +0800 CST 2025-04-12 10:31:30 +0800 CST

Agrupando e organizando dados usando FOR JSON PATH e INCLUDE_NULL_VALUES

  • 772

Estou com um problema com meu script T-SQL. Estou pensando e trabalhando em como produzir a saída esperada dele.

Aqui está meu script T-SQL:

DECLARE @user_id VARCHAR(50) = 'UGUID-2025-01-27-14-09-22-1967-ABCDEFGHIJKL'; -- FOR TESTING PURPOSES ONLY
DECLARE @status_t TABLE (status VARCHAR(50));
INSERT INTO @status_t VALUES ('PENDING'),('APPROVED'),('PROCESSING')

SELECT
    orders.batch_code, -- FOR DEMONSTRATION PURPOSES ONLY
    oa_prod.nested_data AS nested_prod,
    cnb.amount_to_pay
FROM
    [testDB].[dbo].[Orders] AS orders
RIGHT OUTER JOIN
    [testDB].[dbo].[Payment] AS cnb
ON
    orders.order_id = cnb.order_id
LEFT OUTER JOIN
    [testDB].[dbo].[StatusRef] AS stat_ref
ON
    orders.stat_ref_id = stat_ref.stat_ref_id
CROSS APPLY( -- OR OUTER APPLY
    SELECT
        orders.batch_code,
        orders.order_id,
        prod.prod_name,
        pv_kn.key_name,
        pv_kv.value,
        CASE WHEN
            orders.prod_id IS NOT NULL
        THEN
            prod.disc_price
        WHEN
            orders.prod_var_id IS NOT NULL
        THEN
            prod_var.disc_price
        END AS disc_price,
        orders.quantity
    FROM
        [testDB].[dbo].[Product] AS prod
    RIGHT OUTER JOIN
        [testDB].[dbo].[SubProduct] AS prod_var
    ON
        prod.prod_id = prod_var.prod_id
    LEFT OUTER JOIN
        [testDB].[dbo].[SubProductVarKeyValue] AS pv_kv
    ON
        prod_var.prod_var_id = pv_kv.prod_var_id
    LEFT OUTER JOIN
        [testDB].[dbo].[SubProductVarKeyNames] AS pv_kn
    ON
        pv_kv.pv_key_name_id = pv_kn.pv_key_name_id
    WHERE       
        prod.prod_id = orders.prod_id
        OR prod_var.prod_var_id = orders.prod_var_id
    FOR JSON PATH,
    INCLUDE_NULL_VALUES
) AS oa_prod(nested_data) -- it's a syntax analyzer lint conflict ONLY
WHERE
    orders.disable = 0
    AND cnb.disable = 0
    AND orders.user_id = @user_id
    AND stat_ref.com_usd_wrds IN (SELECT status FROM @status_t)
ORDER BY
    orders.dt_stamp DESC,
    orders.batch_code ASC -- To prevent batch_code from being separated
FOR JSON PATH,
INCLUDE_NULL_VALUES

Aqui está meu exemplo mínimo e reproduzível usando variáveis ​​de tabela:

DECLARE @StatusRef TABLE(
    stat_ref_id VARCHAR(50) PRIMARY KEY NOT NULL,
    com_usd_wrds NVARCHAR(100) NOT NULL
);

DECLARE @Product TABLE(
    prod_id VARCHAR(50) PRIMARY KEY NOT NULL,
    prod_name VARCHAR(200) NOT NULL,
    stock INT NOT NULL,
    disc_price DECIMAL(12, 2) NOT NULL
);

DECLARE @SubProduct TABLE(
    prod_var_id VARCHAR(50) PRIMARY KEY NOT NULL,
    stock INT NOT NULL,
    disc_price DECIMAL(12, 2) NOT NULL,
    prod_id VARCHAR(50) NOT NULL
);

DECLARE @Orders TABLE(
    order_id VARCHAR(50) PRIMARY KEY NOT NULL,
    batch_code VARCHAR(50) NULL,
    quantity INT NOT NULL,
    stat_ref_id VARCHAR(50) NOT NULL,
    disable BIT DEFAULT (0) NOT NULL,
    dt_stamp DATETIME NOT NULL,
    prod_id VARCHAR(50) NULL,
    prod_var_id VARCHAR(50) NULL,
    user_id VARCHAR(50) NOT NULL
);

DECLARE @Payment TABLE(
    amount_to_pay DECIMAL(14, 2) NOT NULL,
    order_id VARCHAR(50) NOT NULL,
    disable BIT DEFAULT (0) NOT NULL
);

DECLARE @SubProductVarKeyValue TABLE(
    value VARCHAR(100) NOT NULL,
    prod_var_id VARCHAR(50) NOT NULL,
    pv_key_name_id VARCHAR(50) NOT NULL
);

DECLARE @SubProductVarKeyNames TABLE(
    pv_key_name_id VARCHAR(50) PRIMARY KEY NOT NULL,
    key_name VARCHAR(100) NOT NULL
);

INSERT INTO @StatusRef
VALUES
(
    'STAT-REF-1001', -- stat_ref_id
    'PENDING' -- com_usd_wrds
),
(
    'STAT-REF-1002', -- stat_ref_id
    'APPROVED' -- com_usd_wrds
),
(
    'STAT-REF-1003', -- stat_ref_id
    'PROCESSING' -- com_usd_wrds
);

INSERT INTO @Product
VALUES
(
    'PROD-ID-1001', -- prod_id
    'iPhone', -- prod_name
    0, -- stock | dependent to @SubProduct
    0.00 -- disc_price | dependent to @SubProduct
),
(
    'PROD-ID-1002', -- prod_id
    'Samsung', -- prod_name
    0, -- stock | dependent to @SubProduct
    0.00 -- disc_price | dependent to @SubProduct
),
(
    'PROD-ID-1003', -- prod_id
    'Nokia', -- prod_name
    75, -- stock
    33150.00 -- disc_price
),
(
    'PROD-ID-1004', -- prod_id
    'Google', -- prod_name
    100, -- stock
    53509.00 -- disc_price
),
(
    'PROD-ID-1005', -- prod_id
    'Sony', -- prod_name
    0, -- stock | dependent to @SubProduct
    0.00 -- disc_price | dependent to @SubProduct
),
(
    'PROD-ID-1006', -- prod_id
    'Lenovo', -- prod_name
    0, -- stock | dependent to @SubProduct
    0.00 -- disc_price | dependent to @SubProduct
);

INSERT INTO @SubProduct
VALUES
(
    'PROD-VAR-ID-1', -- prod_var_id
    25, -- stock
    45809.00, -- disc_price
    'PROD-ID-1001' -- prod_id
),
(
    'PROD-VAR-ID-2', -- prod_var_id
    50, -- stock
    40209.00, -- disc_price
    'PROD-ID-1002' -- prod_id
),
(
    'PROD-VAR-ID-3', -- prod_var_id
    0, -- stock | dependent to @Product
    0.00, -- disc_price | dependent to @Product
    'PROD-ID-1003' -- prod_id
),
(
    'PROD-VAR-ID-4', -- prod_var_id
    0, -- stock | dependent to @Product
    0.00, -- disc_price | dependent to @Product
    'PROD-ID-1004' -- prod_id
),
(
    'PROD-VAR-ID-5', -- prod_var_id
    125, -- stock
    25809.00, -- disc_price
    'PROD-ID-1005' -- prod_id
),
(
    'PROD-VAR-ID-6', -- prod_var_id
    150, -- stock
    49100.00, -- disc_price
    'PROD-ID-1006' -- prod_id
);

INSERT INTO @SubProductVarKeyValue
VALUES
(
    'new', -- value
    'PROD-VAR-ID-1', -- prod_var_id
    'PVKN-ID-1' -- pv_key_name_id
),
(
    'new', -- value
    'PROD-VAR-ID-2', -- prod_var_id
    'PVKN-ID-1' -- pv_key_name_id
),
(
    'new', -- value
    'PROD-VAR-ID-5', -- prod_var_id
    'PVKN-ID-1' -- pv_key_name_id
),
(
    'new', -- value
    'PROD-VAR-ID-6', -- prod_var_id
    'PVKN-ID-1' -- pv_key_name_id
)

INSERT INTO @SubProductVarKeyNames
VALUES
(
    'PVKN-ID-1', -- pv_key_name_id
    'Condition' -- key_name
)

INSERT INTO @Orders
(
    order_id,
    batch_code,
    quantity,
    stat_ref_id,
    dt_stamp,
    prod_id,
    prod_var_id,
    user_id
)
VALUES
(
    'ORDER-2025-04-11-B71D0E2F5D8C', -- order_id
    NULL, -- batch_code
    1, -- quantity
    'STAT-REF-1003', -- stat_ref_id
    '2025-04-14 10:17:20.963', -- dt_stamp
    NULL, -- prod_id
    'PROD-VAR-ID-1', -- prod_var_id
    'UGUID-2025-01-27-14-09-22-1967-ABCDEFGHIJKL' -- user_id
),
(
    'ORDER-2025-04-11-D95EB033CA40', -- order_id
    'BGUID-2025-04-11-6D81B58FAE94', -- batch_code
    2, -- quantity
    'STAT-REF-1001', -- stat_ref_id
    '2025-04-13 09:17:20.963', -- dt_stamp
    NULL, -- prod_id
    'PROD-VAR-ID-2', -- prod_var_id
    'UGUID-2025-01-27-14-09-22-1967-ABCDEFGHIJKL' -- user_id
),
(
    'ORDER-2025-04-11-7F04EFA2BB60', -- order_id
    'BGUID-2025-04-11-6D81B58FAE94', -- batch_code
    2, -- quantity
    'STAT-REF-1001', -- stat_ref_id
    '2025-04-13 09:17:20.963', -- dt_stamp
    'PROD-ID-1003', -- prod_id
    NULL, -- prod_var_id
    'UGUID-2025-01-27-14-09-22-1967-ABCDEFGHIJKL' -- user_id
),
(
    'ORDER-2025-04-10-3F03EAA47686', -- order_id
    'BGUID-2025-04-10-20239FD2059F', -- batch_code
    1, -- quantity
    'STAT-REF-1002', -- stat_ref_id
    '2025-04-12 08:17:20.963', -- dt_stamp
    'PROD-ID-1004', -- prod_id
    NULL, -- prod_var_id
    'UGUID-2025-01-27-14-09-22-1967-ABCDEFGHIJKL' -- user_id
),
(
    'ORDER-2025-04-10-F4A89E2C4A30', -- order_id
    'BGUID-2025-04-10-20239FD2059F', -- batch_code
    1, -- quantity
    'STAT-REF-1002', -- stat_ref_id
    '2025-04-12 08:17:20.963', -- dt_stamp
    NULL, -- prod_id
    'PROD-VAR-ID-5', -- prod_var_id
    'UGUID-2025-01-27-14-09-22-1967-ABCDEFGHIJKL' -- user_id
),
(
    'ORDER-2025-04-08-31BD887341FA', -- order_id
    NULL, -- batch_code
    1, -- quantity
    'STAT-REF-1001', -- stat_ref_id
    '2025-04-11 07:17:20.963', -- dt_stamp
    NULL, -- prod_id
    'PROD-VAR-ID-6', -- prod_var_id
    'UGUID-2025-01-27-14-09-22-1967-ABCDEFGHIJKL' -- user_id
);

INSERT INTO @Payment
(
    amount_to_pay,
    order_id
)
VALUES
(
    45809.00, -- amount_to_pay
    'ORDER-2025-04-11-B71D0E2F5D8C' -- order_id
),
(
    146718.00, -- amount_to_pay
    'ORDER-2025-04-11-D95EB033CA40' -- order_id
),
(
    146718.00, -- amount_to_pay
    'ORDER-2025-04-11-7F04EFA2BB60' -- order_id
),
(
    79318.00, -- amount_to_pay
    'ORDER-2025-04-10-3F03EAA47686' -- order_id
),
(
    79318.00, -- amount_to_pay
    'ORDER-2025-04-10-F4A89E2C4A30' -- order_id
),
(
    49100.00, -- amount_to_pay
    'ORDER-2025-04-08-31BD887341FA' -- order_id
);
SELECT * FROM @StatusRef

SAÍDA:

stat_ref_id com_usd_wrds
STAT-REF-1001 PENDENTE
STAT-REF-1002 APROVADO
STAT-REF-1003 PROCESSAMENTO
SELECT * FROM @Product

SAÍDA:

id_do_produto nome_do_produto estoque preço_disc
PROD-ID-1001 iPhone 0 0,00
PROD-ID-1002 Samsung 0 0,00
PROD-ID-1003 Nokia 75 33150,00
PROD-ID-1004 Google 100 53509,00
PROD-ID-1005 Sony 0 0,00
PROD-ID-1006 Lenovo 0 0,00
SELECT * FROM @SubProduct

SAÍDA:

id_var_do_produto estoque preço_disc id_do_produto
PROD-VAR-ID-1 25 45809,00 PROD-ID-1001
PROD-VAR-ID-2 50 40209,00 PROD-ID-1002
PROD-VAR-ID-3 0 0,00 PROD-ID-1003
PROD-VAR-ID-4 0 0,00 PROD-ID-1004
PROD-VAR-ID-5 125 25809,00 PROD-ID-1005
PROD-VAR-ID-6 150 49100,00 PROD-ID-1006
SELECT * FROM @Orders ORDER BY dt_stamp

SAÍDA:

id_do_pedido código_de_lote quantidade stat_ref_id desabilitar dt_stamp id_do_produto id_var_do_produto ID do usuário
ORDEM-2025-04-08-31BD887341FA NULO 1 STAT-REF-1001 0 2025-04-11 07:17:20.963 NULO PROD-VAR-ID-6 UGUID-2025-01-27-14-09-22-1967-ABCDEFGHIJKL
ORDEM-2025-04-10-3F03EAA47686 BGUID-2025-04-10-20239FD2059F 1 STAT-REF-1002 0 2025-04-12 08:17:20.963 PROD-ID-1004 NULO UGUID-2025-01-27-14-09-22-1967-ABCDEFGHIJKL
ORDEM-2025-04-10-F4A89E2C4A30 BGUID-2025-04-10-20239FD2059F 1 STAT-REF-1002 0 2025-04-12 08:17:20.963 NULO PROD-VAR-ID-5 UGUID-2025-01-27-14-09-22-1967-ABCDEFGHIJKL
PEDIDO-2025-04-11-7F04EFA2BB60 BGUID-2025-04-11-6D81B58FAE94 2 STAT-REF-1001 0 2025-04-13 09:17:20.963 PROD-ID-1003 NULO UGUID-2025-01-27-14-09-22-1967-ABCDEFGHIJKL
ORDEM-2025-04-11-D95EB033CA40 BGUID-2025-04-11-6D81B58FAE94 2 STAT-REF-1001 0 2025-04-13 09:17:20.963 NULO PROD-VAR-ID-2 UGUID-2025-01-27-14-09-22-1967-ABCDEFGHIJKL
ORDEM-2025-04-11-B71D0E2F5D8C NULO 1 STAT-REF-1003 0 2025-04-14 10:17:20.963 NULO PROD-VAR-ID-1 UGUID-2025-01-27-14-09-22-1967-ABCDEFGHIJKL
SELECT * FROM @Payment

SAÍDA:

valor_a_pagar id_do_pedido desabilitar
45809,00 ORDEM-2025-04-11-B71D0E2F5D8C 0
146718,00 ORDEM-2025-04-11-D95EB033CA40 0
146718,00 PEDIDO-2025-04-11-7F04EFA2BB60 0
79318,00 ORDEM-2025-04-10-3F03EAA47686 0
79318,00 ORDEM-2025-04-10-F4A89E2C4A30 0
45809,00 ORDEM-2025-04-08-31BD887341FA 0
SELECT * FROM @SubProductVarKeyValue

SAÍDA:

valor id_var_do_produto pv_key_name_id
novo PROD-VAR-ID-1 PVKN-ID-1
novo PROD-VAR-ID-2 PVKN-ID-1
novo PROD-VAR-ID-5 PVKN-ID-1
novo PROD-VAR-ID-6 PVKN-ID-1
SELECT * FROM @SubProductVarKeyNames

SAÍDA:

pv_key_name_id nome_da_chave
PVKN-ID-1 Doença

Aqui está o exemplo modificado do script que é semelhante ao primeiro fornecido:

DECLARE @user_id VARCHAR(50) = 'UGUID-2025-01-27-14-09-22-1967-ABCDEFGHIJKL'; -- FOR TESTING PURPOSES ONLY
DECLARE @status_t TABLE (status VARCHAR(50));
INSERT INTO @status_t VALUES ('PENDING'),('APPROVED'),('PROCESSING')

SELECT
    orders.batch_code, -- FOR DEMONSTRATION PURPOSES ONLY
    oa_prod.nested_data AS nested_prod,
    cnb.amount_to_pay
FROM
    @Orders AS orders
RIGHT OUTER JOIN
    @Payment AS cnb
ON
    orders.order_id = cnb.order_id
LEFT OUTER JOIN
    @StatusRef AS stat_ref
ON
    orders.stat_ref_id = stat_ref.stat_ref_id
CROSS APPLY( -- OR OUTER APPLY
    SELECT
        orders.batch_code,
        orders.order_id,
        prod.prod_name,
        pv_kn.key_name,
        pv_kv.value,
        CASE WHEN
            orders.prod_id IS NOT NULL
        THEN
            prod.disc_price
        WHEN
            orders.prod_var_id IS NOT NULL
        THEN
            prod_var.disc_price
        END AS disc_price,
        orders.quantity
    FROM
        @Product AS prod
    RIGHT OUTER JOIN
        @SubProduct AS prod_var
    ON
        prod.prod_id = prod_var.prod_id
    LEFT OUTER JOIN
        @SubProductVarKeyValue AS pv_kv
    ON
        prod_var.prod_var_id = pv_kv.prod_var_id
    LEFT OUTER JOIN
        @SubProductVarKeyNames AS pv_kn
    ON
        pv_kv.pv_key_name_id = pv_kn.pv_key_name_id
    WHERE       
        prod.prod_id = orders.prod_id
        OR prod_var.prod_var_id = orders.prod_var_id
    FOR JSON PATH,
    INCLUDE_NULL_VALUES
) AS oa_prod(nested_data) -- it's a syntax analyzer lint conflict ONLY
WHERE
    orders.disable = 0
    AND cnb.disable = 0
    AND orders.user_id = @user_id
    AND stat_ref.com_usd_wrds IN (SELECT status FROM @status_t)
ORDER BY
    orders.dt_stamp DESC
    --orders.batch_code ASC -- To prevent batch_code from being separated
FOR JSON PATH,
INCLUDE_NULL_VALUES

Infelizmente, quando embelezo a saída JSON, isso é o que ele gera:

[
  {
    "batch_code": null,
    "nested_prod": [
      {
        "batch_code": null,
        "order_id": "ORDER-2025-04-11-B71D0E2F5D8C",
        "prod_name": "iPhone",
        "key_name": "Condition",
        "value": "new",
        "disc_price": 45809,
        "quantity": 1
      }
    ],
    "amount_to_pay": 45809
  },
  {
    "batch_code": "BGUID-2025-04-11-6D81B58FAE94",
    "nested_prod": [
      {
        "batch_code": "BGUID-2025-04-11-6D81B58FAE94",
        "order_id": "ORDER-2025-04-11-D95EB033CA40",
        "prod_name": "Samsung",
        "key_name": "Condition",
        "value": "new",
        "disc_price": 40209,
        "quantity": 2
      }
    ],
    "amount_to_pay": 146718
  },
  {
    "batch_code": "BGUID-2025-04-11-6D81B58FAE94",
    "nested_prod": [
      {
        "batch_code": "BGUID-2025-04-11-6D81B58FAE94",
        "order_id": "ORDER-2025-04-11-7F04EFA2BB60",
        "prod_name": "Nokia",
        "key_name": null,
        "value": null,
        "disc_price": 33150,
        "quantity": 2
      }
    ],
    "amount_to_pay": 146718
  },
  {
    "batch_code": "BGUID-2025-04-10-20239FD2059F",
    "nested_prod": [
      {
        "batch_code": "BGUID-2025-04-10-20239FD2059F",
        "order_id": "ORDER-2025-04-10-3F03EAA47686",
        "prod_name": "Google",
        "key_name": null,
        "value": null,
        "disc_price": 53509,
        "quantity": 1
      }
    ],
    "amount_to_pay": 79318
  },
  {
    "batch_code": "BGUID-2025-04-10-20239FD2059F",
    "nested_prod": [
      {
        "batch_code": "BGUID-2025-04-10-20239FD2059F",
        "order_id": "ORDER-2025-04-10-F4A89E2C4A30",
        "prod_name": "Sony",
        "key_name": "Condition",
        "value": "new",
        "disc_price": 25809,
        "quantity": 1
      }
    ],
    "amount_to_pay": 79318
  },
  {
    "batch_code": null,
    "nested_prod": [
      {
        "batch_code": null,
        "order_id": "ORDER-2025-04-08-31BD887341FA",
        "prod_name": "Lenovo",
        "key_name": "Condition",
        "value": "new",
        "disc_price": 49100,
        "quantity": 1
      }
    ],
    "amount_to_pay": 49100
  }
]

No entanto, preciso que a saída seja algo como isto:

[
  {
    "batch_code": null,
    "nested_prod": [
      {
        "batch_code": null,
        "order_id": "ORDER-2025-04-11-B71D0E2F5D8C",
        "prod_name": "iPhone",
        "key_name": "Condition",
        "value": "new",
        "disc_price": 45809,
        "quantity": 1
      }
    ],
    "amount_to_pay": 45809
  },
  {
    "batch_code": "BGUID-2025-04-11-6D81B58FAE94",
    "nested_prod": [
      {
        "batch_code": "BGUID-2025-04-11-6D81B58FAE94",
        "order_id": "ORDER-2025-04-11-D95EB033CA40",
        "prod_name": "Samsung",
        "key_name": "Condition",
        "value": "new",
        "disc_price": 40209,
        "quantity": 2
      },
      {
        "batch_code": "BGUID-2025-04-11-6D81B58FAE94",
        "order_id": "ORDER-2025-04-11-7F04EFA2BB60",
        "prod_name": "Nokia",
        "key_name": null,
        "value": null,
        "disc_price": 33150,
        "quantity": 2
      }
    ],
    "amount_to_pay": 146718
  },
  {
    "batch_code": "BGUID-2025-04-10-20239FD2059F",
    "nested_prod": [
      {
        "batch_code": "BGUID-2025-04-10-20239FD2059F",
        "order_id": "ORDER-2025-04-10-3F03EAA47686",
        "prod_name": "Google",
        "key_name": null,
        "value": null,
        "disc_price": 53509,
        "quantity": 1
      },
      {
        "batch_code": "BGUID-2025-04-10-20239FD2059F",
        "order_id": "ORDER-2025-04-10-F4A89E2C4A30",
        "prod_name": "Sony",
        "key_name": "Condition",
        "value": "new",
        "disc_price": 25809,
        "quantity": 1
      }
    ],
    "amount_to_pay": 79318
  },
  {
    "batch_code": null,
    "nested_prod": [
      {
        "batch_code": null,
        "order_id": "ORDER-2025-04-08-31BD887341FA",
        "prod_name": "Lenovo",
        "key_name": "Condition",
        "value": "new",
        "disc_price": 49100,
        "quantity": 1
      }
    ],
    "amount_to_pay": 49100
  }
]

Observação: O amount_to_payfoi pré-calculado no aplicativo cliente. Portanto, ele deve se tornar uma instância única quando batch_codes duplicados forem agrupados.

Os pedidos do usuário podem causar variações na saída JSON desejada mostrada acima.

Alguém está familiarizado com o problema que estou enfrentando?

Na medida do possível, prefiro não implementar a abordagem Common Table Expression (CTE).

sql-server
  • 2 2 respostas
  • 109 Views

2 respostas

  • Voted
  1. Doug Hills
    2025-04-15T02:56:01+08:002025-04-15T02:56:01+08:00

    Vou ignorar o dano cerebral de entender o esquema inteiro. Acho que essa abordagem vai agrupar as coisas da maneira que você quiser. Achei que JSON_QUERY() não deveria escapar as aspas nas chaves e valores no JSON aninhado, mas ainda as recebo quando executo isso. Provavelmente deixei passar algo aí.

    SELECT 
          o.batch_code
        , o.amount_to_pay
        , CASE 
            WHEN o.batch_code IS NULL 
            THEN JSON_QUERY((
                SELECT 
                      oo.batch_code 
                    , oo.order_id
                    , p.prod_name
                    , COALESCE(p.disc_price, sp.disc_price) as disc_price
                FROM @Orders as oo
                LEFT OUTER JOIN @Product as p
                    ON oo.prod_id = p.prod_id
                LEFT OUTER JOIN @SubProduct as sp
                    ON oo.prod_var_id = sp.prod_var_id
                WHERE o.order_id = oo.order_id
                FOR JSON PATH,
                INCLUDE_NULL_VALUES
            ))
            ELSE JSON_QUERY((
                SELECT 
                      oo.batch_code 
                    , oo.order_id
                    , p.prod_name
                    , COALESCE(p.disc_price, sp.disc_price) as disc_price
                FROM @Orders as oo
                LEFT OUTER JOIN @Product as p
                    ON oo.prod_id = p.prod_id
                LEFT OUTER JOIN @SubProduct as sp
                    ON oo.prod_var_id = sp.prod_var_id
                WHERE o.batch_code = oo.batch_code
                FOR JSON PATH,
                INCLUDE_NULL_VALUES
            )) 
            END as nested_prod
    FROM (
        SELECT o.order_id, o.batch_code, p.amount_to_pay
        FROM @Orders as o
        LEFT OUTER JOIN @Payment as p
            ON o.order_id = p.order_id
        WHERE batch_code IS NULL
    
        UNION 
    
        SELECT NULL as order_id, batch_code, SUM(p.amount_to_pay) as amount_to_pay
        FROM @Orders as o
        LEFT OUTER JOIN @Payment as p
            ON o.order_id = p.order_id
        WHERE batch_code iS not null
        GROUP BY o.batch_code
    ) as o
    FOR JSON PATH,
    INCLUDE_NULL_VALUES
    
    
    • 1
  2. Best Answer
    Rodger Kong
    2025-04-15T18:20:11+08:002025-04-15T18:20:11+08:00

    A maneira como você tenta construir um JSON está correta: aninhar uma subconsulta FOR JSON PATH ou uma tabela unida na instrução SELECT gerará o texto JSON aninhado desejado. No entanto, existem alguns relacionamentos incorretos na sua amostra de dados, o que causa um resultado inesperado.

    No meu entendimento:

    • O nível mais externo da sua saída deve ser o objeto BATCH, que é agregado da tabela @orders que possui o mesmo batch_code. Presumo que pedidos com o mesmo valor de batch_code também tenham os mesmos valores de stat_ref_id, disable, user_id e dt_stamp. Para que eu possa incluir essas colunas em um conjunto de dados, chamo-o de batches.

    • The BATCH object also has a property amount_to_pay, observe the sample data, it should be the value of sum(disc_price * quantity) of the orders with same value of batch_code. In your query, this value comes from the table @Payment, but in the table, column amount_to_pay is related to the @orders by order_id, it will repeating with @orders, so we need to add a new relationship to the dataset batched.

    • The most importaint is object BATCH includes an array which contains object ORDER, it look like each ORDER has only one PRODUCT/SUBPRODUCT object, this must be a nested array in JSON. To impliment this, the CROSS APPLY must filter orders by batch_code.

    If my understanding is correct, issues in your SQL script are:

    • Your main query is based on table @orders, it has 6 validated rows, the top level of JSON result has to be a array contain 6 objects.

    • The result you expect has 4 top level objects, If you aggregate the @orders by batch_code directly, NULL values make you cannot pass it into subquery and filter correct orders/products. We have to find a valid key column during aggregating to represent batch_id.

    • The column amount_to_pay is come from table @Payment, but the only column can make relationship is order_id, if the main query JOIN with order_id will extend the rows either. We must add a key that can JOIN with the new batch_id in main query.

    • The subquery of CROSS APPLY should filter the table @orders by batch_code, since the NULL value make this impossible, we need to add a batch_id in this @orders table as filter key too.

    Of all the previous points, add a batch_id column in the @orders table is key.

    • I think no batch number means only has one order, then I can treat the order_id as batch_code when the batch_code is null. So I building a CTE p_orders before the query, using IIF(batch_code IS NULL) to create a new column batch_id as key.

    • Then I changing the main query to a nested query which SELECT DISTINCT batch_id and some columns as the dataset batches.

    • I changing the dataset cnb to add a batch_id by JOIN the @Payment and the table p_orders.

    • At last, I adding a JOIN p_tables in the subquery of CROSS APPLY to get columns value which must show in JSON, then filtering inner rows by the value of batch_id of the main query batches.

    Code is here:

    DECLARE @StatusRef TABLE(
        stat_ref_id VARCHAR(50) PRIMARY KEY NOT NULL,
        com_usd_wrds NVARCHAR(100) NOT NULL
    );
    
    DECLARE @Product TABLE(
        prod_id VARCHAR(50) PRIMARY KEY NOT NULL,
        prod_name VARCHAR(200) NOT NULL,
        stock INT NOT NULL,
        disc_price DECIMAL(12, 2) NOT NULL
    );
    
    DECLARE @SubProduct TABLE(
        prod_var_id VARCHAR(50) PRIMARY KEY NOT NULL,
        stock INT NOT NULL,
        disc_price DECIMAL(12, 2) NOT NULL,
        prod_id VARCHAR(50) NOT NULL
    );
    
    DECLARE @Orders TABLE(
        order_id VARCHAR(50) PRIMARY KEY NOT NULL,
        batch_code VARCHAR(50) NULL,
        quantity INT NOT NULL,
        stat_ref_id VARCHAR(50) NOT NULL,
        disable BIT DEFAULT (0) NOT NULL,
        dt_stamp DATETIME NOT NULL,
        prod_id VARCHAR(50) NULL,
        prod_var_id VARCHAR(50) NULL,
        user_id VARCHAR(50) NOT NULL
    );
    
    DECLARE @Payment TABLE(
        amount_to_pay DECIMAL(14, 2) NOT NULL,
        order_id VARCHAR(50) NOT NULL,
        disable BIT DEFAULT (0) NOT NULL
    );
    
    DECLARE @SubProductVarKeyValue TABLE(
        value VARCHAR(100) NOT NULL,
        prod_var_id VARCHAR(50) NOT NULL,
        pv_key_name_id VARCHAR(50) NOT NULL
    );
    
    DECLARE @SubProductVarKeyNames TABLE(
        pv_key_name_id VARCHAR(50) PRIMARY KEY NOT NULL,
        key_name VARCHAR(100) NOT NULL
    );
    
    INSERT INTO @StatusRef
    VALUES
    (
        'STAT-REF-1001', -- stat_ref_id
        'PENDING' -- com_usd_wrds
    ),
    (
        'STAT-REF-1002', -- stat_ref_id
        'APPROVED' -- com_usd_wrds
    ),
    (
        'STAT-REF-1003', -- stat_ref_id
        'PROCESSING' -- com_usd_wrds
    );
    
    INSERT INTO @Product
    VALUES
    (
        'PROD-ID-1001', -- prod_id
        'iPhone', -- prod_name
        0, -- stock | dependent to @SubProduct
        0.00 -- disc_price | dependent to @SubProduct
    ),
    (
        'PROD-ID-1002', -- prod_id
        'Samsung', -- prod_name
        0, -- stock | dependent to @SubProduct
        0.00 -- disc_price | dependent to @SubProduct
    ),
    (
        'PROD-ID-1003', -- prod_id
        'Nokia', -- prod_name
        75, -- stock
        33150.00 -- disc_price
    ),
    (
        'PROD-ID-1004', -- prod_id
        'Google', -- prod_name
        100, -- stock
        53509.00 -- disc_price
    ),
    (
        'PROD-ID-1005', -- prod_id
        'Sony', -- prod_name
        0, -- stock | dependent to @SubProduct
        0.00 -- disc_price | dependent to @SubProduct
    ),
    (
        'PROD-ID-1006', -- prod_id
        'Lenovo', -- prod_name
        0, -- stock | dependent to @SubProduct
        0.00 -- disc_price | dependent to @SubProduct
    );
    
    INSERT INTO @SubProduct
    VALUES
    (
        'PROD-VAR-ID-1', -- prod_var_id
        25, -- stock
        45809.00, -- disc_price
        'PROD-ID-1001' -- prod_id
    ),
    (
        'PROD-VAR-ID-2', -- prod_var_id
        50, -- stock
        40209.00, -- disc_price
        'PROD-ID-1002' -- prod_id
    ),
    (
        'PROD-VAR-ID-3', -- prod_var_id
        0, -- stock | dependent to @Product
        0.00, -- disc_price | dependent to @Product
        'PROD-ID-1003' -- prod_id
    ),
    (
        'PROD-VAR-ID-4', -- prod_var_id
        0, -- stock | dependent to @Product
        0.00, -- disc_price | dependent to @Product
        'PROD-ID-1004' -- prod_id
    ),
    (
        'PROD-VAR-ID-5', -- prod_var_id
        125, -- stock
        25809.00, -- disc_price
        'PROD-ID-1005' -- prod_id
    ),
    (
        'PROD-VAR-ID-6', -- prod_var_id
        150, -- stock
        49100.00, -- disc_price
        'PROD-ID-1006' -- prod_id
    );
    
    INSERT INTO @SubProductVarKeyValue
    VALUES
    (
        'new', -- value
        'PROD-VAR-ID-1', -- prod_var_id
        'PVKN-ID-1' -- pv_key_name_id
    ),
    (
        'new', -- value
        'PROD-VAR-ID-2', -- prod_var_id
        'PVKN-ID-1' -- pv_key_name_id
    ),
    (
        'new', -- value
        'PROD-VAR-ID-5', -- prod_var_id
        'PVKN-ID-1' -- pv_key_name_id
    ),
    (
        'new', -- value
        'PROD-VAR-ID-6', -- prod_var_id
        'PVKN-ID-1' -- pv_key_name_id
    )
    
    INSERT INTO @SubProductVarKeyNames
    VALUES
    (
        'PVKN-ID-1', -- pv_key_name_id
        'Condition' -- key_name
    )
    
    INSERT INTO @Orders
    (
        order_id,
        batch_code,
        quantity,
        stat_ref_id,
        dt_stamp,
        prod_id,
        prod_var_id,
        user_id
    )
    VALUES
    (
        'ORDER-2025-04-11-B71D0E2F5D8C', -- order_id
        NULL, -- batch_code
        1, -- quantity
        'STAT-REF-1003', -- stat_ref_id
        '2025-04-14 10:17:20.963', -- dt_stamp
        NULL, -- prod_id
        'PROD-VAR-ID-1', -- prod_var_id
        'UGUID-2025-01-27-14-09-22-1967-ABCDEFGHIJKL' -- user_id
    ),
    (
        'ORDER-2025-04-11-D95EB033CA40', -- order_id
        'BGUID-2025-04-11-6D81B58FAE94', -- batch_code
        2, -- quantity
        'STAT-REF-1001', -- stat_ref_id
        '2025-04-13 09:17:20.963', -- dt_stamp
        NULL, -- prod_id
        'PROD-VAR-ID-2', -- prod_var_id
        'UGUID-2025-01-27-14-09-22-1967-ABCDEFGHIJKL' -- user_id
    ),
    (
        'ORDER-2025-04-11-7F04EFA2BB60', -- order_id
        'BGUID-2025-04-11-6D81B58FAE94', -- batch_code
        2, -- quantity
        'STAT-REF-1001', -- stat_ref_id
        '2025-04-13 09:17:20.963', -- dt_stamp
        'PROD-ID-1003', -- prod_id
        NULL, -- prod_var_id
        'UGUID-2025-01-27-14-09-22-1967-ABCDEFGHIJKL' -- user_id
    ),
    (
        'ORDER-2025-04-10-3F03EAA47686', -- order_id
        'BGUID-2025-04-10-20239FD2059F', -- batch_code
        1, -- quantity
        'STAT-REF-1002', -- stat_ref_id
        '2025-04-12 08:17:20.963', -- dt_stamp
        'PROD-ID-1004', -- prod_id
        NULL, -- prod_var_id
        'UGUID-2025-01-27-14-09-22-1967-ABCDEFGHIJKL' -- user_id
    ),
    (
        'ORDER-2025-04-10-F4A89E2C4A30', -- order_id
        'BGUID-2025-04-10-20239FD2059F', -- batch_code
        1, -- quantity
        'STAT-REF-1002', -- stat_ref_id
        '2025-04-12 08:17:20.963', -- dt_stamp
        NULL, -- prod_id
        'PROD-VAR-ID-5', -- prod_var_id
        'UGUID-2025-01-27-14-09-22-1967-ABCDEFGHIJKL' -- user_id
    ),
    (
        'ORDER-2025-04-08-31BD887341FA', -- order_id
        NULL, -- batch_code
        1, -- quantity
        'STAT-REF-1001', -- stat_ref_id
        '2025-04-11 07:17:20.963', -- dt_stamp
        NULL, -- prod_id
        'PROD-VAR-ID-6', -- prod_var_id
        'UGUID-2025-01-27-14-09-22-1967-ABCDEFGHIJKL' -- user_id
    );
    
    INSERT INTO @Payment
    (
        amount_to_pay,
        order_id
    )
    VALUES
    (
        45809.00, -- amount_to_pay
        'ORDER-2025-04-11-B71D0E2F5D8C' -- order_id
    ),
    (
        146718.00, -- amount_to_pay
        'ORDER-2025-04-11-D95EB033CA40' -- order_id
    ),
    (
        146718.00, -- amount_to_pay
        'ORDER-2025-04-11-7F04EFA2BB60' -- order_id
    ),
    (
        79318.00, -- amount_to_pay
        'ORDER-2025-04-10-3F03EAA47686' -- order_id
    ),
    (
        79318.00, -- amount_to_pay
        'ORDER-2025-04-10-F4A89E2C4A30' -- order_id
    ),
    (
        49100.00, -- amount_to_pay
        'ORDER-2025-04-08-31BD887341FA' -- order_id
    );
    
    DECLARE @user_id VARCHAR(50) = 'UGUID-2025-01-27-14-09-22-1967-ABCDEFGHIJKL'; -- FOR TESTING PURPOSES ONLY
    DECLARE @status_t TABLE (status VARCHAR(50));
    INSERT INTO @status_t VALUES ('PENDING'),('APPROVED'),('PROCESSING')
    ;
    WITH p_orders
    AS
    (
        SELECT IIF(o.batch_code IS NULL, o.order_id, o.batch_code) as batch_id, o.* FROM @orders o
    )
    SELECT
        batchs.batch_code AS 'batch_code', -- FOR DEMONSTRATION PURPOSES ONLY
        oa_prod.nested_data AS 'nested_prod',
        cnb.amount_to_pay AS 'amount_to_pay'
    FROM
    (
        SELECT DISTINCT batch_id, batch_code, stat_ref_id, disable, user_id, dt_stamp FROM p_orders 
    )batchs
    RIGHT OUTER JOIN
    (
        SELECT DISTINCT o.batch_id, p.amount_to_pay, p.disable FROM p_orders o
        INNER JOIN @Payment p
        ON o.order_id = p.order_id
    )cnb
    ON
        batchs.batch_id = cnb.batch_id
    LEFT OUTER JOIN
        @StatusRef AS stat_ref
    ON
        batchs.stat_ref_id = stat_ref.stat_ref_id
    CROSS APPLY
    (
        SELECT
            orders.batch_code,
            orders.order_id,
            prod.prod_name,
            pv_kn.key_name,
            pv_kv.value,
            CASE WHEN
                orders.prod_id IS NOT NULL
            THEN
                prod.disc_price
            WHEN
                orders.prod_var_id IS NOT NULL
            THEN
                prod_var.disc_price
            END AS disc_price,
            orders.quantity
        FROM
            @Product AS prod
        RIGHT OUTER JOIN
            @SubProduct AS prod_var
        ON
            prod.prod_id = prod_var.prod_id
        INNER JOIN p_orders orders
        ON prod.prod_id = orders.prod_id 
            OR prod_var.prod_var_id = orders.prod_var_id
        LEFT OUTER JOIN
            @SubProductVarKeyValue AS pv_kv
        ON
            prod_var.prod_var_id = pv_kv.prod_var_id
        LEFT OUTER JOIN
            @SubProductVarKeyNames AS pv_kn
        ON
            pv_kv.pv_key_name_id = pv_kn.pv_key_name_id
        WHERE       
            orders.batch_id = batchs.batch_id
        FOR JSON PATH,
        INCLUDE_NULL_VALUES
    )AS oa_prod(nested_data)
    WHERE
        batchs.disable = 0
        AND cnb.disable = 0
        AND batchs.user_id = @user_id
        AND stat_ref.com_usd_wrds IN (SELECT status FROM @status_t)
    ORDER BY
        batchs.dt_stamp DESC
    FOR JSON PATH,
    INCLUDE_NULL_VALUES
    

    Code without CTE:

    DECLARE @StatusRef TABLE(
        stat_ref_id VARCHAR(50) PRIMARY KEY NOT NULL,
        com_usd_wrds NVARCHAR(100) NOT NULL
    );
    
    DECLARE @Product TABLE(
        prod_id VARCHAR(50) PRIMARY KEY NOT NULL,
        prod_name VARCHAR(200) NOT NULL,
        stock INT NOT NULL,
        disc_price DECIMAL(12, 2) NOT NULL
    );
    
    DECLARE @SubProduct TABLE(
        prod_var_id VARCHAR(50) PRIMARY KEY NOT NULL,
        stock INT NOT NULL,
        disc_price DECIMAL(12, 2) NOT NULL,
        prod_id VARCHAR(50) NOT NULL
    );
    
    DECLARE @Orders TABLE(
        order_id VARCHAR(50) PRIMARY KEY NOT NULL,
        batch_code VARCHAR(50) NULL,
        quantity INT NOT NULL,
        stat_ref_id VARCHAR(50) NOT NULL,
        disable BIT DEFAULT (0) NOT NULL,
        dt_stamp DATETIME NOT NULL,
        prod_id VARCHAR(50) NULL,
        prod_var_id VARCHAR(50) NULL,
        user_id VARCHAR(50) NOT NULL
    );
    
    DECLARE @Payment TABLE(
        amount_to_pay DECIMAL(14, 2) NOT NULL,
        order_id VARCHAR(50) NOT NULL,
        disable BIT DEFAULT (0) NOT NULL
    );
    
    DECLARE @SubProductVarKeyValue TABLE(
        value VARCHAR(100) NOT NULL,
        prod_var_id VARCHAR(50) NOT NULL,
        pv_key_name_id VARCHAR(50) NOT NULL
    );
    
    DECLARE @SubProductVarKeyNames TABLE(
        pv_key_name_id VARCHAR(50) PRIMARY KEY NOT NULL,
        key_name VARCHAR(100) NOT NULL
    );
    
    INSERT INTO @StatusRef
    VALUES
    (
        'STAT-REF-1001', -- stat_ref_id
        'PENDING' -- com_usd_wrds
    ),
    (
        'STAT-REF-1002', -- stat_ref_id
        'APPROVED' -- com_usd_wrds
    ),
    (
        'STAT-REF-1003', -- stat_ref_id
        'PROCESSING' -- com_usd_wrds
    );
    
    INSERT INTO @Product
    VALUES
    (
        'PROD-ID-1001', -- prod_id
        'iPhone', -- prod_name
        0, -- stock | dependent to @SubProduct
        0.00 -- disc_price | dependent to @SubProduct
    ),
    (
        'PROD-ID-1002', -- prod_id
        'Samsung', -- prod_name
        0, -- stock | dependent to @SubProduct
        0.00 -- disc_price | dependent to @SubProduct
    ),
    (
        'PROD-ID-1003', -- prod_id
        'Nokia', -- prod_name
        75, -- stock
        33150.00 -- disc_price
    ),
    (
        'PROD-ID-1004', -- prod_id
        'Google', -- prod_name
        100, -- stock
        53509.00 -- disc_price
    ),
    (
        'PROD-ID-1005', -- prod_id
        'Sony', -- prod_name
        0, -- stock | dependent to @SubProduct
        0.00 -- disc_price | dependent to @SubProduct
    ),
    (
        'PROD-ID-1006', -- prod_id
        'Lenovo', -- prod_name
        0, -- stock | dependent to @SubProduct
        0.00 -- disc_price | dependent to @SubProduct
    );
    
    INSERT INTO @SubProduct
    VALUES
    (
        'PROD-VAR-ID-1', -- prod_var_id
        25, -- stock
        45809.00, -- disc_price
        'PROD-ID-1001' -- prod_id
    ),
    (
        'PROD-VAR-ID-2', -- prod_var_id
        50, -- stock
        40209.00, -- disc_price
        'PROD-ID-1002' -- prod_id
    ),
    (
        'PROD-VAR-ID-3', -- prod_var_id
        0, -- stock | dependent to @Product
        0.00, -- disc_price | dependent to @Product
        'PROD-ID-1003' -- prod_id
    ),
    (
        'PROD-VAR-ID-4', -- prod_var_id
        0, -- stock | dependent to @Product
        0.00, -- disc_price | dependent to @Product
        'PROD-ID-1004' -- prod_id
    ),
    (
        'PROD-VAR-ID-5', -- prod_var_id
        125, -- stock
        25809.00, -- disc_price
        'PROD-ID-1005' -- prod_id
    ),
    (
        'PROD-VAR-ID-6', -- prod_var_id
        150, -- stock
        49100.00, -- disc_price
        'PROD-ID-1006' -- prod_id
    );
    
    INSERT INTO @SubProductVarKeyValue
    VALUES
    (
        'new', -- value
        'PROD-VAR-ID-1', -- prod_var_id
        'PVKN-ID-1' -- pv_key_name_id
    ),
    (
        'new', -- value
        'PROD-VAR-ID-2', -- prod_var_id
        'PVKN-ID-1' -- pv_key_name_id
    ),
    (
        'new', -- value
        'PROD-VAR-ID-5', -- prod_var_id
        'PVKN-ID-1' -- pv_key_name_id
    ),
    (
        'new', -- value
        'PROD-VAR-ID-6', -- prod_var_id
        'PVKN-ID-1' -- pv_key_name_id
    )
    
    INSERT INTO @SubProductVarKeyNames
    VALUES
    (
        'PVKN-ID-1', -- pv_key_name_id
        'Condition' -- key_name
    )
    
    INSERT INTO @Orders
    (
        order_id,
        batch_code,
        quantity,
        stat_ref_id,
        dt_stamp,
        prod_id,
        prod_var_id,
        user_id
    )
    VALUES
    (
        'ORDER-2025-04-11-B71D0E2F5D8C', -- order_id
        NULL, -- batch_code
        1, -- quantity
        'STAT-REF-1003', -- stat_ref_id
        '2025-04-14 10:17:20.963', -- dt_stamp
        NULL, -- prod_id
        'PROD-VAR-ID-1', -- prod_var_id
        'UGUID-2025-01-27-14-09-22-1967-ABCDEFGHIJKL' -- user_id
    ),
    (
        'ORDER-2025-04-11-D95EB033CA40', -- order_id
        'BGUID-2025-04-11-6D81B58FAE94', -- batch_code
        2, -- quantity
        'STAT-REF-1001', -- stat_ref_id
        '2025-04-13 09:17:20.963', -- dt_stamp
        NULL, -- prod_id
        'PROD-VAR-ID-2', -- prod_var_id
        'UGUID-2025-01-27-14-09-22-1967-ABCDEFGHIJKL' -- user_id
    ),
    (
        'ORDER-2025-04-11-7F04EFA2BB60', -- order_id
        'BGUID-2025-04-11-6D81B58FAE94', -- batch_code
        2, -- quantity
        'STAT-REF-1001', -- stat_ref_id
        '2025-04-13 09:17:20.963', -- dt_stamp
        'PROD-ID-1003', -- prod_id
        NULL, -- prod_var_id
        'UGUID-2025-01-27-14-09-22-1967-ABCDEFGHIJKL' -- user_id
    ),
    (
        'ORDER-2025-04-10-3F03EAA47686', -- order_id
        'BGUID-2025-04-10-20239FD2059F', -- batch_code
        1, -- quantity
        'STAT-REF-1002', -- stat_ref_id
        '2025-04-12 08:17:20.963', -- dt_stamp
        'PROD-ID-1004', -- prod_id
        NULL, -- prod_var_id
        'UGUID-2025-01-27-14-09-22-1967-ABCDEFGHIJKL' -- user_id
    ),
    (
        'ORDER-2025-04-10-F4A89E2C4A30', -- order_id
        'BGUID-2025-04-10-20239FD2059F', -- batch_code
        1, -- quantity
        'STAT-REF-1002', -- stat_ref_id
        '2025-04-12 08:17:20.963', -- dt_stamp
        NULL, -- prod_id
        'PROD-VAR-ID-5', -- prod_var_id
        'UGUID-2025-01-27-14-09-22-1967-ABCDEFGHIJKL' -- user_id
    ),
    (
        'ORDER-2025-04-08-31BD887341FA', -- order_id
        NULL, -- batch_code
        1, -- quantity
        'STAT-REF-1001', -- stat_ref_id
        '2025-04-11 07:17:20.963', -- dt_stamp
        NULL, -- prod_id
        'PROD-VAR-ID-6', -- prod_var_id
        'UGUID-2025-01-27-14-09-22-1967-ABCDEFGHIJKL' -- user_id
    );
    
    INSERT INTO @Payment
    (
        amount_to_pay,
        order_id
    )
    VALUES
    (
        45809.00, -- amount_to_pay
        'ORDER-2025-04-11-B71D0E2F5D8C' -- order_id
    ),
    (
        146718.00, -- amount_to_pay
        'ORDER-2025-04-11-D95EB033CA40' -- order_id
    ),
    (
        146718.00, -- amount_to_pay
        'ORDER-2025-04-11-7F04EFA2BB60' -- order_id
    ),
    (
        79318.00, -- amount_to_pay
        'ORDER-2025-04-10-3F03EAA47686' -- order_id
    ),
    (
        79318.00, -- amount_to_pay
        'ORDER-2025-04-10-F4A89E2C4A30' -- order_id
    ),
    (
        49100.00, -- amount_to_pay
        'ORDER-2025-04-08-31BD887341FA' -- order_id
    );
    
    DECLARE @user_id VARCHAR(50) = 'UGUID-2025-01-27-14-09-22-1967-ABCDEFGHIJKL'; -- FOR TESTING PURPOSES ONLY
    DECLARE @status_t TABLE (status VARCHAR(50));
    INSERT INTO @status_t VALUES ('PENDING'),('APPROVED'),('PROCESSING')
    
    SELECT
        batches.batch_code AS 'batch_code', -- FOR DEMONSTRATION PURPOSES ONLY
        oa_prod.nested_data AS 'nested_prod',
        cnb.amount_to_pay AS 'amount_to_pay'
    FROM
    (
        SELECT DISTINCT 
            IIF(o.batch_code IS NULL, o.order_id, o.batch_code) as batch_id, 
            batch_code, stat_ref_id, disable, user_id, dt_stamp FROM @orders o
    )batches
    RIGHT OUTER JOIN
    (
        SELECT DISTINCT IIF(o.batch_code IS NULL, o.order_id, o.batch_code) as batch_id, 
            p.amount_to_pay, p.disable 
        FROM @orders o INNER JOIN @Payment p
        ON o.order_id = p.order_id
    )cnb
    ON
        batches.batch_id = cnb.batch_id
    LEFT OUTER JOIN
        @StatusRef AS stat_ref
    ON
        batches.stat_ref_id = stat_ref.stat_ref_id
    CROSS APPLY
    (
        SELECT
            orders.batch_code,
            orders.order_id,
            prod.prod_name,
            pv_kn.key_name,
            pv_kv.value,
            CASE WHEN
                orders.prod_id IS NOT NULL
            THEN
                prod.disc_price
            WHEN
                orders.prod_var_id IS NOT NULL
            THEN
                prod_var.disc_price
            END AS disc_price,
            orders.quantity
        FROM
            @Product AS prod
        RIGHT OUTER JOIN
            @SubProduct AS prod_var
        ON
            prod.prod_id = prod_var.prod_id
        INNER JOIN 
        (
            SELECT IIF(o.batch_code IS NULL, o.order_id, o.batch_code) as batch_id, o.* FROM @orders o
        )AS orders
        ON prod.prod_id = orders.prod_id 
            OR prod_var.prod_var_id = orders.prod_var_id
        LEFT OUTER JOIN
            @SubProductVarKeyValue AS pv_kv
        ON
            prod_var.prod_var_id = pv_kv.prod_var_id
        LEFT OUTER JOIN
            @SubProductVarKeyNames AS pv_kn
        ON
            pv_kv.pv_key_name_id = pv_kn.pv_key_name_id
        WHERE       
            orders.batch_id = batches.batch_id
        FOR JSON PATH,
        INCLUDE_NULL_VALUES
    )AS oa_prod(nested_data)
    WHERE
        batches.disable = 0
        AND cnb.disable = 0
        AND batches.user_id = @user_id
        AND stat_ref.com_usd_wrds IN (SELECT status FROM @status_t)
    ORDER BY
        batches.dt_stamp DESC
    FOR JSON PATH,
    INCLUDE_NULL_VALUES
    
    • 1

relate perguntas

  • SQL Server - Como as páginas de dados são armazenadas ao usar um índice clusterizado

  • Preciso de índices separados para cada tipo de consulta ou um índice de várias colunas funcionará?

  • Quando devo usar uma restrição exclusiva em vez de um índice exclusivo?

  • Quais são as principais causas de deadlocks e podem ser evitadas?

  • Como determinar se um Índice é necessário ou necessário

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

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

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve