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

Couchbase N1QL多重联接和求和查询产生错误输出,couchbase,n1ql,Couchbase,N1ql,我有一个桶,里面有以下三个文件: coffee { id } cold_coffee { coffeeId number } warm_coffee { coffeeId number } [ coffee { id: 1 }, cold_coffee { coffeeId:1 number:5 }, cold_coffee { coffeeId

我有一个桶,里面有以下三个文件:

coffee {
    id
}

cold_coffee {
    coffeeId
    number
}

warm_coffee {
    coffeeId
    number
}
[
    coffee {
        id: 1
    },
    cold_coffee {
        coffeeId:1
        number:5 
    },
    cold_coffee {
        coffeeId:1
        number:5 
    },
    warm_coffee {
        coffeeId:1
        number:10
    }
]
我使用Couchbase Server Community Edition 6.0.0在N1QL中编写了以下查询:

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
}

cold_coffee {
    coffeeId
    number
}

warm_coffee {
    coffeeId
    number
}
[
    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 
似乎因为加入的原因,一份温咖啡文件被计算了两次

我遇到这个问题时可能有相同的错误,但不幸的是,它是SQL

我不确定如何使用N1QL解决这个问题,因为连接的右边术语必须是表/存储桶,如下所示

这里有一个可能的解决方案,但我不确定如何实现这是N1QL


有人能帮忙吗?

联接可以扩展原始行。在第一次连接期间,最左边的文档被展开。您正在使用第一个文档字段作为第二个联接条件,它可以在相同条件下生成多个文档。这就是语义的工作原理。您需要根据需要调整连接条件

第二个联接使用最左边的一个文档。由于不同的文件相同的值加起来可能不起作用,可能计数不足一次。如果我是对的,你正在寻找第二个加入使用从最左边的咖啡独特的文件

也许你看起来像这样

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;
三级连接

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
;

联接可以展开原始行。在第一次连接期间,最左边的文档被展开。您正在使用第一个文档字段作为第二个联接条件,它可以在相同条件下生成多个文档。这就是语义的工作原理。您需要根据需要调整连接条件

第二个联接使用最左边的一个文档。由于不同的文件相同的值加起来可能不起作用,可能计数不足一次。如果我是对的,你正在寻找第二个加入使用从最左边的咖啡独特的文件

也许你看起来像这样

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;
三级连接

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
;

伟大的非常感谢你的帮助!例如,如果添加了另一份文件,如choc_coffee,并且所有这些文件都需要一笔款项,请给出建议?我正在努力理解如何将这种逻辑添加到您的解决方案中?谢谢顺便说一句,如果这两个文档需要求和,则此代码有效。请勾选3级联接。相关子查询需要使用键。否则,使用相关子querygreat会更容易!非常感谢你的帮助!例如,如果添加了另一份文件,如choc_coffee,并且所有这些文件都需要一笔款项,请给出建议?我正在努力理解如何将这种逻辑添加到您的解决方案中?谢谢顺便说一句,如果这两个文档需要求和,则此代码有效。请勾选3级联接。相关子查询需要使用键。否则,使用相关子查询会更容易