Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1551 connectés 

  FORUM HardWare.fr
  Programmation
  SQL/NoSQL

  Requête SQL (Access) : données sans liens entre elles

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Requête SQL (Access) : données sans liens entre elles

n°1645508
hervai
Posté le 19-11-2007 à 22:07:09  profilanswer
 

Bonjour, je cherche à faire une requête permettant d'afficher 2 types de données sans lien entre elles, et sans doublons. Ma BDD est celle d'une bibliothèque, et la requête doit afficher d'une part tous les auteurs du 19eme siecle, et d'autre part tous les éditeurs du 20eme siecle. Je sais qu'il faut passer par un UNION ; voici les 2 tables sur lesquelles on travaille pour cette requete :
http://pix.nofrag.com/b/4/f/d9f9cf7c5cea8c4589efffa6bff2e.jpg
la date d'edition est un numérique correspondant à l'année, et la date de naissance de l'auteur en format date (les conditions de sélection ne sont pas un problème, le seul problème est l'affichage des 2 résultats en 2 colonnes, et sans doublons).
D'avance merci.


Message édité par hervai le 22-11-2007 à 17:52:23
mood
Publicité
Posté le 19-11-2007 à 22:07:09  profilanswer
 

n°1645563
olivthill
Posté le 20-11-2007 à 07:41:10  profilanswer
 

Pour ne pas avoir de doublon, on utilise habituellement le mot clef "distinct".
 
Requête pour avoir la liste des éditeurs du 20e siècle

select distinct Nom_editeur
  from Editeur
 where Date_edition >= '19000101' and Date_edition < '20000101'

