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

  FORUM HardWare.fr
  Programmation
  SQL/NoSQL

  utiliser CONCAT/DISTINCT ?

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

utiliser CONCAT/DISTINCT ?

n°2170579
Thornac
Posté le 10-01-2013 à 13:34:22  profilanswer
 

Bonjours a tous !
 
Alors je vous explique la situation, j'ai une base de donnée de ce type
 
Matricule  |  Nom  | Prenom  | Commentaire                Ligne
---------------------------------------
0111 | Nom1  | Prenom1  | commentaire1                    1
0111 | Nom1  | Prenom1  |                                        2
0111 | Nom1  | Prenom1  | com                                 3
0111 | Nom2  | Prenom2  | commentaire2                    4
0222 | Nom2  | Prenom3  | commentaire2                    5
0333 | Nom3  | Prenom3  | commentaire3                    6
 
et je  voudrais d'afficher uniquement les lignes 1,4,5,6.( les lignes ne sont pas dans la base de donnée bien entendu)
 
Je pensais alors a concatener le nom et prenom et apres faire un distinct dessus est ce possible ?
 
SELECT DISTINCT( Concat(Nom,Prenom)), Matricule, Commentaire FROM Matable;
 
Thornac

mood
Publicité
Posté le 10-01-2013 à 13:34:22  profilanswer
 

n°2170612
x1fr
Posté le 10-01-2013 à 16:39:42  profilanswer
 

Le distinct n'est pas une fonction et il s'applique sur l'ensemble des colonnes sélectionnées, donc dans ton cas, du moment que tu affiches le commentaire, il te retournera les lignes 2 et 3.
 
Là comme ça je ne vois pas trop de solution, mais la structure de table est un peu bizarre. Ne vaudrait-il pas mieux sortir le champ commentaire dans une table séparée, liée à la première par le numéro de matricule? Comme ça dans ta première table tu n'a pas de doublon, et ça paraîtrait plus naturel.


---------------
Origin / PSN / Steam / Uplay : x1fr - bnet : Fab#2717
n°2170658
CyberDenix
Posté le 10-01-2013 à 22:35:58  profilanswer
 

GROUP BY nom,prenom
 
ou
 
GROUP BY CONCAT (nom,prenom)
 
Je te donne les deux, car selon le cas, l'une est plus rapide que l'autre et vice versa.


---------------
Directeur Technique (CTO)
n°2170668
x1fr
Posté le 10-01-2013 à 23:08:13  profilanswer
 

Tu ne pourras pas faire de select sur un champ qui n'est pas dnas le group by (autre que sum, count, etc...)


---------------
Origin / PSN / Steam / Uplay : x1fr - bnet : Fab#2717
n°2170685
Thornac
Posté le 11-01-2013 à 09:55:40  profilanswer
 

Je vous remercie de vos réponse, j'ai essayé de mettre un group by nom,prenom ca n'affiche plus aucun doublons certes mais j'ai plus aucune autre information que les noms et les prénoms !

n°2170686
x1fr
Posté le 11-01-2013 à 10:15:46  profilanswer
 

Normal (cf mon poste au dessus)
 
Et si tu rajoutes le champ commentaires dans le select, tu sera obligé de l'ajouter aussi dans le group by, et du coup ça ne réglera pas le problème de doublons
 
edit : en même temps, comment tu veux gérer l'affichage des commentaires? si un ensemble nom/prénom a 3 commentaires, tu ne veux afficher que le premier? une concaténation des 3?


Message édité par x1fr le 11-01-2013 à 10:17:36

---------------
Origin / PSN / Steam / Uplay : x1fr - bnet : Fab#2717
n°2170688
Farian
Posté le 11-01-2013 à 10:23:25  profilanswer
 

A priori, le commentaire le plus long ...
 
Utiliser les clause HAVING et MAX, prévues pour fonctionner avec le GROUP BY ?
 
N'ayant plus la syntaxe exacte en tête, je me contente de vous souffler l'idée :)


Message édité par Farian le 11-01-2013 à 10:26:06
n°2170697
Thornac
Posté le 11-01-2013 à 11:39:49  profilanswer
 

Il est nécessaire que j'affiche que le commentaire correspondant a la première fois ou le nom et prénom apparaisse dans la table. si la ligne trois serais lu en premier dans la base de donnée alors il faudrait qu'il n'affiche uniquement "com". Mais je ne suis même pas sure que ce soit possible uniquement en SQL >.>
 
Je ne sais pas qui a conçu cette base de donnée mais je l'étriperais bien ahah ^^

