[résolu]Requête SQL et croisement de tables

Je vous présente le contexte : je suis une quiche en SQL…une grosse. Donc même quand il s’agit de faire un truc tout simple j’y arrive pas.

La situation :
J’ai une table qui contient un listing de produits, j’utilise un champ “id” pour les différencier, ensuite j’ai d’autres tables qui contiennent les spécifications du produit en question, pour ça, je met en relation avec le champ id de “tproduits”, un autre champ “idproduit” qui aura la même valeur. Les specifications sont précisées avec des champs booléens (par exemple si le produit est une valve, j’aurais tproduit_type.valve = TRUE).

Le problème :
Bon maintenant, je veux faire une recherche : j’ai besoin d’avoir les produits de “tproduits” en fonction des paramètres contenus dans “tproduits_type” (les champs booléens)…donc j’ai fait cette requête avec mes jolies mimines (et un split et une boucle aussi) :

Mais évidemment ça marche pas…sinon je posterai pas.

Ma question :
Est ce quelqu’un pourrait m’expliquer pourquoi ? Et éventuellement le “comment ça marche” des requêtes imbriquées…

Merci d’avance

[quote name=‘Ismar’ date=’ 8 Aug 2005, 10:28’]Je vous présente le contexte : je suis une quiche en SQL…une grosse. Donc même quand il s’agit de faire un truc tout simple j’y arrive pas.

La situation :
J’ai une table qui contient un listing de produits, j’utilise un champ “id” pour les différencier, ensuite j’ai d’autres tables qui contiennent les spécifications du produit en question, pour ça, je met en relation avec le champ id de “tproduits”, un autre champ “idproduit” qui aura la même valeur. Les specifications sont précisées avec des champs booléens (par exemple si le produit est une valve, j’aurais tproduit_type.valve = TRUE).

Le problème :
Bon maintenant, je veux faire une recherche : j’ai besoin d’avoir les produits de “tproduits” en fonction des paramètres contenus dans “tproduits_type” (les champs booléens)…donc j’ai fait cette requête avec mes jolies mimines (et un split et une boucle aussi) :

Mais évidemment ça marche pas…sinon je posterai pas.

Ma question :
Est ce quelqu’un pourrait m’expliquer pourquoi ? Et éventuellement le “comment ça marche” des requêtes imbriquées…

Merci d’avance
[right][post=“384044”]<{POST_SNAPBACK}>[/post][/right][/quote]
SELECT tproduits.* FROM tproduits WHERE tproduits.id IN (SELECT tproduit_type.idproduit FROM tproduit_type WHERE valve=‘TRUE’)

ça marche pas mieux ?

sinon

Select tproduits.*
FROM tproduits,
tproduit_type
where tproduits.id = tproduit_type.idproduit And
tproduit_type.valve = True

Deja, tu dis meme pas quelle base tu utilises. On suppose MySQL donc.

Ensuite, les subqueries ne sont accessibles qu’a partir de la version 4.1 de MySQL. Mais franchement, pour ce que tu veux faire, les jointures (JOIN) c’est beaucoup mieux :

[sql]SELECT tproduits.* FROM tproduits LEFT JOIN tproduit_type ON tproduits.id = tproduit_type.idproduit WHERE valve=‘TRUE’[/sql]

Euh je suis pas trop d accord la les left join ca rame un max

je dirais meme plus ca rame un max sa race

</edit mode>

Bon alors en fait, c’est pas mysql, c’est une base Access (non non, j’ai toujours pas le choix…je bosse toujours en ASP) et aucune technique ne fonctionne… Bon du coup j’ai essayé avec une requête ultra simple “pour voir”, et j’ai encore une erreur…
Bon je vais chercher ailleurs.

Merci à tous en tout cas.

hahaha il a trouve pire que mysql :stuck_out_tongue: Bravo Ismar :stuck_out_tongue:

Sous acces via ODBC, ca, ca doit marcher:

Select * FROM tproduits, tproduit_type where tproduits.id = tproduit_type.idproduit And tproduit_type.valve = True
et ca aussi:

Select * FROM tproduits inner join tproduit_type ON tproduits.id = tproduit_type.idproduit where tproduit_type.valve = True

C’est pas toi qui a fait la base hein? Non parce que un champs pour chaque type de produit disponible, c’est juste DEGUEULASSE.

edit: Vu que le demandeur est Ismar, le « toi » se referait a Ismar hein, rince… Mais c’etait pas clair, je l’avoue :stuck_out_tongue:

LoneWolf
Le createur de cette base merite la torture :stuck_out_tongue:

[quote name=‹ LoneWolf › date=’ 8 Aug 2005, 12:05’]hahaha il a trouve pire que mysql  :stuck_out_tongue: Bravo Ismar  :stuck_out_tongue:

Sous acces via ODBC, ca, ca doit marcher:

