Question

Cela vient de se convertir à MSSQL MySql. Ce qui suit est le code que je suis en train de se rendre au travail:

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;

On suppose toutes les variables existent déjà. Lorsque cela se brise est sur « Comme SharedDataPerPath » partie, donc je suppose que j'aliasing une instruction select afin que vous puissiez y accéder comme une table ne sont pas pris en charge dans MySQL? Si le schéma de table aiderait, répondre à un commentaire et je vais l'ajouter à la question.

Merci d'avance!

Était-ce utile?

La solution

-- 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;

Autres conseils

Un FULL OUTER JOIN peut souvent être simulé avec le UNION des deux LEFT JOIN et RIGHT JOIN. à-dire qu'il est sur la gauche et ceux de droite, correspondant à la mesure du possible sur les critères de jointure. Il est généralement très rarement utilisé, dans mon expérience. J'ai un grand système où il est utilisé qu'une seule fois.

Ce que vous semblez vouloir le faire ici parce que FULL OUTER JOIN n'est pas disponible est de UNION deux ensembles et définir des critères de JOIN entre les deux sous-ensembles, ce qui est vraiment pas possible. Les deux ensembles qui sont UNIONed dans votre exemple ne peuvent pas avoir des alias, ils ne peuvent pas avoir une clause de WHERE qui tente de les relier.

La méthode décrite ci-dessus avec l'extérieur gauche et à droite se joint travaille ensemble bien et semble filles fusionnées être la solution communément acceptée. Il y a quelques détails à gauche de cette Cependant, comme je l'ai trouvé en lisant divers exemples dans les forums.

  1. Échangez vos sources de table sur les colonnes que vous utilisez pour se joindre à d'une sélection à l'autre pour tenir compte des valeurs NULL produites par jointures externes.

  2. Ajouter des fonctions à vos « COALESCE colonnes fixes » qui pourraient également revenir comme NULLs produits par jointures externes.

Exemple:

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`)
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top