Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

[mysql] Faire sans subquery

5 réponses
Avatar
Daniel Déchelotte
Bonjour,

Je cherche auprès de vous un coup de pouce en MySQL ; si ce n'est pas
le meilleur forum, merci de me l'indiquer.

Alors voilà, j'ai d'une part une grosse table, mos_users, avec un champ
id, un champ name, et plein d'autres. D'autre part, j'ai une petite
table, dd_moderators, qui ne contient que la colonne user_id.

> describe mos_users
Field |Type |Null|Key |Default |Extra |
id |int(11) | |PRI |NULL |auto_increment|
name |varchar(50) | |MUL | | |
username |varchar(25) | | | | |
etc

> describe dd_moderators
Field |Type |Null|Key |Default|Extra|
user_id|int(11)| |PRI |0 | |

J'aimerais les noms et ID des modérateurs et de ceux qui ne le sont pas :

# Les moderateurs
SELECT name, id
FROM mos_users
WHERE id IN (SELECT * FROM dd_moderators)

# Les autres
SELECT name, id
FROM mos_users
WHERE id NOT IN (SELECT * FROM dd_moderators)

Problème, ça ne marche pas :
error: <You have an error in your SQL syntax near 'SELECT * FROM dd_moderators)

Mais en fait, c'est le concept même de subquery qui pose problème :
> select 1
fonctionne
mais
> select (select 1)
produit aussi : error: <You have an error in your SQL syntax near 'select 1)'

Pour info, le serveur est online.net, apparemment avec MySQL 4.1, mais
en fait je ne sais pas vérifier cette info.

Voyez-vous comment obtenir les résultats qui m'intéressent ? Est-il
possible de ne faire qu'une requête (name, id et un booléen) ?

Merci,
--
Daniel Déchelotte
http://yo.dan.free.fr/

5 réponses

Avatar
Jogo
Sur fr.comp.applications.sgbd, Daniel Déchelotte disait :

# Les moderateurs
SELECT name, id
FROM mos_users
WHERE id IN (SELECT * FROM dd_moderators)

# Les autres
SELECT name, id
FROM mos_users
WHERE id NOT IN (SELECT * FROM dd_moderators)

Problème, ça ne marche pas :
error: <You have an error in your SQL syntax near 'SELECT * FROM
dd_moderators)



Je n'utilise pas MySQL, mais je pense que vous feriez bien de
remplacer * par la colonne qie vous intéresse.

D'autre part, les tables n'ayant qu'un seul champ sont rares. Elles
servent normalement à lister les valeurs possibles pour d'autres champs
d'autres tables. Ce n'est le cas dans votre exemple. Pourquoi ne pas
avoir ajouté un champ "moderator" de type booléen à la table mos_users ?

Mais en fait, c'est le concept même de subquery qui pose problème :
> select 1
fonctionne
mais
> select (select 1)
produit aussi : error: <You have an error in your SQL syntax near
'select 1)'



Une subquery renvoie l'équivalent d'un table. Essayez donc :

SELECT * FROM (SELECT 1) s

--
Pour posséder vraiment un bien, il faut l'avoir perdu et retrouvé.
- Simone de Beauvoir - La force des choses -
Avatar
Ph. B.
Daniel Déchelotte a demandé:
Bonjour,

Je cherche auprès de vous un coup de pouce en MySQL ; si ce n'est pas
le meilleur forum, merci de me l'indiquer.

Alors voilà, j'ai d'une part une grosse table, mos_users, avec un champ
id, un champ name, et plein d'autres. D'autre part, j'ai une petite
table, dd_moderators, qui ne contient que la colonne user_id.

describe mos_users


Field |Type |Null|Key |Default |Extra |
id |int(11) | |PRI |NULL |auto_increment|
name |varchar(50) | |MUL | | |
username |varchar(25) | | | | |
etc

describe dd_moderators


Field |Type |Null|Key |Default|Extra|
user_id|int(11)| |PRI |0 | |

J'aimerais les noms et ID des modérateurs et de ceux qui ne le sont pas :

# Les moderateurs
SELECT name, id
FROM mos_users
WHERE id IN (SELECT * FROM dd_moderators)

# Les autres
SELECT name, id
FROM mos_users
WHERE id NOT IN (SELECT * FROM dd_moderators)

Problème, ça ne marche pas :
error: <You have an error in your SQL syntax near 'SELECT * FROM dd_moderators)

