Mysql

無法通過 4 個表連接在 MySQL 中進行查詢以提供我想要的結果

  • June 13, 2018

我需要幫助來調整我的查詢以使結果顯示在底部。

這是我的數據庫插圖:

在此處輸入圖像描述

這是為每個表創建 TABLE 的命令:

CREATE TABLE `produits` (
 `sku` varchar(50) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
 `description` text CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `produits` (`sku`, `description`) VALUES
('1', 'Produit 1'),
('2', 'Produit 2'),
('3', 'Produit 3');


CREATE TABLE `produitssite` (
  `pssku` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
  `psloc` varchar(250) COLLATE utf8_unicode_ci NOT NULL,
  `psabcd` varchar(10) COLLATE utf8_unicode_ci NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

INSERT INTO `produitssite` (`pssku`, `psloc`, `psabcd`) VALUES
('1', 'A', 'd'),
('1', 'B', 'd'),
('2', 'A', 'c'),
('3', 'A', 'b'),
('4', 'C', 'd');


CREATE TABLE `stocksminmax` (
 `smmsku` varchar(250) CHARACTER SET latin1 NOT NULL,
 `smmloc` varchar(250) CHARACTER SET latin1 NOT NULL,
 `smmphy` float(20,2) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

INSERT INTO `stocksminmax` (`smmsku`, `smmloc`, `smmphy`) VALUES
('1', 'A', 10.00),
('1', 'B', 20.00),
('2', 'A', 20.00),
('3', 'B', 5.00),
('4', 'B', 10.00);


CREATE TABLE `ventes` (
 `ventesku` varchar(50) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
 `ventelocalisation` varchar(250) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
 `vente1805` double DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT INTO `ventes` (`ventesku`, `ventelocalisation`, `vente1805`) VALUES
('1', 'A', 500),
('1', 'B', 250),
('2', 'B', 600),
('3', 'A', 400),
('4', 'A', 100);

以下是我嘗試在 1 中獲得的三個請求:

SELECT * FROM produits RIGHT JOIN stocksminmax ON sku = smmsku

SELECT * FROM produits RIGHT JOIN produitssite ON sku = pssku

SELECT * FROM produits RIGHT JOIN ventes ON sku = ventesku

但我也嘗試在我的請求中加入每個表上的位置:smmloc、psloc 和 venteloc

這是我試圖獲得的: 在此處輸入圖像描述

謝謝你的幫助。

您真正想要做的是使用FULL JOIN;將帶有 SKU 和位置的三個表連接起來。這將連接指定列匹配的行,還包括兩個表中指定欄位匹配的行。

不幸的是,MySQL 5.6 沒有實現FULL JOIN. 標準的解決方法是執行以下操作:

SELECT *
 FROM table1 t1
        LEFT  JOIN table 2 t2 ON t1.id = t2.id
UNION ALL
SELECT *
 FROM table1 t1
        RIGHT JOIN table 2 t2 ON t1.id = t2.id
WHERE t1.id IS NULL
;

這將為您提供表的結果LEFT JOIN,然後在表的結果中進行聯合RIGHT JOIN,不包括結果中的行LEFT JOIN

排除處理 theLEFT JOIN和 theRIGHT JOIN都將返回 an 將返回的任何行的事實INNER JOIN。我們想要這些行 - 但我們不想將它們中的每一行包含兩次!

所以,我分三個步驟建構了這個查詢:

  • ventes首先,我建構了查詢以從和中返回行produitssite
  • 然後,我將該查詢用作子查詢(標識為s1,表示“步驟 1”),並將其結果連接到stocksminmax.
  • 最後,我將第二個查詢用作子查詢(標識為s2,表示“步驟 2”),並將LEFT JOIN這些結果編輯到produits. 對於這最後一步,由於您似乎不想在其他三個表中的至少一個表中列出不匹配的產品,因此我們不必同時執行 aLEFT JOIN和 a RIGHT JOIN

這是我得到的查詢:

SELECT `sku`,`description`
     ,`smmsku`,`smmloc`,`smmphy`
     ,`pssku`,`psloc`,`psabcd`
     ,`ventesku`,`ventelocalisation`,`vente1805`
 FROM (
       SELECT `theSku`
             ,`theLoc`
             ,`smmsku`,`smmloc`,`smmphy`
             ,`pssku`,`psloc`,`psabcd`
             ,`ventesku`,`ventelocalisation`,`vente1805`
         FROM (SELECT `pssku` as theSku
                     ,`psloc` as theLoc
                     ,`pssku`,`psloc`,`psabcd`
                     ,`ventesku`,`ventelocalisation`,`vente1805`
                 FROM produitssite ps
                        LEFT  JOIN ventes v ON ps.pssku = v.ventesku
                                           AND ps.psloc = v.ventelocalisation
               UNION ALL
               SELECT `ventesku` as theSku
                     ,`ventelocalisation` as theLoc
                     ,`pssku`,`psloc`,`psabcd`
                     ,`ventesku`,`ventelocalisation`,`vente1805`
                 FROM produitssite ps
                        RIGHT JOIN ventes v ON ps.pssku = v.ventesku
                                           AND ps.psloc = v.ventelocalisation
                WHERE ps.pssku IS NULL
              ) s1
                LEFT  JOIN stocksminmax smm ON s1.theSku = smm.smmsku
                                           AND s1.theLoc = smm.smmloc
       UNION ALL
       SELECT `smmsku` as theSku
             ,`smmloc` as theLoc
             ,`smmsku`,`smmloc`,`smmphy`
             ,`pssku`,`psloc`,`psabcd`
               ,`ventesku`,`ventelocalisation`,`vente1805`
         FROM (SELECT `pssku` as theSku
                     ,`psloc` as theLoc
                     ,`pssku`,`psloc`,`psabcd`
                     ,`ventesku`,`ventelocalisation`,`vente1805`
                 FROM produitssite ps
                        LEFT  JOIN ventes v ON ps.pssku = v.ventesku
                                           AND ps.psloc = v.ventelocalisation
               UNION ALL
               SELECT `ventesku` as theSku
                     ,`ventelocalisation` as theLoc
                     ,`pssku`,`psloc`,`psabcd`
                     ,`ventesku`,`ventelocalisation`,`vente1805`
                 FROM produitssite ps
                        RIGHT JOIN ventes v ON ps.pssku = v.ventesku
                                           AND ps.psloc = v.ventelocalisation
                WHERE ps.pssku IS NULL
              ) s1
                RIGHT JOIN stocksminmax smm ON s1.theSku = smm.smmsku
                                           AND s1.theLoc = smm.smmloc
        WHERE s1.theSku IS NULL
      ) s2
        LEFT  JOIN produits p ON s2.theSku = p.sku
;

我相信結果符合您的預期 - 您可以在這個db-fiddle中看到它們(以及查詢,工作) 。

引用自:https://dba.stackexchange.com/questions/209523