Суммируйте результаты нескольких сгруппированных документов

couchbase n1ql

330 просмотра

1 ответ

Я настроил схему, в которой я связываю две разные сущности: пользователей и брендов. Эта ассоциация хранится в документе UserBrand. Пользователь может иметь несколько брендов, и в каждом документе UserBrand содержащаяся в нем информация различна.

Вот пример трех документов:

{
    type: "UserBrand",
    userId: "x",
    brandId: 1,
    value: 100
}

{
    type: "UserBrand",
    userId: "x",
    brandId: 2,
    value: 50
}

{
    type: "UserBrand",
    userId: "y",
    brandId: 1,
    value: 150
}

Как видите, пользователь «х» следует нескольким брендам. Как я могу получить сумму значений, сгруппированных по пользователю, при получении информации о пользователе?

До сих пор я могу объединить оба типа документов (User и UserBrand) с помощью этого запроса:

SELECT ub.*, u.name FROM bucket as ub JOIN bucket as u ON KEYS "User_" || ub.userId WHERE ub.type="UserBrand" AND u.type="User" AND (ub.brand=1 OR ub.brand=2)

но я не могу сгруппировать записи и суммировать значения для одного пользователя. Можно ли сделать это по одному запросу?

Если возможно, конечный результат должен выглядеть примерно так:

{
    type: "UserBrand",
    name: "name1',
    userId: "x",
    brandId: 1,
    value: 150
}

{
    type: "UserBrand",
    name: "name2',
    userId: "y",
    brandId: 1,
    value: 150
}
Автор: Manuel Reis Источник Размещён: 08.11.2019 11:25

Ответы (1)


0 плюса

Почему вы используете «объединение» вместо «группировать по» и агрегации? Если бы я хотел суммировать значения для каждого отдельного идентификатора пользователя, я бы написал запрос следующим образом:

select userId, sum(value) from bucket group by userId;

Обратите внимание, что при использовании «group by» каждое поле в списке выбора должно быть либо частью списка «group by» (userId выше), либо выражением агрегации (например, sum (value) выше). Но что, если вы хотите включить поле «имя» в результат? Если вы знаете, что «имя» всегда имеет одно и то же значение для данного идентификатора, вы можете использовать функцию агрегирования, такую ​​как «max» или «min», чтобы вывести значение (поскольку max из набора идентичных значений будет любым из ценности):

select userId, max(name), sum(value) from bucket group by userId;

Для поля типа «brandId», которое, кажется, имеет разные значения, вы должны использовать функцию агрегирования, например «array_agg», которая будет принимать все различные значения «brandId» и помещать их в массив. Например,

select userId, max(name), sum(value), array_agg(distinct brandId) from bucket group by userId;
Автор: EbenH Размещён: 22.08.2016 03:50
Вопросы из категории :
32x32