Mais en fait, c'est le concept même de subquery qui pose problème :
select 1


fonctionne
mais
select (select 1)


produit aussi : error: <You have an error in your SQL syntax near 'select 1)'

Pour info, le serveur est online.net, apparemment avec MySQL 4.1, mais
en fait je ne sais pas vérifier cette info.

Voyez-vous comment obtenir les résultats qui m'intéressent ? Est-il
possible de ne faire qu'une requête (name, id et un booléen) ?

Merci,



Bonjour,

Comme l'ont signalé l'interpréteur SQL et "Jogo", ta requête est mal
écrite. Il faut écrire :

# Les moderateurs
SELECT name, id
FROM mos_users
WHERE id IN (SELECT user_id FROM dd_moderators)

# Les autres
SELECT name, id
FROM mos_users
WHERE id NOT IN (SELECT user_id FROM dd_moderators)

La requête imbriquée ne doit renvoyer qu'une colonne compatible avec
celle de la clause WHERE la précédant.

--
Philippe.
Avatar
fgirault
On 26 fév, 23:05, Daniel Déchelotte
internet.invalid> wrote:

Voyez-vous comment obtenir les résultats qui m'intéressent ? Est-il
possible de ne faire qu'une requête (name, id et un booléen) ?




Avec une jointure :

SELECT
mos_users.name,
mos_users.id,
dd_moderators.user_id IS NOT NULL
FROM mos_users
LEFT JOIN dd_moderators ON dd_moderators.user_id = mos_users.id

--
FG
Avatar
P'tit Marcel
Daniel Déchelotte a écrit :
> describe mos_users


Field |Type |Null|Key |Default |Extra
id |int(11) | |PRI |NULL
name |varchar(50) | |MUL | |
username |varchar(25) | | | |
> describe dd_moderators



user_id|int(11)| |PRI |0 | |


Déjà je pense que ta base n'est pas optimisée/normalisée :

Puisque la relation mos_users vers dd_moderators a une cardinalité
(0,1), et que dd_moderators n'a pas d'attributs, je te conseille de
supprimer dd_moderators et d'ajouter un *attribut* booléen moderators à
la table mos_users.


J'aimerais les noms et ID des modérateurs et de ceux qui ne le sont pas :
# Les moderateurs
SELECT name, id FROM mos_users WHERE id IN (SELECT * FROM dd_moderators)



une sous-requête ne doit être utilisées qu'à défaut d'autre solution car
elle peut empêcher un sgbd d'optimiser l'exécution. ici une jointure
marcherait au moins aussi bien et sans doute mieux :

SELECT name, id FROM mos_users INNER JOIN dd_moderators ON id = user_id

ou avec la structure de base que je te suggère :
SELECT name, id FROM mos_users WHERE moderators


# Les autres
SELECT name, id FROM mos_users WHERE id NOT IN (SELECT * FROM dd_moderators)



même remarque donc :

SELECT name, id FROM mos_users LEFT JOIN dd_moderators ON id = user_id
WHERE user_id IS NULL

ou avec la structure de base que je te suggère :
SELECT name, id FROM mos_users WHERE NOT moderators


eça
--
P'tit Marcel
stats sur les forums modérés http://www.centrale-lyon.org/ng/
Avatar
Daniel Déchelotte
a écrit :

Daniel Déchelotte wrote:

> Est-il possible de ne faire qu'une requête (name, id et un booléen) ?

Avec une jointure :

SELECT
mos_users.name,
mos_users.id,
dd_moderators.user_id IS NOT NULL
FROM mos_users
LEFT JOIN dd_moderators ON dd_moderators.user_id = mos_users.id



Merci ! Comme j'ai toujours besoin des deux infos (qui est modérateur
et qui ne l'est pas), je pense utiliser cette requête plutôt que deux.

Merci aussi aux autres contributeurs. La BD a vraiment l'air de ne pas
supporter les sous-requêtes. Même
SELECT * FROM (SELECT 1)
me donne
You have an error in your SQL syntax near 'SELECT 1)'

Quant à ajouter un champ à mos_users, je reconnais que ce serait le
plus intuitif et performant (surtout vue mon utilisation), mais c'est
une table gérée par le CMS. Je préfère ne pas prendre de risques et
confiner mes manips à mes propres tables.

Merci à vous.
--
Daniel Déchelotte
http://yo.dan.free.fr/