(A adpater en fonction de la base de données pour le formatage de la date, là j'ai pris le formatage Sybase)
 
Requête pour avoir la liste des auteurs du 19e siècle

select distinct Nom_auteur
  from Auteur
 where (Date_naissance_auteur >= "18000101" and Date_naissance_auteur < "1900101" )
    or (Date_deces_auteur >= "18000101" and Date_deces_auteur < "1900101" )

(A adpater en fonction de la base de données pour le formatage de la date, là j'ai pris le formatage Sybase)
 
Si l'on veut mettre bout à bout ces deux listes, on mettra le mot clef "union" entre les deux requêtes. il faudra aussi que les noms des colonnes soient les mêmes pour les deux requêtes. Pour cela, on utilisera des alias.
 
Mais le problème est différent. Il semble qu'il ne s'agisse pas de mettre les résultats bout à bout, mais côte à côte. Dans ce cas, il ne faut pas utiliser "union". On mettra nos deux requêtes en sous-requête d'une requête principale :

select
 (select distinct Nom_editeur
  from Editeur
 where Date_edition >= '19000101' and Date_edition < '20000101'),
(select distinct Nom_auteur
  from Auteur
 where (Date_naissance_auteur >= "18000101" and Date_naissance_auteur < "1900101" )
    or (Date_deces_auteur >= "18000101" and Date_deces_auteur < "1900101" )

Sous Oracle, il faudra peut-être ajouter "from dual" parce qu'Oracle aime bien qu'un nom de table soit spécifié.

n°1645630
casimimir
Posté le 20-11-2007 à 10:06:21  profilanswer
 

non la ca ne va pas marcher, pour mettre un sous-select a cet endroit il faut qu'il ne retourne qu'une seule valeur.
 
je suis pas vraiment sur de saisir ce que tu veux, tu pourrais faire donner un exemple concret avec des données?

n°1645724
olivthill
Posté le 20-11-2007 à 12:19:16  profilanswer
 

Bonne remarque, mais, justement, ici, chaque sous-select ne retourne qu'une seule colonne, donc cela devrait marcher (en tous cas sous Oracle (mais je ne peux pas tester, je suis bloqué chez moi à cause des grrrr...)).

n°1645798
casimimir
Posté le 20-11-2007 à 14:05:12  profilanswer
 

il ne faut jamais penser en terme de colonne mais en terme de ligne en sgbd :)

n°1645992
hervai
Posté le 20-11-2007 à 17:23:51  profilanswer
 

Voilà ce que ca m'affiche en faisant la requete d'olivthill :  
http://pix.nofrag.com/5/0/1/6232a151ed8093b607843791d9877.jpg

n°1645994
MagicBuzz
Posté le 20-11-2007 à 17:33:30  profilanswer
 

Code :
  1. SELECT 'Auteur' type, nom_auteur nom
  2. FROM auteur
  3. WHERE date_naissance_auteur BETWEEN '01/01/1800' AND '31/12/1899'
  4. OR date_deces_auteur BETWEEN '01/01/1900' AND '31/12/1999'
  5. union
  6. SELECT 'Editeur' type, nom_editeur nom
  7. FROM edite
  8. WHERE date_edition BETWEEN '01/01/1900' AND '31/12/1999'


 
PS : Pas besoin de DISTINCT étant donné que le UNION fait déjà un DISCTINCT (pour ne pas faire le distinct automatique, utiliser UNION ALL)


Message édité par MagicBuzz le 20-11-2007 à 17:34:17
n°1645995
MagicBuzz
Posté le 20-11-2007 à 17:35:18  profilanswer
 

PS : Pour les auteurs, si un auteur est né à la fin du 18° et mort au début du 20°, la requête ne marche pas. Mais bon ça doit pas courir les rues... C'est à toi de voir si tu prends ou non en compte ce cas.
 
Ensuite, pour décider si un auteur est contemporain d'une époque, je ne sais pas si des critères sur sa date de naissance et de décès sont suffisants... Généralement on prendra plutôt les dates de parutions de ses bouquins non ?

Message cité 1 fois
Message édité par MagicBuzz le 20-11-2007 à 17:36:03
n°1646012
hervai
Posté le 20-11-2007 à 17:59:57  profilanswer
 

SELECT 'Auteur' type
 
Je ne comprend pas bien les ' ' et le "type" , en tout cas écrit tel quel ca ne marche pas.

n°1646024
omega2
Posté le 20-11-2007 à 18:26:58  profilanswer
 

MagicBuzz a écrit :

Ensuite, pour décider si un auteur est contemporain d'une époque, je ne sais pas si des critères sur sa date de naissance et de décès sont suffisants... Généralement on prendra plutôt les dates de parutions de ses bouquins non ?

Personellement, je considère qu'un auteur est contemporain à l'époque où il a vécu et non pas aux périodes correspondants aux dates de première parution de ses écrits. Il existe trop de cas où des textes n'ont été publié que plusieurs années après la mort d'un auteur pour pouvoir se baser là dessus.
 
Pour prendre un auteur très célèbre : Victor Hugo. Certains de ses écrits n'ont été retrouvé que plusieurs décennies après sa mort. La seule publication qui est considéré comme comprenant l'intégralité de ses écrits date d'ailleurs de 2001 et elle contenait quelques inédits (certes pas dans la catégorie "romans" ) . Ca n'en fait pas pour autant un contemporain de Bernard Werber.
 

hervai a écrit :

SELECT 'Auteur' type
 
Je ne comprend pas bien les ' ' et le "type" , en tout cas écrit tel quel ca ne marche pas.


Ca, ça veut dire : retourne moi la valeur 'Auteur' dans la colonne de nom 'type' pour chaque ligne du résultat. C'est un raccourcis qui permet d'avoir une colonne dont la valeur est fixe.

Message cité 1 fois
Message édité par omega2 le 20-11-2007 à 18:28:38
mood
Publicité
Posté le 20-11-2007 à 18:26:58  profilanswer
 

n°1646077
MagicBuzz
Posté le 20-11-2007 à 19:30:25  profilanswer
 

omega2 a écrit :

Personellement, je considère qu'un auteur est contemporain à l'époque où il a vécu et non pas aux périodes correspondants aux dates de première parution de ses écrits. Il existe trop de cas où des textes n'ont été publié que plusieurs années après la mort d'un auteur pour pouvoir se baser là dessus.


Ouais, enfin... Je voulais dire "date à laquel il a écrit". Le mot "publié" effectivement n'était pas approprié ;)
D'un autre côté, prendre en compte un auteur né en 1898 dans les auteurs du 19° je sais pas si c'est très malin non plus ;) M'enfin j'imagine qu'il y a une règle établie qui permet de décider ou non si une personne est contemporaine d'une époque ou non, et ce, que ce soit en rapport ou non avec son activité :)
 

omega2 a écrit :


