N1QL Многократный запрос на объединение и суммирование приводит к неправильному выводу - PullRequest
1 голос
/ 30 октября 2019

У меня есть корзина, содержащая следующие три документа:

coffee {
    id
}

cold_coffee {
    coffeeId
    number
}

warm_coffee {
    coffeeId
    number
}

Я написал следующий запрос в N1QL с использованием Couchbase Server Community Edition 6.0.0:

SELECT META(coffee).id as coffeeId,
SUM(cold_coffee.`number`) as `ccNumber`,
SUM(warm_coffee.`number`) as `wcNumber`,
FROM coffee_bucket coffee
left JOIN coffee_bucket cold_coffee
    ON  META(coffee).id = cold_coffee.coffeeId 
    and cold_coffee.type='cold_coffee'
left JOIN coffee_bucket warm_coffee
    ON META(coffee).id = warm_coffee.coffeeId 
    and warm_coffee.type='warm_coffee'
where coffee.type='coffee'
group by META(coffee).id;

У меня естьнесколько документов cold_coffee и warm_coffee для каждого кофе, и мне нужно сложить числа для всех документов cold_coffee и warm_coffee. У меня проблема в том, что если, например, у меня есть следующие документы:

[
    coffee {
        id: 1
    },
    cold_coffee {
        coffeeId:1
        number:5 
    },
    cold_coffee {
        coffeeId:1
        number:5 
    },
    warm_coffee {
        coffeeId:1
        number:10
    }
]

Мои итоги следующие:

ccNumber: 10
wcNumber:20 

Кажется, из-за объединений одного документа warm_coffeeподсчитывается дважды?

Я столкнулся с этим сайтом , возможно, с той же ошибкой, но, к сожалению, это SQL.

И я не уверен, как решить эту проблему с помощью N1QL, потому чтоПравильный термин JOIN должен быть таблицей / контейнером, как показано в следующем post .

Вот возможное решение , но я не уверен, как реализоватьэто N1QL?

Может кто-нибудь помочь?

1 Ответ

3 голосов
/ 30 октября 2019

СОЕДИНЕНИЯ могут расширять исходные строки. Во время первого соединения левее всего документ раскрывается. Вы используете первое поле документа в качестве второго условия соединения, которое может создавать несколько документов с одинаковым условием. Вот как работает семантика. Вам необходимо настроить условие соединения в соответствии с потребностями.

Во втором JOIN больше всего используется один документ из левого. SUM over DISTINCT может не сработать, потому что разные документы с одинаковым значением (warm_coffee, может быть меньше) считаются один раз. Если я прав, вы ищете второе объединение, чтобы использовать уникальный документ от ЛЕВОГО большинства кофе.

Может быть, вы ищете что-то вроде этого

SELECT c.coffeeId,
       MAX(c.ccNumber) AS `ccNumber`,
       SUM(warm_coffee.`number`) AS `wcNumber`,
FROM ( SELECT META(coffee).id AS coffeeId,
       SUM(cold_coffee.`number`) AS `ccNumber`
       FROM coffee_bucket coffee
       LEFT JOIN coffee_bucket cold_coffee
            ON  META(coffee).id = cold_coffee.coffeeId AND cold_coffee.type='cold_coffee'
       WHERE coffee.type='coffee'
       GROUP BY META(coffee).id
     ) AS c
LEFT JOIN coffee_bucket warm_coffee
          ON c.coffeeId = warm_coffee.coffeeId AND warm_coffee.type='warm_coffee'
GROUP BY c.coffeeId;

3 уровня объединения

SELECT d.coffeeId,
       MAX(c.ccNumber) AS `ccNumber`,
       MAX(c.wcNumber) AS `wcNumber`,
       SUM(ch.`number`) AS `chNumber`
FROM ( SELECT c.coffeeId,
              MAX(c.ccNumber) AS `ccNumber`,
              SUM(warm_coffee.`number`) AS `wcNumber`,
       FROM ( SELECT META(coffee).id AS coffeeId,
              SUM(cold_coffee.`number`) AS `ccNumber`
              FROM coffee_bucket coffee
              LEFT JOIN coffee_bucket cold_coffee
                   ON  META(coffee).id = cold_coffee.coffeeId AND cold_coffee.type='cold_coffee'
              WHERE coffee.type='coffee'
              GROUP BY META(coffee).id
            ) AS c
       LEFT JOIN coffee_bucket warm_coffee
                 ON c.coffeeId = warm_coffee.coffeeId AND warm_coffee.type='warm_coffee'
       GROUP BY c.coffeeId) AS d
LEFT JOIN coffee_bucket ch
     ON d.coffeeId = ch.coffeeId AND ch.type='chaoc_coffee'
GROUP BY d.coffeeId
;
...