Агрегация запросов Couchbase N1QL - PullRequest
1 голос
/ 18 апреля 2019

Я пытаюсь написать запрос, который будет агрегировать результаты запроса, чтобы обеспечить итоговые значения для сопоставленных результатов.

Документы в корзине выглядят следующим образом:

{
    "clientId": "test-client",
    "event": {
        "history": [
            {
                "code": "FAILED",
                "serviceId": "s1"
            },
            {
                "code": "SUCCESS",
                "serviceId": "s2"
            }
        ],
        "size": 200
    }
},
{
    "clientId": "test-client",
    "event": {
        "history": [
            {
                "code": "FAILED",
                "serviceId": "s1"
            },
            {
                "code": "SUCCESS",
                "serviceId": "s2"
            }
        ],
        "size": 200
    }
},
{
    "clientId": "test-client",
    "event": {
        "history": [
            {
                "code": "SUCCESS",
                "serviceId": "s1"
            }
        ],
        "size": 200
    }
}

Выходной документ, который я ищу, выглядит следующим образом:

{
    "clientId": "test-client",
    "totalSize": 600,
    "totalVolume": 3,
    "serviceSummary": [
        {
            "serviceId": "s1",
            "serviceTotalSize": 200,
            "serviceTotalVolume": 1
        },
        {
            "serviceId": "s2",
            "serviceTotalSize": 400,
            "serviceTotalVolume": 2
        }
    ]
}

Таким образом, запрос должен

  • агрегировать все результаты для clientId, вычисляя totalSize и totalVolume
  • посмотрите на содержимое массива истории и найдите идентификатор службы с кодом «SUCCESS»
  • предоставит общий размер и объем для serivceId, где событие было успешным

Пока у меня есть запрос, подобный этому:

select 
    d.clientId, 
    count(*) totalVolume, 
    sum(d.event.size) totalSize ,
    ARRAY_AGG(DISTINCT h.serviceId) serviceSummary
from demo d
unnest d.event.history h
where h.code = 'SUCCESS'
group by d.clientId;

, который выдает часть результата, который я хочу, но не полный serviceSummary

спасибо за любую помощь.

1 Ответ

2 голосов
/ 18 апреля 2019

Стандарты SQL не допускают вложенных агрегатов, в которых вам нужен промежуточный подзапрос с многоуровневыми агрегатами.

SELECT d1.clientId,
       SUM(d1.serviceTotalVolume) AS totalVolume,
       SUM(d1.serviceTotalSize) AS totalSize,
       ARRAY_AGG({d1.serviceId, d1.serviceTotalVolume, d1.serviceTotalSize}) AS serviceSummary
FROM ( SELECT
             d.clientId,
             h.serviceId,
             COUNT(1) AS serviceTotalVolume,
             SUM(d.event.size) AS serviceTotalSize
       FROM demo AS d
       UNNEST d.event.history AS h
       WHERE h.code = 'SUCCESS'
       GROUP BY d.clientId, h.serviceId) AS d1
GROUP BY d1.clientId;
...