2017-08-29 48 views
4

我有4個表(精簡有關列簡潔):MySQL查詢跨4個表連接不同的標準

CREATE TABLE `papers` (
    `paper_id` int(11) NOT NULL DEFAULT '0', 
    PRIMARY KEY (`paper_id`) 
); 
INSERT INTO papers (paper_id) VALUES(1001); 
INSERT INTO papers (paper_id) VALUES(1002); 
INSERT INTO papers (paper_id) VALUES(1003); 
INSERT INTO papers (paper_id) VALUES(1004); 
INSERT INTO papers (paper_id) VALUES(1005); 
INSERT INTO papers (paper_id) VALUES(1006); 

CREATE TABLE `questions` (
    `question_id` int(11) NOT NULL AUTO_INCREMENT, 
    `type_id` int(11) NOT NULL, 
    PRIMARY KEY (`question_id`) 
); 
INSERT INTO questions (type_id) VALUES(1); 
INSERT INTO questions (type_id) VALUES(2); 
INSERT INTO questions (type_id) VALUES(1); 
INSERT INTO questions (type_id) VALUES(3); 

CREATE TABLE `question_depends` (
    `question_id` int(11) NOT NULL, 
    `depends_question_id` int(11) NOT NULL, 
    `depends_answer_val` int(11) NOT NULL, 
    PRIMARY KEY (`question_id`,`depends_question_id`) 
); 
INSERT INTO question_depends (question_id, depends_question_id, depends_answer_val) VALUES(3, 1, 0); 
INSERT INTO question_depends (question_id, depends_question_id, depends_answer_val) VALUES(2, 1, 1); 
INSERT INTO question_depends (question_id, depends_question_id, depends_answer_val) VALUES(3, 1, 1); 

CREATE TABLE `answers` (
    `paper_id` int(11) NOT NULL, 
    `question_id` int(11) NOT NULL, 
    `answer_val` int(2) NOT NULL, 
    PRIMARY KEY (`paper_id`,`question_id`) 
); 
INSERT INTO answers (paper_id, question_id, answer_val) VALUES(1002, 1, 1); 
INSERT INTO answers (paper_id, question_id, answer_val) VALUES(1002, 4, 0); 
INSERT INTO answers (paper_id, question_id, answer_val) VALUES(1004, 1, 0); 
INSERT INTO answers (paper_id, question_id, answer_val) VALUES(1004, 3, 1); 
INSERT INTO answers (paper_id, question_id, answer_val) VALUES(1005, 1, 1); 

我想拿出,顯示了所有可能的所有數據的單一查詢組合:

  1. 所有文件的ID應該是輸出至少一次
  2. 給定paper_id可能會或可能不會有答案,可能會或可能不會有依賴性
  3. 的ultim ate的目標是查看每個依賴關係問題是否得到解答,如果是這樣,如果答案val匹配每個紙張id的依賴關係答案val,並確定paper_id是否存在依賴關係問題以及是否有任何問題未得到答案(不論他們是否應答有依賴)
  4. 如果需要

我可以調整表/數據我差點:

select P.paper_id as P_PID, 
    A.paper_id as A_PID, 
    A.question_id as A_QID, 
    A.answer_val as A_VAL, 
    QD.question_id as QD_QID, 
    QD.depends_question_id AS QD_DQID, 
    QD.depends_answer_val AS QD_VAL, 
    Q.type_id AS Q_TYPE 
from papers P 
left join answers A on A.paper_id = P.paper_id 
left join question_depends QD on QD.depends_question_id = A.question_id 
left join questions Q on Q.question_id = QD.question_id 
UNION 
select NULL AS P_PID, 
    NULL AS A_PID, 
    A.question_id as A_QID, 
    A.answer_val as A_VAL, 
    QD.question_id as QD_QID, 
    QD.depends_question_id AS QD_DQID, 
    QD.depends_answer_val AS QD_VAL, 
    Q.type_id AS Q_TYPE 
from question_depends QD 
left join answers A on QD.depends_question_id = A.question_id 
left join questions Q on Q.question_id = QD.question_id 
    where A.question_id IS NULL 

...但輸出有答案的數據爲每個每一行paper_id不僅僅是那個paper_id。任何想法讚賞!使用這個小樣本數據集上述選擇輸出:

P_PID A_PID A_QID A_VAL QD_QID QD_DQID QD_VAL Q_TYPE 
1001        
1002 1002 1  1  2  1  1  2 
1002 1002 1  1  3  1  0  1 
1002 1002 4  0  NULL NULL NULL NULL 
1003 NULL NULL NULL NULL NULL NULL NULL 
1004 1004 1  0  2  1  1  2 
1004 1004 1  0  3  1  0  1 
1004 1004 3  1  NULL NULL NULL NULL 
1005 1005 1  1  2  1  1  2 
1005 1005 1  1  3  1  0  1 
1006 NULL NULL NULL NULL NULL NULL NULL 