Select * FROM tproduits, tproduit_type where tproduits.id = tproduit_type.idproduit And tproduit_type.valve = True
et ca aussi:

Select * FROM tproduits inner join tproduit_type ON tproduits.id = tproduit_type.idproduit where tproduit_type.valve = True

C’est pas toi qui a fait la base hein? Non parce que un champs pour chaque type de produit disponible, c’est juste DEGUEULASSE.

LoneWolf
Le createur de cette base merite la torture  :stuck_out_tongue:
[right][post=« 384076 »]<{POST_SNAPBACK}>[/post][/right][/quote]
je te rassure c’est pas moi

Ismar : t’as pas un msg d’erreur à nous donner ?

Bon alors, avant toute lapidation, je tiens à dire que maman, je t’aime…toi aussi petit frère…
c’est moi qui ait fait la table

Mais heu…c’était la nuit, j’avais mal aux dent, un rendez vous chez le dentiste et je vous ai parlé de mon expérience traumatisante avec un vieux monsieur tout nu ?

hum

Bon, beaucoup plus sérieusement : je sais, j’ai fait le goret (le gros qui pue et tout et tout)…mais maintenant il faut que je fasse avec.
Donc en fait, j’ai fait mes petits tests et il ne semble pas que ce soit une erreur SQL…j’ai l’impression qu’il ne trouve pas ma table, tout simplement…

Donc je vous remercie pour toutes vos suggestions, mais là je vais faire des enquêtes :P.

Une des regles de base dans le dev web, c’est de tester ses requetes dans le logiciel de BDD avant de mettre ca dans le code du site.

Donc ca serait pas mal que tu testes d’abord tes requetes dans access, je crois :stuck_out_tongue:

LoneWolf
hahaha Ismar, « c’est moi qui a fait la base », mort de rire :stuck_out_tongue:

[quote name=‹ peuh_ › date=’ 8 Aug 2005, 12:37’]Euh je suis pas trop d accord la les left join ca rame un max

je dirais meme plus ca rame un max sa race

</edit mode>
[right][post=« 384069 »]<{POST_SNAPBACK}>[/post][/right][/quote]

Oui oui, mais bien sur…

Select * from cgb_data_main where item_id = 10
Select * from cgb_data_main left join cgb_folders on dir_id = folder_id where item_id = 10

(et encore, j’ai mis des select *)

Edit : visiblement les balises [sql ] [/sql ] sont a eviter :stuck_out_tongue:

[quote name=‘Ismar’ date=’ 8 Aug 2005, 12:38’]j’ai fait mes petits tests et il ne semble pas que ce soit une erreur SQL…j’ai l’impression qu’il ne trouve pas ma table, tout simplement…

Donc je vous remercie pour toutes vos suggestions, mais là je vais faire des enquêtes :P.
[right][post=“384087”]<{POST_SNAPBACK}>[/post][/right][/quote]
euh… je connais pas bien access mais je sais qu’en Oracle quand j’ai ce genre de problème c’est parceque je n’ai pas préfixé le nom de la table par le nom du schéma dans le From

du genre

Select …
From Ma_table => fonctionne pas

Select …
From Mon_Schema.Ma_table => fonctionne

(je sais pas si Access gère différents schémas)

Voir au niveau des droits d’acces aussi peut être (table accessible en read pour le user avec lequel tu te connecte ?)


Sinon pour les Joins une différence de 0.0001 sec sur une requete qui retourne une seule row… c’est un peu juste pour prouver que le Join est plus efficace non ?

tant que j’y suis, pourquoi LEFT join ?

et pourquoi JOIN vu que tu dois quand même citer le 2 colonnes qui n’ont pas le même nom ?

enfin c’est pour discuter hein… m’fait ch** au taf alors…

[quote name=‘Ismar’ date=’ 8 Aug 2005, 10:28’]
Je vous présente le contexte : je suis une quiche en SQL…une grosse. Donc même quand il s’agit de faire un truc tout simple j’y arrive pas.

La situation :
J’ai une table qui contient un listing de produits, j’utilise un champ “id” pour les différencier, ensuite j’ai d’autres tables qui contiennent les spécifications du produit en question, pour ça, je met en relation avec le champ id de “tproduits”, un autre champ “idproduit” qui aura la même valeur. Les specifications sont précisées avec des champs booléens (par exemple si le produit est une valve, j’aurais tproduit_type.valve = TRUE).

Le problème :
Bon maintenant, je veux faire une recherche : j’ai besoin d’avoir les produits de “tproduits” en fonction des paramètres contenus dans “tproduits_type” (les champs booléens)…donc j’ai fait cette requête avec mes jolies mimines (et un split et une boucle aussi) :

Tu pourrais mettre le message d’erreur histoire que l’on comprenne un peu mieux ?

Sinon sous access, si tu mets le TRUE entre cote, c’est que tu considères la valeur comme étant une chaine de caractère, et non un booléen.