n°2170707
deliriumtr​emens
sic transit intestinal...
Posté le 11-01-2013 à 12:39:49  profilanswer
 

La seule manière de récupérer des données distinctes serait un
 

Code :
  1. SELECT
  2.    MIN(matricule),
  3.    Nom,
  4.    Prenom,
  5.    MIN(commentaire)
  6. FROM <taTable>
  7. GROUP BY
  8.   Nom,
  9.   Prenom


 
Maintenant, le MIN(commentaire) ne te donnera évidemment pas la première ligne dans la base, c'est un choix d'une fonction d'aggrégation qui est arbitraire, tu pourrais en prendre une autre, mais le problème de l'arbitraire resterait.
Le MIN(matricule) est aussi arbitraire, mais si on a toujours le même matricule pour un couple "Nom/prénom", pas de problème.
La notion de "première ligne dans la base" ne fait d'ailleurs pas de sens.
Si tu n'as pas d'autre colonne dans ta table (id autoincrémenté, datetime), tu ne peux rien faire...


Message édité par deliriumtremens le 11-01-2013 à 12:41:49
n°2170711
Thornac
Posté le 11-01-2013 à 13:21:39  profilanswer
 

Donc comme l'as dit x1fr le group by ne peut pas être utiliser si je veux afficher les autres donnée que le nom et prenom, ensuite je ne suis pas sure de comprendre ce que tu veux faire avec min ?  
 
Quand tu parle d'une colonne date time c'est a dire une colonne qui référence l'heure pour de l'insertion de ces champs ? Si oui, je vais vérifier c'est bien possible car la table est juste immense !

mood
Publicité
Posté le 11-01-2013 à 13:21:39  profilanswer
 

n°2170716
deliriumtr​emens
sic transit intestinal...
Posté le 11-01-2013 à 13:44:03  profilanswer
 

En fait, pour faire une requête correcte avec un group by, tous les champs qui ne sont pas dans une fonction d'aggrégation (MIN, MAX, SUM, COUNT, etc.) doivent être présents dans le GROUP BY.
 
Donc, pour avoir des résultats groupés par nom et prénom, il faut que tous les autres champs soient dans des fonctions d'aggrégation (bon pour le matricule,en fait, on pourrait aussi l'utiliser dans le GROUP BY).
 
C'est pour ça que j'utilise un MIN sur commentaire.
 
Maintenant, s'il y a une clé primaire autoincrémentée, ou un champ de type timestamp ou datetime (qui, comme tu le dits, référence la date et l'heure lors de l'insertion), il y aurait moyen de faire plus propre.

n°2170719
Thornac
Posté le 11-01-2013 à 14:04:08  profilanswer
 

D'accord merci de tes explication, Mais ils se trouve que je doit aussi afficher des dates et plein d'autre type que des chaines cela fonctionnerais t-il ? (Je t'avoue ne jamais avoir fait attention a ces fonctions min et max dans les docs étant donné que je n'ais jamais été amené à les utiliser.  
 
Je viens à l'instant de constater qu'il y à bien un timestamp. Je pense comprendre de qu'elle moyens tu parle mais je ne vois pas trop comment différencier les doublons, par l’horaire qui serais plus récent mais comment les comparer uniquement entre eux ?  
 
Encore merci de vos réponse et de votre rapidité à me répondre !

n°2170740
deliriumtr​emens
sic transit intestinal...
Posté le 11-01-2013 à 15:09:08  profilanswer
 

Les fonctions d'aggrégations marchent sur à peu près tous les types de champs, oui.
 
Sinon, admettons que tu as un champ timestamp (ou un type date quelconque, le plus précis étant le mieux) nommé insertDate (original, non ?)
 
Alors, ta requête deviendrait (jointure sur une requête sur la même table avec une recherche de la plus petite "date d'insertion" )
 

Code :
  1. SELECT t.nom, t.prenom, t.matricule, t.commentaire from maTable t
  2. INNER JOIN
  3.      (SELECT t1.nom, t1.prenom, min(t1.insertDate) as minTime
  4.       FROM maTable t1
  5.       GROUP BY t1.nom, t1.prenom) as minQuery
  6.   ON t.nom = minQuery.nom AND t.prenom = minQuery.prenom AND t.insertDate = minQuery.minTime


 
Tu peux regarder le résultat ici, j'ai rajouté des "dates d'insertion" à la noeud.
 
L'avantage, c'est que tu n'as plus rien d'arbitraire, et que tu n'as plus à te soucier de fonctions d'aggrégations dans la requête principale.
 
Le seul risque, c'est d'avoir 2 lignes dans ta table avec les mêmes noms et prénoms et la même "insertDate". Mais le risque me paraît faible (?)
Pour vérifier ce point :
 

Code :
  1. SELECT nom, prenom
  2. FROM maTable
  3. GROUP BY nom, prenom, insertDate
  4. HAVING COUNT(*) > 1


 
Si la requête ne renvoie rien, c'est gagné !


Message édité par deliriumtremens le 11-01-2013 à 15:13:18
n°2170766
Thornac
Posté le 11-01-2013 à 16:55:19  profilanswer
 

Parfaitement ce que je voulais ! Encore merci ! Pas encore exactement tout compris à l'opération (compris ce qu'elle fait mais pas comment elle le fait ) mais je compte bien étudiez cela plus en détail !

