8
votes

Rencontre de gauche sur des critères supplémentaires dans l'accès MS

J'ai la requête T-SQL suivante (un cas de test simple) fonctionnant bien dans MS SQL mais ne peut pas obtenir la requête équivalente dans l'accès MS (JET-SQL). Le problème est les critères supplémentaires dans la jointure gauche. Comment puis-je faire cela dans l'accès MS? strong>

T-SQL: P>

SELECT * FROM dbo_A 
LEFT JOIN dbo_B ON (dbo_A.ID = dbo_B.A_ID AND dbo_B.F_ID = 3)


3 commentaires

Ne devrait pas avoir besoin des crochets sur les critères de jointure


Est-ce qu'il importe que l'exemple T-SQL est une jointure extérieure? Tout ce que c'est essentiellement en train de retourner toutes les lignes en A.


@OMG Ponies - sans la parenthèse, je reçois une erreur de syntaxe, avec eux, accédez aux crashs ... @MELVIN - Non, le mot extérieur est facultatif.


4 Réponses :


-4
votes

Cette dernière condition techniquement n'est pas une jointure mais une comparaison avec une valeur littérale. Mettez-le dans une clause WHERE:

SELECT *
FROM a LEFT OUTER JOIN b ON a.ID = b.a_id
WHERE b.f_id = 3;


2 commentaires

Ce n'est pas vrai. Vérification F_ID = 3 Dans la condition de jointure de gauche vous donnerait NULL pour toutes les valeurs de B lorsque f_id = 3. Le mettre dans la clause de l'endroit où la clause ne les retournerait pas du tout.


Désolé, ce que je voulais dire, c'est que vous obtenez NULL lorsque f_ID <> 3 pour une jointure à gauche.



1
votes

Obtenez-vous un message d'erreur lorsqu'il se bloque ou est-ce que cela vous bloque? Juger par le nom de DBO_B Je vais deviner que ce sont des tableaux liés dans l'accès. Je crois que lorsque vous faites une jointure comme cet accès ne dit pas SQL Server qu'il a besoin du résultat de la jointure, il est écrit: "Donnez-moi toutes les lignes des deux tables", puis il essaie de les rejoindre lui-même. Si les tables sont très importantes, cela peut entraîner la mise en place de l'application.

Vous ferez probablement mieux de créer une vue sur SQL Server pour ce dont vous avez besoin.


4 commentaires

Certainement une bonne idée, cela signifie-t-il que ma syntaxe est correcte, l'accès ne peut pas le gérer?


Je ne sais pas si l'accès lui-même a une limite technique, mais si les tables sont des millions de lignes, le PC sur lequel l'accès est exécuté ainsi que le réseau sur lequel les données doivent être couplées sont probablement submergées.


Ce n'est pas vrai du tout que Jet / Ace demande la table complète et qui se joint elle-même, à moins que quelque chose empêche Jet / Ace d'obtenir les métadonnées qu'il a besoin de déterminer si elle peut transmettre le tout au serveur (qui devrait être le cas 99% du temps). Ou, il pourrait s'agir de quelque chose à propos des tables liées (qui pourraient être des vues, par exemple) qui empêche le jet / Ace de faire le travail. Ce sont les deux cas que je peux penser que cela pourrait causer le jet / Ace pour demander les tables complètes avec le SQL fourni. En bref, c'est très très peu probable que cela se produise.


Créer une vue est une bonne idée, mais je n'ai pas d'autorisations pour créer des vues.



13
votes

Vous devez utiliser un sous-sélection pour appliquer la condition:

  SELECT *
  FROM dbo_A LEFT JOIN 
    (SELECT dbo_B.* FROM dbo_B WHERE dbo_B.F_ID = 3) AS dbo_B 
      ON dbo_A.ID = dbo_B.A_ID;


3 commentaires

Oui, je sais que je peux utiliser un sous-sélection, mais c'est nettement plus lent, donc je préférerais utiliser une jointure gauche. Je ne savais pas à propos de l'option de requête passthrough, qui fonctionnait parfaitement! (Plus d'infos sur les autres ici: support.microsoft.com/kb/303968 ). Je marquais votre réponse comme acceptée depuis cela. Merci!


Si le sous-sol est plus lent dépend de deux choses: 1) La manière dont le moteur de base de données impliquait optimise le sous-sélection contre l'alternative et l'évidence dans ce cas, 2) si l'option est même disponible. Dans JET / ACE SQL, ce n'est pas parce que vous ne pouvez pas avoir une jointure multi-champs définie dans la direction opposée (c'est-à-dire un de A => B et l'autre de B => A). Il se peut que SQL Server optimise le sous-optimisme sous-optimally par rapport à l'alternative, mais si vous utilisez Jet / Ace, vous devez suivre les règles de Jet / Ace, d'où la mention de passthroughs.


Je suis à peu près sûr qu'une jointure gauche est toujours plus rapide qu'un sous-sélection. Bien sûr, dans un petit ensemble de données ou si votre moteur DB peut optimiser (AKA transformer votre sous-sélection dans une jointure à gauche), vous ne verrez pas une différence, mais "une jointure gauche puis une sélection de n lignes" va être plus rapide que " n + 1 sélectionne ". Certainement, dans mon cas, SQL Server a couru la joindre à gauche plus rapidement.



0
votes

Je pense que l'accès MS s'attend à ce que les deux tables s'appelle dans chaque section des jointures sur la clause. Comme une affaire, cela fonctionne pour moi: xxx

a.id ou tout autre champ autre de la table A


0 commentaires