N1QL多重联接和求和查询产生错误的输出

时间:2019-10-30 08:07:14

标签: couchbase n1ql

我有一个包含以下三个文档的存储桶:

source ~/.bashrc

我已使用Couchbase Server Community Edition 6.0.0在N1QL中编写了以下查询:

coffee {
    id
}

cold_coffee {
    coffeeId
    number
}

warm_coffee {
    coffeeId
    number
}

我为每份咖啡有多个cold_coffee和warm_coffee文档,我需要对所有cold_coffee和warm_coffee文档的数量求和。我遇到的问题是,例如,如果我有以下文档:

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;

我的总计如下:

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

似乎因为加入而对单个warm_coffee文件进行了两次计数?

我碰到了这个site,可能有相同的错误,但不幸的是它是SQL。

而且我不确定如何使用N1QL解决此问题,因为JOIN的右手项必须是表/存储桶,如以下post所示。

这里可能是solution,但我不确定N1QL是如何实现的?

有人可以帮忙吗?

1 个答案:

答案 0 :(得分:3)

JOINS可以扩展原始行。在第一个Join左边,大多数文档被展开。您将第一个文档字段用作第二个连接条件,该条件可以产生多个条件相同的文档。这就是语义的工作方式。您需要根据需要调整加入条件。

第二个JOIN最多使用左边的一个文档。 DISTINCT上的SUM可能不起作用,因为对相同值(warm_coffee,可能正在计数)的不同文档计数一次。如果我是对的,那么您正在寻找第二次加入,以使用LEFT大多数咖啡中的独特文档。

也许您正在寻找这样的东西

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
;