n°2171124
Thornac
Posté le 14-01-2013 à 16:18:18  profilanswer
 

Me revoilà !  
 
J'étais entrain d'étudier le code que tu ma montrer et je me posais une question  
 
Si, je travail sur  même table, je vais avoir besoin de cette jointure dès que je veux enlever des doublons même si je ne cherches pas a avoir leurs nom mais plutot leurs dates d'embauche ou de sortie de l'entreprise?  
 
Thornac


Message édité par Thornac le 14-01-2013 à 16:31:24
n°2171266
deliriumtr​emens
sic transit intestinal...
Posté le 15-01-2013 à 10:32:32  profilanswer
 

Lapin compris (ou en tout cas pas sûr). A priori je dirais oui.
 
Tu as des dates d'embauche ou de sortie dans la même table, et tu voudrais savoir si cette requête est utilisable pour ça ?
 
Mais as-tu un champ "DateEmbauche" et un champ "DateSortie", répétés à chaque entrée ?
Structure étrange...
 
Essaie de préciser un peu le besoin (et puis c'est difficile de répondre sans connaître la structure complète de la table)

n°2171271
Thornac
Posté le 15-01-2013 à 11:39:15  profilanswer
 

Désoler, disons qu'il ont regrouper dans une même tables a peut prêt tout a ce qu'on dirais, donc sur la table énoncer au début j'ai date embauche et date sortie qui sont dans la même table.
 
 Il se trouve que je doit compter le nombre de sortie ainsi le nombre
d'embauche par mois et par année mais comme j'ai des doublons il est nécessaire que je les enlève de la même façon non ?
 
 Saurais tu notamment si je peut découper avec substr() des dates afin de les regrouper par moi et année ? Je n'ai pas accès aux fonction Year(), Month(), et Day() sur le logiciel qui m'est imposer d'utiliser par mon entreprise ...
 
edit :
 
J'ai rajouté http://sqlfiddle.com/#!2/f5598/1 ce qu'il manquait c'est a dire les dates embauche et sortie avec les requêtes qui me permette de trouver combien d'employer ont quitter ou ont été embaucher par mois. Sauf que bien évidement il faut que ce soit en une requête et qu'il ne prenne pas des dates des doublons en compte ... Donc faut il que j'insère dans ma requête nom et prénom ... Logiquement oui il me semble et bien avec les noms et préno car il peut y avoir deux sortie ou deux embauche le même jours.


Message édité par Thornac le 15-01-2013 à 14:51:15
n°2171363
deliriumtr​emens
sic transit intestinal...
Posté le 15-01-2013 à 17:29:24  profilanswer
 

Il y a effectivement des fonctions sur les chaînes de caractères dans différents SGBD (Système de gestion de base de données), maintenant ils sont différents de l'un à l'autre.
 
Si tu n'as pas les fonctions Year, Month et Day, tu pourrais me dire quelle SGBD vous utilisez ? Ca aura un impact sur les fonctions utilisées...
Ensuite, tu es sûr que les dates d'embauche et de sortie sont bien des colonnes de type "Date", parce qu'il est possible qu'ils aient été stockés dans un format type Varchar, voire entier, ça se voit plus souvent qu'on pense, même si c'est une bien mauvaise idée. (bref, si tu as le nom précis du type de ces colonnes, ça aidera sûrement).
 
 
EDITH:
Ce qui est bizarre dans ton exemple, c'est qu'il y a des dates d'entrée et de sortie différentes pour le même couple Nom/Prénom. C'est voulu ? Ca correspond à la réalité ?


Message édité par deliriumtremens le 15-01-2013 à 17:33:50
n°2171441
Thornac
Posté le 16-01-2013 à 10:44:49  profilanswer
 

Donc pour te répondre c'est une base de donnée HyperFileSQL de ce que j'en ais compris. Il semblerait que les fonctions utilisable soit celle ci : http://doc.pcsoft.fr/fr-fr/?203400 [...] equete-sql .
J'avoue ne pas pouvoir confirmer si c'est un format date ou une chaine de caractère. Je n'ai encore jamais utiliser ce genre de base de donné lors de ma formation.
 
Donc pour ce qui est des dates. J'ai écrit des dates plus ou moins au hasard sur le site SQLfiddle. Mais dans mon cas je peut avoir des employer qui comporte forcement un date d'embauche mais pas forcement une date de sortie. Et cette dernière serais forcement après la date d'embauche bien évidement.
 

Code :
  1. SELECT
  2. COUNT(SUBSTR(t1.IT_DATEMB,3,4)) AS nbEmbauche
  3. FROM
  4. maTable t1
  5. WHERE
  6. SUBSTR(t1.IT_DATEMB,1,4) = '2012'
  7. GROUP BY SUBSTR(t1.IT_DATEMB,3,4);


Voilà le fruit de mes recherches. Avec ce code j’obtiens le compte du nombre d'embauche, pour l'année 2012 le tout triée par mois. ( Si, il y au moins une embauche par mois, ce qui est apparemment le cas de mon entreprise). Je peut notamment récupérer de la même façon les sorties. Mais je n'arrive pas a unir les deux car lorsque quand je join les deux j'obtiens un problème liée à la condition qui devient.
 

Code :
  1. WHERE
  2. SUBSTR(t1.IT_DATEMB,1,4) = '2012' OR SUBSTR(t1.IT_DATSOR,1,4) = '2012'


 
Il se trouve que avec cette condition me récupère toutes les dates que j'ai besoin. Mais le problème est que j'obtiens par les count(), un résultat équivalent pour les deux count(). Je suppose donc que il ne compte pas séparément les dates embauches et sorties. Ce qui m'a amené à tester une nouvelle requête avec des INNER JOIN mais sans résultat probant.

n°2171454
deliriumtr​emens
sic transit intestinal...
Posté le 16-01-2013 à 11:30:40  profilanswer
 

Pas mal de manières de résoudre, une des solutions serait de faire une sous-requête avec une UNION.
 
 

Code :
  1. SELECT SUM(nbEmbauches), SUM(nbSorties), month
  2. FROM
  3. (SELECT
  4.     SUBSTR(t1.IT_DATEMB, 3, 4) as month,
  5.     COUNT(*) AS nbEmbauches,
  6.     0 AS nbSorties
  7.   FROM maTable t1
  8.   WHERE SUBSTR(t1.IT_DATEMB,1,4) = '2012'
  9.   GROUP BY SUBSTR(t1.IT_DATEMB,3,4)
  10.   UNION
  11.   SELECT
  12.     SUBSTR(t1.IT_DATSOR, 3, 4) as month,
  13.     0 AS nbEmbauches,
  14.     COUNT(*) AS nbSorties
  15.   FROM maTable t1
  16.   WHERE SUBSTR(t1.IT_DATESOR,1,4) = '2012'
  17.   GROUP BY SUBSTR(t1.IT_DATESOR,3,4)
  18.   )
  19. GROUP BY month;


Message édité par deliriumtremens le 16-01-2013 à 11:31:04
n°2171681
Thornac
Posté le 17-01-2013 à 18:18:12  profilanswer
 

Bon bah rien à dire ça me donne exactement ce qu'il me fallait ... le pire c'est que j'avais essayer l'union aussi avant ta solution mais j'avais des erreurs à cause des 0 AS Sortie et 0 AS Embauche. que je n'avais pas mis donc j'avais quand même des erreurs ... Donc bah j'ai adapté ton code avec l’enlèvement de doublons et certains trucs en plus qu'il mettais demander et cela marche parfaitement.
 
 En tout cas je te remercie grandement de ton aide. J'ai appris beaucoup !

mood
Publicité
Posté le   profilanswer
 


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

  utiliser CONCAT/DISTINCT ?

 

Sujets relatifs
[JAVA+ HTML5] quelle API utiliser pour la génération de code HTML5 ?jointure complète/externe : comment l'utiliser ?
Menu déroulant sans utiliser Flash moyen javascript pour ne pas utiliser de marquee ?
comment utiliser TexCoordGeneration avec un objet(.obj) chargéquel outil utiliser pour l'interface de mon jeu (Ogre3D)
Impossible d'utiliser CpanC++ Builder 6 - Utiliser une liste déroulante
[SQL] Une requette avec DISTINCT et COUNTComment installer et utiliser Abbot sous Java ?
Plus de sujets relatifs à : utiliser CONCAT/DISTINCT ?


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR