我正在尝试运行一个聚合查询,其中联接可以在联接表中找到0、1或2行。 我想聚合“仅一次”,无论联接是找到1还是2个匹配行。
最小的例子。
+--------------+--------+-----------+
| container_id | thing | alternate |
+--------------+--------+-----------+
| 1 | box | 0 |
| 1 | box | 1 |
| 1 | hat | 0 |
| 2 | monkey | 0 |
| 3 | monkey | 1 |
| 3 | chair | 1 |
+--------------+--------+-----------+
+--------------+------+
| container_id | uses |
+--------------+------+
| 1 | 3 |
| 2 | 1 |
| 3 | 2 |
+--------------+------+
您可以看到“框”两次与1号容器ID关联。一次使用alternate = 0,一次使用alternate = 1。
SELECT
thing, COUNT(DISTINCT ct.container_id) AS occurrencs, SUM(uses) AS uses
FROM
container_thing AS ct
INNER JOIN
container_usage AS cu ON cu.container_id = ct.container_id
GROUP BY
thing
给予:
+--------+------------+------+
| thing | occurrencs | uses |
+--------+------------+------+
| box | 1 | 6 |
| chair | 1 | 2 |
| hat | 1 | 3 |
| monkey | 2 | 3 |
+--------+------------+------+
但我真正想要的是:
+--------+------------+------+
| thing | occurrencs | uses |
+--------+------------+------+
| box | 1 | 3 |
| chair | 1 | 2 |
| hat | 1 | 3 |
| monkey | 2 | 3 |
+--------+------------+------+
我希望3作为第一行的使用值,因为“盒子”在总共使用了3次的容器中。由于使用“ alternate”列,因此该值得到6。 我可以以不同的方式加入或以不同的方式分组,还是可以在SUM表达式中对每个不同的事物仅进行一次SUM运算,而不论alter的值如何?
(请注意,事物可以在容器中交替显示,也可以不同时显示或不同时显示。)
设置最小示例所需的SQL:
-- Set up db
CREATE DATABASE sumtest;
USE sumtest;
-- Set up tables
CREATE TABLE container (id INT PRIMARY KEY);
CREATE TABLE container_thing (container_id INT, thing NVARCHAR(10), alternate BOOLEAN);
CREATE TABLE container_usage (container_id INT, uses INT);
-- Insert data
INSERT INTO container (id) VALUES (1), (2), (3);
INSERT INTO container_thing (container_id, thing, alternate) VALUES (1, 'box', FALSE), (1, 'box', TRUE), (1, 'hat', FALSE), (2, 'monkey', FALSE), (3, 'monkey', TRUE), (3, 'chair', TRUE);
INSERT INTO container_usage VALUES (1, 3), (2, 1), (3, 2);
-- Query
SELECT thing, COUNT(DISTINCT ct.container_id) AS occurrencs, SUM(uses) AS uses FROM container_thing AS ct INNER JOIN container_usage AS cu ON cu.container_id = ct.container_id GROUP BY thing;
答案 0 :(得分:0)
如果只想使用..,则不应在join ..中执行总和,因为该联接会为每个macthing ON子句产生T1xT2行
其中N是来自table1的行数,而M是来自table2的行数,因此在box的情况下,您有2 x 1的值3 = 6。
为避免这种情况,您应该将container_usage与subqiery一起加入以得到关于container_thing计数的综合结果
select t.thing, t.count_container, cu.uses
from (
SELECT thing, container_id, COUNT(DISTINCT ct.container_id) count_container
FROM container_thing
GROUP BY thing, container_id
) t
inner join container_usage AS cu ON cu.container_id = t.container_id
答案 1 :(得分:0)
您可以通过仅从派生表中的DISTINCT
中选择container_id
和thing
的{{1}}值并将它们container_thing
{ 1}}:
JOIN
输出
container_usage