理想的輸出(如果我沒有錯字任何東西)將是:

P_PID A_PID A_QID A_VAL QD_QID QD_DQID QD_VAL Q_TYPE 
1001 NULL NULL NULL 2  1  1  2 
1001 NULL NULL NULL 3  1  0  1 
1002 1002 1  1  2  1  1  2 
1002 NULL NULL NULL 3  1  0  1 
1002 1002 4  0  NULL NULL NULL 3 
1003 NULL NULL NULL 2  1  1  2 
1003 NULL NULL NULL 3  1  0  1 
1004 1004 1  0  2  1  1  2 
1004 NULL NULL NULL 3  1  0  1 
1004 1004 3  1  NULL NULL NULL 1 
1005 1005 1  1  2  1  1  2 
1005 NULL NULL NULL 3  1  0  1 
1006 NULL NULL NULL 2  1  1  2 
1006 NULL NULL NULL 3  1  0  1 
+0

你能告訴我們您預期的結果? –

+3

我希望有一天我不會覺得只需要提出一個問題,因爲它包含樣本數據的相關表格DDL + DML。直到那一天,這裏有5個免費聲望點。不要把它們都放在一個地方...... :-) –

+0

你能解釋一下1001,1003和1006的預期行嗎?他們沒有答案......「沒有答案」同樣是錯誤的答案?那麼,爲什麼它們在這些「3 1 0」中,而不是「3 1 1」(他們對問題1的回答可能是1或0),或者總是「回答0」沒有答案?但是,那麼爲什麼「2 1 1」在那裏(「沒有回答」到「1」應該得到相關性「x 1 0」,對吧?)。另外:你不應該試圖爲「第二」依賴獲得「空」。如果你想隱藏這些,隱藏(=不打印)在客戶端。該值是已知的,所以不要使其爲空。另外,最後的左連接應該是A.question_id,而不是QD.question_id。 – Solarflare

回答

0

「分而治之」。將問題分爲三種情況。

SELECT /*Answers and no depends*/ p.paper_id AS p_pid, 
    a.paper_id AS a_pid, 
    a.question_id AS a_qid, 
    a.answer_val AS a_val, 
    qd.question_id AS qd_qid, 
    qd.depends_question_id AS qd_dqid, 
    qd.depends_answer_val AS qd_val, 
    q.type_id AS q_type 
FROM papers p 
JOIN answers a 
    ON a.paper_id = p.paper_id 
LEFT OUTER JOIN question_depends qd 
    ON a.question_id = qd.depends_question_id 
     AND 
     a.answer_val = qd.depends_answer_val 
LEFT OUTER JOIN questions q 
    ON q.question_id = a.question_id 
WHERE qd.question_id IS NULL 
UNION 
SELECT /*Answers and depends*/ p.paper_id AS p_pid, 
    a.paper_id AS a_pid, 
    a.question_id AS a_qid, 
    a.answer_val AS a_val, 
    qd.question_id AS qd_qid, 
    qd.depends_question_id AS qd_dqid, 
    qd.depends_answer_val AS qd_val, 
    q.type_id AS q_type 
FROM papers p 
JOIN answers a 
    ON a.paper_id = p.paper_id 
LEFT OUTER JOIN question_depends qd 
    ON a.question_id = qd.depends_question_id 
     AND 
     a.answer_val = qd.depends_answer_val 
LEFT OUTER JOIN questions q 
    ON q.question_id = qd.question_id 
WHERE qd.question_id IS NOT NULL 
UNION 
SELECT /*Missing answer*/ p.paper_id AS p_pid, 
    a.paper_id AS a_pid, 
    a.question_id AS a_qid, 
    a.answer_val AS a_val, 
    qd.question_id AS qd_qid, 
    qd.depends_question_id AS qd_dqid, 
    qd.depends_answer_val AS qd_val, 
    q.type_id AS q_type 
FROM papers p 
CROSS JOIN question_depends qd 
JOIN questions q 
    ON q.question_id = qd.question_id 
LEFT OUTER JOIN answers a 
    ON a.paper_id = p.paper_id 
     AND 
     a.question_id = qd.depends_question_id 
     AND 
     a.answer_val = qd.depends_answer_val 
WHERE a.question_id IS NULL 
ORDER BY 1, 7 DESC; 

您可以檢查結果上SQL小提琴http://sqlfiddle.com/#!9/fbd3a9/3