2009-06-13 17 views
-1

這是從MSSQL轉換到MySql。以下是我試圖開始工作的代碼:幫我用這個MySql完全外連接(或聯合)

CREATE TEMPORARY TABLE PageIndex (
    IndexId int AUTO_INCREMENT NOT NULL PRIMARY KEY, 
    ItemId VARCHAR(64) 
); 

INSERT INTO PageIndex (ItemId) 
SELECT Paths.PathId 
    FROM Paths, 
     ((SELECT Paths.PathId 
      FROM AllUsers, Paths 
      WHERE Paths.ApplicationId = @ApplicationId 
      AND AllUsers.PathId = Paths.PathId 
      AND (@Path IS NULL 
       OR Paths.LoweredPath LIKE LOWER(@Path))) AS SharedDataPerPath 
      UNION -- This used to be a FULL OUTER JOIN but MySQL doesnt support that. 
     (SELECT DISTINCT Paths.PathId 
      FROM PerUser, Paths 
      WHERE Paths.ApplicationId = @ApplicationId 
      AND PerUser.PathId = Paths.PathId 
      AND (@Path IS NULL 
       OR Paths.LoweredPath LIKE LOWER(@Path))) AS UserDataPerPath 
      ON SharedDataPerPath.PathId = UserDataPerPath.PathId) 
      WHERE Paths.PathId = SharedDataPerPath.PathId OR Paths.PathId = UserDataPerPath.PathId 
      ORDER BY Paths.Path ASC; 

假設任何變量已存在。如果這是破壞是在'作爲SharedDataPerPath'的一部分,所以我猜我濫用選擇語句,以便您可以像MySQL中不支持表一樣訪問它?如果表格模式有幫助,請回複評論,我會將其添加到問題中。

在此先感謝!

+0

可以投給此功能來實現[MySQL的](http://bugs.mysql.com/bug.php?id=18003&thanks=3¬ify=67 ) – 2012-06-11 14:44:13

回答

1
-- Assuming these are defined in your store procedure 
DECLARE @ApplicationId VARCHAR(64); 
DECLARE @Path VARCHAR(256); 
SET @ApplicationId = NULL; 
Set @Path = NULL; 

CREATE TEMPORARY TABLE SharedDataPerPath 
(
    PathId VARCHAR(256) 
); 

CREATE TABLE UserDataPerPath 
(
    PathId VARCHAR(256) 
); 

-- Do this instead of aliasing a select statment 'AS SharedDataPerPath' 
INSERT INTO SharedDataPerPath 
SELECT Paths.PathId 
    FROM aspnet_PersonalizationAllUsers AllUsers, aspnet_Paths Paths 
WHERE Paths.ApplicationId = @ApplicationId 
    AND AllUsers.PathId = Paths.PathId 
    AND (@Path IS NULL OR Paths.LoweredPath LIKE LOWER(@Path)); 

-- Do this instead of aliasing a select statement 'AS UserDataPerPath' 
INSERT INTO UserDataPerPath 
SELECT DISTINCT Paths.PathId 
    FROM aspnet_PersonalizationPerUser PerUser, aspnet_Paths Paths 
WHERE Paths.ApplicationId = @ApplicationId 
    AND PerUser.PathId = Paths.PathId 
    AND (@Path IS NULL OR Paths.LoweredPath LIKE LOWER(@Path)); 

-- This is how I would do my 'FULL OUTER JOIN' 
SELECT Paths.PathId 
    FROM `wppi_net_db`.`aspnet_Paths` Paths, 
     (SELECT * 
      FROM SharedDataPerPath AS s 
      LEFT OUTER JOIN UserDataPerPath AS u 
       ON s.PathID = u.PathID 
      UNION -- OR UNION ALL see: http://www.xaprb.com/blog/2006/05/26/how-to-write-full-outer-join-in-mysql/ 
      SELECT * 
      FROM SharedDataPerPath AS s 
      RIGHT OUTER JOIN UserDataPerPath AS u 
       ON s.PathID = u.PathID) AS DataPerPaths 
    WHERE Paths.PathId = DataPerPaths.PathId 
    ORDER BY Paths.Path ASC; 

-- At some point you need to drop your temp tables 
DROP TEMPORARY TABLE SharedDataPerPath; 
DROP TEMPORARY TABLE UserDataPerPath; 
2

A FULL OUTER JOIN通常可以使用LEFT JOINRIGHT JOIN兩者的UNION進行模擬。即全部在左邊和右邊,在可能的情況下匹配加入標準。根據我的經驗,它通常極少使用。我有一個大系統,它只用了一次。

你似乎是想在這裏做,因爲FULL OUTER JOIN不適什麼是UNION兩套,並設置兩個子集,這真的是不可能的之間的一些JOIN標準。在您的示例中編輯的UNION這兩組不能有別名,也不能有WHERE子句試圖鏈接它們。

+0

好吧,那很好,如果它不適用於MySQL,但這是在MSSQL中有效,那麼我能做些什麼來得到這個工作?我應該分解它,並在一些臨時表中存儲一些東西嗎? – DJTripleThreat 2009-06-13 03:31:31

1

上面描述的將左右外連接結合在一起的方法運作良好,似乎是普遍接受的解決方案。不過,我留下了一些細節,因爲我在閱讀各種留言板上的各種示例時發現了這些細節。

  1. 將您用於連接的列的表源切換到另一個選擇以解釋由外部連接產生的空值。

  2. 將COALESCE函數添加到您的「固定列」中,這些列可能會返回爲由外部聯接產生的NULL。

實施例:

SELECT 
`Wins_VW`.`Year`, 
`Wins_VW`.`Period`, 
COALESCE(`Wins_VW`.`Wins`,0) as Wins, 
COALESCE(`Leads_VW`.`Leads`,0) as Leads 
FROM `Wins_VW` LEFT OUTER JOIN `Leads_VW` 
ON(`Wins_VW`.`Year` = `Leads_VW`.`Year` 
AND `Wins_VW`.`Period` = `Leads_VW`.`Period`) 

UNION 

SELECT 
`Leads_VW`.`Year`, 
`Leads_VW`.`Period`, 
COALESCE(`Wins_VW`.`Wins`,0) as Wins, 
COALESCE(`Leads_VW`.`Leads`,0) as Leads 
FROM `Wins_VW` RIGHT OUTER JOIN `Leads_VW` 
ON(`Wins_VW`.`Year` = `Leads_VW`.`Year` 
AND `Wins_VW`.`Period` = `Leads_VW`.`Period`)