En fait les jointures externes rament lorsque la table externe contient beaucoup d’enregistrement puisqu’il fait une recherche sur toute la table externe.

Si tes deux tables sont vides unreal, c’est normal que ton test n’apporte pas de résultats flagrants.

C’est encore pire lorsque les champs de jointure ne sont pas des index, dans ce cas tu fais de beaux full scans…

Donc, je suis un vieux boulet poisseux, j’ai répertorié toutes les merdes que j’avais fait (oui parce qu’en fait c’était pas vraiment un problème de requête SQL), donc :

  • Include foireux donc forcément la BDD il avait du mal à la trouver(un “…/” de trop)
  • Intranet entier qui part en peau de zob et qui fait que je peux plus me connecter à mes BDD.
  • Boucle infini (celle là c’est la pire je crois) : les while, il vaut mieux foutre un incrément quelque part, sinon il aime pas.

Donc les constatations :

  • J’ai besoin de repos
  • J’ai pas besoin de Murphy
  • J’ai besoin de vancances
  • Cool c’est vendredi…dommage qu’on soit que lundi

Petite note : ma base est naze et mes requêtes pas optimisées certes, mais je tiens à préciser que je me fous un peu des perfs parce que c’est 1)pour un intranet 2)il n’y aura que 50 entrées dans la base à priori…donc bon c’est pas un drame non plus.

En tout cas, merci à tous pour l’aide que vous m’avez prodiguée (zyva comment ch’cause moa ?)

[quote name=‹ Ismar › date=’ 8 Aug 2005, 14:35’]Petite note : ma base est naze et mes requêtes pas optimisées certes, mais je tiens à préciser que je me fous un peu des perfs parce que c’est 1)pour un intranet 2)il n’y aura que 50 entrées dans la base à priori…donc bon c’est pas un drame non plus.
[right][post=« 384131 »]<{POST_SNAPBACK}>[/post][/right][/quote]
ça me fait penser à des phrases aussi célèbres que « 640 KB of RAM should be enough for everybody » :stuck_out_tongue:

bonne chance pour la suite en tout cas.

Y a pas photo qu’une jointure sera quasiement toujours beaucoup plus performante qu’une requete imbriquee sur des cas non triviaux… suffit de reflechir 2 secondes a ce qu’il doit faire.

On dit une ouiche

[quote name=‹ Flyoc › date=’ 8 Aug 2005, 19:40’]On dit une ouiche
[right][post=« 384201 »]<{POST_SNAPBACK}>[/post][/right][/quote]

:stuck_out_tongue: ouiche loraine ! Allez viens on va mangez des chips, c’est tout ce que ca te fait quand je te dis qu’on va mangez des chips ? :stuck_out_tongue:

je suis désolé mais les jointures ne sont pas bonnes à toutes les utilisations, tu veux du timing? :

SELECT tbl_order.idorder , order_row.reference , order_row.quantity , order_row.unit_price , tbl_order.DateHeure , tbl_order.idpayment , real_product.idreal_product , real_product.productmask
FROM real_product
LEFT JOIN order_row ON real_product.idreal_product = order_row.idrealproduct
LEFT JOIN tbl_order ON order_row.idorder = tbl_order.idorder
WHERE (
(
tbl_order.DateHeure LIKE ‘2005-08%’
)
AND (
tbl_order.idpayment = ‘1’
)
AND (
real_product.productmask = ‘2’
)
)
ORDER BY order_row.unit_price ASC

Cette bouse prend 11.1532 secondes pour me retourner 5 enregistrements.

Maintenant :

SELECT tbl_order.idorder , order_row.reference , order_row.quantity , order_row.unit_price , tbl_order.DateHeure , tbl_order.idpayment , real_product.idreal_product , real_product.productmask
FROM real_product, order_row, tbl_order
WHERE real_product.idreal_product = order_row.idrealproduct
AND order_row.idorder = tbl_order.idorder
AND (
(
tbl_order.DateHeure LIKE ‘2005-08%’
)
AND (
tbl_order.idpayment = ‘1’
)
AND (
real_product.productmask = ‘2’
)
)
ORDER BY order_row.unit_price ASC
LIMIT 0 , 30

cette requête me donne le meme résultat en 0.1251 sec.

Ce que je veux dire, c est que jointures ou pas, il n’y a pas qu’une seule école, il faut s’adapter.

Au fait t"habites à combien de kilomètres de Tours?

[quote name=‘peuh_’ date=’ 9 Aug 2005, 09:47’]bla bla bla
[right][post=“384362”]<{POST_SNAPBACK}>[/post][/right][/quote]

Personnellement j’appelle ta deuxième solution une jointure interne et ta première une jointure externe (même si le mot clé JOIN n’est pas utilisé dans ta deuxième).

Et comme je l’ai déjà dit, c’est NORMAL qu’une jointure externe rame par rapport à une jointure interne.