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;
你需要從C1和C2與加盟一個類別加盟 - 一個類別,你肯定不希望一個笛卡爾乘積,如你與LEFT OUTER JOIN得到,所以你拿將類別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
這裏是一個進一步的測試在兩個額外行,而在C1和C2對應的行。有兩個查詢測試,我的和querydkkumargoyal。
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
我認爲我的結果是正確的,其他沒有,主要是因爲可供選擇取決於當問題規定,它A.Stuff_ID
是唯一不是唯一的(並且額外的數據行使其不唯一)。
您如何看待'bonCodigo'的查詢?並感謝你的幫助,我只是在想哪一個更好,他的查詢速度有點快(我猜是因爲連接數少了)。只是有趣的你的想法。謝謝。 – user1016265
他的查詢與我的非常相似;他做了一個更簡單的(未加入)聯盟 - 它可以說比我的重複加入者更加整潔。一個非常好的優化器可能會等價地對待這兩個。這是一個很好的重組;如果我花了很長時間來研究它,我可能也會這樣做。這是DRY(不要重複自己)原理的簡單應用。他的回答指出了一種方法來簡化你的生活;放棄兩個類別表;只使用一個。 –