This is coming from converting MSSQL to MySql. The following is code I'm trying to get to work:
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;
Assume any variables exist already. Where this is breaking is on the 'As SharedDataPerPath' part, so I'm guessing that I aliasing a select statement so that you can access it like a table isn't supported in MySQL? If table schema would help, reply with a comment and I will add that to the question.
Thanks in advance!
-- 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;
A FULL OUTER JOIN
can often be simulated with the UNION
of both LEFT JOIN
and RIGHT JOIN
. i.e. it is all on the left and those on the right, matching where possible on the join criteria. It is usually extremely rarely used, in my experience. I have a large system where it is only used once.
What you seem to be wanting to do here because FULL OUTER JOIN
is not available is to UNION
two sets and set some JOIN
criteria between the two subsets, which really isn't possible. The two sets that are UNION
ed in your example cannot have aliases, nor can they have a WHERE
clause which attempts to link them.
The method described above with the left and right outer joins unioned together works well and seems to be the commonly accepted solution. There are some details left out of this however as I have found when reading various examples across the message boards.
Swap your the table sources on the columns you use to join with from one select to the other to account for NULLs produced by the outer joins.
Add COALESCE functions to your "fixed columns" that might also come back as NULLs produced by the outer joins.
Example:
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`)