Ca, ça veut dire : retourne moi la valeur 'Auteur' dans la colonne de nom 'type' pour chaque ligne du résultat. C'est un raccourcis qui permet d'avoir une colonne dont la valeur est fixe.


Effectivement. Ici, ça te permet de différencier les noms qui correspondent à un auteur et les lignes qui correspondent à un éditeur, parceque je trouve ça un peu étrange de vouloir les mélanger.
Si t'as besoin de retrouver qu'une liste de noms, tous "type" confondu, et sans doublons, alors vire simplement cette clause.


Message édité par MagicBuzz le 20-11-2007 à 19:32:24
n°1646109
hervai
Posté le 20-11-2007 à 20:40:29  profilanswer
 

Dans tous les cas ça ne compile pas sous access :(

n°1646158
MagicBuzz
Posté le 20-11-2007 à 22:46:13  profilanswer
 

et ça dit quoi comme erreur ? comment ça ça compile pas ? essaie de faire :
 

Code :
  1. SELECT 'Auteur' AS [type], nom_auteur AS nom
  2. FROM auteur
  3. WHERE date_naissance_auteur BETWEEN '01/01/1800' AND '31/12/1899'OR date_deces_auteur BETWEEN '01/01/1900' AND '31/12/1999'
  4. union
  5. SELECT 'Editeur' AS [type], nom_editeur AS nom
  6. FROM edite
  7. WHERE date_edition BETWEEN '01/01/1900' AND '31/12/1999'

n°1646269
omega2
Posté le 21-11-2007 à 09:55:53  profilanswer
 

hervai > Note pour plus tard : Toujours préciser quand on bosse avec access comme base de donnée, il a des règles d'écriture des requêtes qui différent des autres. ;)

n°1647398
hervai
Posté le 22-11-2007 à 16:35:12  profilanswer
 

MagicBuzz a écrit :

et ça dit quoi comme erreur ? comment ça ça compile pas ? essaie de faire :
 

Code :
  1. SELECT 'Auteur' AS [type], nom_auteur AS nom
  2. FROM auteur
  3. WHERE date_naissance_auteur BETWEEN '01/01/1800' AND '31/12/1899'OR date_deces_auteur BETWEEN '01/01/1900' AND '31/12/1999'
  4. union
  5. SELECT 'Editeur' AS [type], nom_editeur AS nom
  6. FROM edite
  7. WHERE date_edition BETWEEN '01/01/1900' AND '31/12/1999'



 
Lorsque je compile j'ai cette erreur :
Type de données incompatibles dans l'expression du critère.
 
Sinon, quelqu'un saurait me dire comment faire la somme de SUM(x) et SUM(y) (donc la somme de 2 sommes)?
Aussi, je dois faire une requête qui m'affiche tous les livres appartenant à la fois à la catégorie SF et Aventure, et qui sont loués. Voici mon diagramme de relations et mes données :
http://pix.nofrag.com/3/c/e/1134cc926f9e5e7031ec271ffef20.jpg
http://pix.nofrag.com/4/2/5/9677837f454e6e8ab374f6e996055.jpg


Message édité par hervai le 22-11-2007 à 16:40:25
n°1647429
MagicBuzz
Posté le 22-11-2007 à 16:55:57  profilanswer
 

date est de quel type ?
 
je vois dans ta table "livre" que c'est l'année uniquement, sous forme numérique, et non pas une date. c'est pareil pour tout le reste ?
 
si oui ben... corrige de toi-même... moi je suis parti du principe qu'un champ nommé date était de type date et contenait une date, mais visiblement c'était un peu trop logique comme raisonnement :o

n°1647434
hervai
Posté le 22-11-2007 à 16:59:38  profilanswer
 

Non en fait quasiment toutes les dates sont de type date, exceptés la date d'édition et la date de redaction.

n°1647442
MagicBuzz
Posté le 22-11-2007 à 17:03:48  profilanswer
 

bah je vois pas pkoi la requête que j'ai écrit marche pas.

n°1647452
hervai
Posté le 22-11-2007 à 17:12:20  profilanswer
 

Ta requête marche, elle renvoie ca :  
http://pix.nofrag.com/0/8/7/8dc88d768556b50a802613067eaa9.jpg
 
Moi je voudrais qu'elle renvoie un truc comme ça sans les doublons :
http://pix.nofrag.com/d/e/2/254268aea57dd40e42c067f712174.jpg
donc dans la colonne de gauche les 6 auteurs en 6 lignes, et dans la colonne de droite les 8 editeurs en 8 lignes (c'est possible au moins ce que je demande ?)

n°1647497
MagicBuzz
Posté le 22-11-2007 à 17:52:32  profilanswer
 

impossible, point à la ligne.
 
et je t'invite à regarder ma signature, histoire de comprendre pourquoi c'est impossible, et pourquoi c'est pas dérangeant.


Message édité par MagicBuzz le 22-11-2007 à 17:53:13
n°1647504
hervai
Posté le 22-11-2007 à 17:56:02  profilanswer
 

Ok, je vais utiliser ta requête. Sinon, tu saurais répondre à mes 2 autres questions (somme de 2 sommes, et afficher les livres qui sont à la fois en SF et en Aventure) ?

n°1647586
MagicBuzz
Posté le 22-11-2007 à 19:22:51  profilanswer
 

somme de deux sommes ? qu'entends-tu par là ? c'est pas plutôt l'adition de deux sommes plutôt ?
 

Code :
  1. SELECT champ1, sum(champ2) + sum(champ3) AS total
  2. FROM latable
  3. GROUP BY champ1


 
Sinon, détail ta demande.
 
Pour la seconde question, c'est plus chaud.
 
Le plus simple :
 
Sélectionne les livres en faisant une jointure sur les propriétés (table "possede" si je ne m'abuse)
 
Dans ton where, filtre les lignes de possède où nom_categorie = 'Aventure' or nom_categorie = 'SF'
 
Dans la clause de ton select, ajoute un count(*)
Fait un group by par le nom du livre
 
Et rajoute une clause having count(*) = 2
 
En fait, tu récupères toutes les propriétés des lignes qui sont soit aventure soit sf.
Puis tu comptes ces catégories trouvés (donc par livre, 1 ou 2).
Et tu ne gardes que les lignes où ce compte est égale à 2, c'est à dire que le bouquin a bien les deux catégories (en partant du principe que tu n'as pas de doublons dans la table "possede" )

n°1647589
casimimir
Posté le 22-11-2007 à 19:24:47  profilanswer
 

ceci dit c'est pas completement impossible, il me semblait bien qu'il voulait faire ca depuis le début, en access je sais pas, mais en oracle si je devais absolument le faire (jvois pas trop pourquoi mais bon),  
 
je m'arrangerai pour avoir les valeurs distinctes associées a un numero incrementé (un rank) et je les croiserai en full outer join
 
mais globalement y a pas de sens a la ligne ca je trouve plus emmerdant

Message cité 1 fois
Message édité par casimimir le 22-11-2007 à 19:27:02
n°1647598
MagicBuzz
Posté le 22-11-2007 à 19:36:28  profilanswer
 

casimimir a écrit :

ceci dit c'est pas completement impossible, il me semblait bien qu'il voulait faire ca depuis le début, en access je sais pas, mais en oracle si je devais absolument le faire (jvois pas trop pourquoi mais bon),  
 
je m'arrangerai pour avoir les valeurs distinctes associées a un numero incrementé (un rank) et je les croiserai en full outer join
 
mais globalement y a pas de sens a la ligne ca je trouve plus emmerdant


quand j'ai dit "impossible" effectivement, c'est juste pour signifier que de base, c'est pas jouable sans partir dans un mic mac aussi bancal que possible.
 
mais surtout (mon renvoi vers ma signature va dans ce sens) un SGBD n'a pas pour vocation de mettre en forme les informations, mais de les gérer et savoir les retrouver.
la requête que j'ai proposé est donc amplement suffisante dans la mesure où elle retrouve bien les données, et on sait distinquer les éditeurs des auteurs. ensuite, si on veut les afficher d'une certaine manière, c'est au programme consommateur de la requête de faire les traîtements nécessaires sur le résultat.


Message édité par MagicBuzz le 22-11-2007 à 19:36:50
n°1647603
hervai
Posté le 22-11-2007 à 19:43:31  profilanswer
 

MagicBuzz a écrit :

somme de deux sommes ? qu'entends-tu par là ? c'est pas plutôt l'adition de deux sommes plutôt ?
 

Code :
  1. SELECT champ1, sum(champ2) + sum(champ3) AS total
  2. FROM latable
  3. GROUP BY champ1


 
Sinon, détail ta demande.
 
Pour la seconde question, c'est plus chaud.
 
Le plus simple :
 
Sélectionne les livres en faisant une jointure sur les propriétés (table "possede" si je ne m'abuse)
 
Dans ton where, filtre les lignes de possède où nom_categorie = 'Aventure' or nom_categorie = 'SF'
 
Dans la clause de ton select, ajoute un count(*)
Fait un group by par le nom du livre
 
Et rajoute une clause having count(*) = 2
 
En fait, tu récupères toutes les propriétés des lignes qui sont soit aventure soit sf.
Puis tu comptes ces catégories trouvés (donc par livre, 1 ou 2).
Et tu ne gardes que les lignes où ce compte est égale à 2, c'est à dire que le bouquin a bien les deux catégories (en partant du principe que tu n'as pas de doublons dans la table "possede" )


 
A vrai dire je comprend pas très bien comment faire ce que tu décris, je suis vraiment novice en SQL, je connais le SELECT, COUNT, SUM ..., ça va pas beaucoup plus loin :s

n°1647615
MagicBuzz
Posté le 22-11-2007 à 20:01:48  profilanswer
 

Bah lis doucement, c'est pourtant tout détaillé dans mon post ;)
 
Vu qu'on ne résoud pas les éxercices, et que ta demande me fait de plus en plus penser à un exercice, désolé, mais je ne détaillerai pas plus :p

n°1647634
hervai
Posté le 22-11-2007 à 20:48:46  profilanswer
 

A vrai dire c'est le "having count(*) = 2" avec lequel j'ai du mal : je ne vois pas trop comment tu l'utilises ; pour le reste je pense pouvoir me débrouiller, même si à mon avis il y a une méthode plus facile (je ne vois pas laquelle mais j'en suis sûr).

n°1647681
MagicBuzz
Posté le 22-11-2007 à 22:36:16  profilanswer
 

je doute que tu trouves plus simple. tu peux jouer à coup de sous-requêtes, mais niveau algo, c'est plus complexe, niveau syntaxe aussi, niveau performances, c'est loin derrière, et niveau support par les différents sgbd c'est ças génial. donc non. c'est la solution la plus simple.
 
pour le having, fait une recherche sur le net. le moindre exemple sera extrêment proche de ton exercice, tu peux en etre sur.

n°1647685
hervai
Posté le 22-11-2007 à 22:52:25  profilanswer
 

Dès que je met le count(*), ca me met un msg d'erreur :  
Vous avez essayé d'exécuter une requête ne comprenant pas l'expression spécifiée 'Ref_livre' comme une partie de la fonction d'agrégat.
 
 
Voici comment j'ai écrit la requête :

Code :
  1. SELECT Livre.Ref_livre,Livre.Titre_livre,count(*)
  2. FROM Livre, Categorie, Location, Possede
  3. WHERE Livre.Ref_livre=Possede.Ref_livre AND Possede.Nom_categorie=Categorie.Nom_categorie AND Livre.Ref_livre=Location.Ref_livre AND (Possede.Nom_categorie='Science-fiction' or Possede.Nom_categorie='Aventure') AND Location.Date_retour IS NULL
  4. GROUP BY Livre.Titre_livre
  5. HAVING count(*)=2;

n°1647731
MagicBuzz
Posté le 23-11-2007 à 08:12:51  profilanswer
 

normal, tu ne respectes pas la syntaxe du group by.
il doit avoir l'ensemble des champs que tu sélectionnes mais qui ne font pas parti d'une fonction d'agrégation. là t'as mis le titre du livre, mais pas sa référence.

mood
Publicité
Posté le   profilanswer
 


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  SQL/NoSQL

  Requête SQL (Access) : données sans liens entre elles

 

Sujets relatifs
Ksh/Pl Sql VS ETLSQL oracle erreur nombre invalide
[SQL] Question bidon pour les débutants[résolu] select avec données uniques
j'ai un projet sur accessAffichage Requête 2 tables
Oracle SQL - Requête faussecarnet d'adresse et gestion de la base SQL
IOException sur SQL LOADER 
Plus de sujets relatifs à : Requête SQL (Access) : données sans liens entre elles


Copyright © 1997-2025 Groupe LDLC (Signaler un contenu illicite / Données personnelles)