我在一个表(A)中有一个东西,在另外两个表中有一个类别(C1,C2) category_id来自不同的表格(MC)。
我想计算特定类别中有多少东西。
实时数据示例:
表A
main_key (unique) stuff_id (non unique)
1 7
2 6
3 3
表C1
category_id main_key (it is FK for A table)
1 1
1 2
3 1
表C2
category_id main_key (it is FK for A table)
2 3
2 1
表格MC
category_id category_name
1 blablbl
2 asas
3 asasa
...
之间的关系: C1和A尽可能多 C2和A尽可能多 C1或C2和MC多对一
在当前示例中,我希望将最终结果视为
stuff_qnt category_id category_name
2 1 blablbl
2 2 asas
1 3 asasa
如何通过一个查询实现它?
我的查询是:
SELECT count(A.stuff_id) as stuff_qnt, MC.category_id, MC.category_name
FROM A
LEFT JOIN C1 using(main_key)
LEFT JOIN C2 using(main_key)
LEFT JOIN MC ON (C1.category_id = MC.category_id AND C2.category_id = MC.category_id)
GROUP BY C1.category_id, C2.category_id
但它告诉我错误的结果,我做错了什么?
答案 0 :(得分:1)
SELECT COUNT(*) AS Stuff_Qnt, C.Category_ID, MC.Category_Name
FROM MC
JOIN (SELECT C1.Category_ID
FROM A
JOIN C1 ON A.Main_Key = C1.Main_Key
UNION ALL
SELECT C2.Category_ID
FROM A
JOIN C2 ON A.Main_Key = C2.Main_Key
) AS C
ON C.Category_ID = MC.Category_ID
GROUP BY C.Category_ID, MC.Category_Name
ORDER BY C.Category_ID, Stuff_Qnt;
你需要加入A和C1的类别以及加入A和C2的类别,你绝对不需要笛卡尔产品,例如你得到LEFT OUTER JOIN,所以你拿了列表的UNION类别ID,然后聚合并加入MC。
CREATE TABLE A
(
main_key INTEGER NOT NULL PRIMARY KEY,
stuff_id INTEGER NOT NULL
);
INSERT INTO A VALUES(1, 7);
INSERT INTO A VALUES(2, 6);
INSERT INTO A VALUES(3, 3);
CREATE TABLE MC
(
category_id INTEGER NOT NULL PRIMARY KEY,
category_name VARCHAR(10) NOT NULL
);
INSERT INTO mc VALUES(1, "blablbl");
INSERT INTO mc VALUES(2, "asas");
INSERT INTO mc VALUES(3, "asasa");
CREATE TABLE C1
(
category_id INTEGER NOT NULL REFERENCES mc,
main_key INTEGER NOT NULL REFERENCES a
);
INSERT INTO c1 VALUES(1, 1);
INSERT INTO c1 VALUES(1, 2);
INSERT INTO c1 VALUES(3, 1);
CREATE TABLE C2
(
category_id INTEGER NOT NULL REFERENCES mc,
main_key INTEGER NOT NULL REFERENCES a
);
INSERT INTO c2 VALUES(2, 3);
INSERT INTO c2 VALUES(2, 1);
SELECT COUNT(*) AS Stuff_Qnt, C.Category_ID, MC.Category_Name
FROM MC
JOIN (SELECT C1.Category_ID
FROM A
JOIN C1 ON A.Main_Key = C1.Main_Key
UNION ALL
SELECT C2.Category_ID
FROM A
JOIN C2 ON A.Main_Key = C2.Main_Key
) AS C
ON C.Category_ID = MC.Category_ID
GROUP BY C.Category_ID, MC.Category_Name
ORDER BY C.Category_ID, Stuff_Qnt;
输出:
2 1 blablbl
2 2 asas
1 3 asasa
这是进一步的测试,在A中有两个额外的行,在C1和C2中有相应的行。测试了两个查询,我和query dkkumargoyal。
CREATE TABLE A(main_key INTEGER NOT NULL PRIMARY KEY, stuff_id INTEGER NOT NULL);
INSERT INTO A VALUES(1, 7);
INSERT INTO A VALUES(2, 6);
INSERT INTO A VALUES(3, 3);
INSERT INTO A VALUES(4, 3);
INSERT INTO A VALUES(5, 3);
CREATE TABLE MC(category_id INTEGER NOT NULL PRIMARY KEY, category_name VARCHAR(10) NOT NULL);
INSERT INTO mc VALUES(1, "blablbl");
INSERT INTO mc VALUES(2, "asas");
INSERT INTO mc VALUES(3, "asasa");
CREATE TABLE C1(category_id INTEGER NOT NULL REFERENCES mc, main_key INTEGER NOT NULL REFERENCES a);
INSERT INTO c1 VALUES(1, 1);
INSERT INTO c1 VALUES(1, 2);
INSERT INTO c1 VALUES(3, 1);
INSERT INTO c1 VALUES(3, 4);
INSERT INTO c1 VALUES(1, 4);
INSERT INTO c1 VALUES(1, 5);
CREATE TABLE C2(category_id INTEGER NOT NULL REFERENCES mc, main_key INTEGER NOT NULL REFERENCES a);
INSERT INTO c2 VALUES(2, 3);
INSERT INTO c2 VALUES(2, 1);
INSERT INTO c2 VALUES(2, 5);
SELECT COUNT(*) AS Stuff_Qnt, C.Category_ID, MC.Category_Name
FROM MC
JOIN (SELECT C1.Category_ID
FROM A
JOIN C1 ON A.Main_Key = C1.Main_Key
UNION ALL
SELECT C2.Category_ID
FROM A
JOIN C2 ON A.Main_Key = C2.Main_Key
) AS C
ON C.Category_ID = MC.Category_ID
GROUP BY C.Category_ID, MC.Category_Name
ORDER BY C.Category_ID, Stuff_Qnt;
-- Query by dkkumargoyal
SELECT COUNT(DISTINCT A.stuff_id) AS stuff_qnt, MC.category_id, MC.category_name
FROM A
LEFT JOIN C1 on a.main_key = c1.main_key -- USING(main_key)
LEFT JOIN C2 on a.main_key = c2.main_key -- USING(main_key)
LEFT JOIN MC ON (C1.category_id = MC.category_id OR C2.category_id = MC.category_id)
GROUP BY MC.category_id, mc.category_name
ORDER BY MC.Category_id, stuff_qnt; -- stuff_qnt added for standard compatibility
所做的更改对于代码在测试DBMS(Informix 11.70.FC6)上工作是必要的。
结果1:
4 1 blablbl
3 2 asas
2 3 asasa
结果2:
3 1 blablbl
2 2 asas
2 3 asasa
我认为我的结果是正确的,而另一个则没有,主要是因为当问题规定它不是唯一的时候(和{1}}唯一取决于A.Stuff_ID
是唯一的(并且额外的数据行使它不唯一)。
答案 1 :(得分:1)
请看一下这个参考:
查询:
select m.category_id, m.category_name, count(a.stuff_id) as cntstuff from
(select * from c1
union all
select * from c2) as c
join a
on a.main_key = c.main_key
join mc m
on m.category_id = c.category_id
group by m.category_id
order by m.category_id
;
结果:
CATEGORY_ID CATEGORY_NAME CNTSTUFF
1 blablbl 2
2 asas 2
3 asasa 1
答案 2 :(得分:0)
试试这个SQL。
SELECT COUNT(DISTINCT A.stuff_id) AS stuff_qnt, MC.category_id, MC.category_name
FROM A
LEFT JOIN C1 USING(main_key)
LEFT JOIN C2 USING(main_key)
LEFT JOIN MC ON (C1.category_id = MC.category_id OR C2.category_id = MC.category_id)
GROUP BY MC.category_id