Copy link to clipboard
Copied
Bonjour,
Je voudrais faire un query d'un autre query.
Exemple :
J'ai 2 tables : une des pays et une des villes de ces pays
France : Paris Marseille Lyon
Allemagne : Berlin Cologne
Italie : Rome Milan
Je voudrais pouvoir choisir dans un 1er query les pays, dans le 2ème les villes du pays choisi.
Exemple bienvenu
Merci pour votre aide.
Copy link to clipboard
Copied
Bonjour, ZNB,
What you describe is an inefficient way of doing what you are asking for. Putting a query loop within a query loop is resource intensive. I will attempt to show you the method that you ask, and then I will follow that with what I believe would be a better way of aggregating the data you seek.
<cfquery name='country' datasource='#application.dsn#'>
SELECT country
FROM countries
ORDER BY country ASC
</cfquery>
<cfoutput query='country'>
#country.country#<br />
<cfquery name='city' datasource='#application.dsn#'>
SELECT city
FROM cities
WHERE country = <cfqueryparam value="#country.country#' />
</cfquery>
<cfoutput query='city'>
- #city.city#<br />
</cfoutput>
</cfoutput>
Now for what I consider a much better approach.
<cfquery name='country_city' datasource='#application.dsn#'>
SELECT a.country, b.city
FROM country a LEFT OUTER JOIN city b ON b.country = a.country
ORDER BY a.country ASC, b.city ASC
</cfquery>
<cfoutput query='country_city' group='country'>
#country_city.country#<br />
<cfoutput>
- #country_city.city#<br />
</cfoutput>
</cfoutput>
This takes a single query, aggregates the data as you want it, and displays it quickly and efficiently, without looped database connection/disconnections, etc.
HTH,
^_^
Copy link to clipboard
Copied
Merci pour votre réponse !
Mais je me rends compte que j'ai compliqué le script en faisant 2 tables.
Est-il possible de faire qu'une table avec une colonne Pays et une colonne ville et faire la même chose ?
Merci par avance
Cordialement
Copy link to clipboard
Copied
You can put all the data into one table, yes. But the best practice is to put countries and cities into separate tables. It's a way of normalizing the data to reduce size. If you have one table that has countries and cities, then the country names are being repeatedly used, over and over, taking up space that would be saved by using two tables - one table for country, one table for city with a reference ID to the country table.
Vous pouvez mettre toutes les données dans une table, oui. Mais la meilleure pratique est de mettre les pays et les villes dans des tableaux distincts. C'est un moyen de normaliser les données pour réduire la taille. Si vous avez une table qui a des pays et des villes, puis les noms de pays sont utilisés à plusieurs reprises, encore et encore, en prenant l'espace qui serait sauvé en utilisant deux tables - une table pour le pays, une table pour la ville avec un ID de référence La table de pays.
V/r,
^_^
Copy link to clipboard
Copied
I just realized that I did not completely explain my suggested more efficient method. Assume we have two tables, as such:
TABLE COUNTRY
cid country
1 France
2 Germany
3 Italy
TABLE CITY
city cid
Paris 1
Munchen 2
Nantes 1
Rome 3
Naples 3
Lyon 1
Milan 3
Hanover 2
The suggested query should have contained LEFT OUTER JOIN WHERE b.cid = a.cid so that it would match the country ID in each table. Such a query would result in output like this:
France
- Lyon
- Nantes
- Paris
Germany
- Hanover
- Munchen
Italy
- Milan
- Naples
- Rome
HTH,
^_^
Copy link to clipboard
Copied
Merci
J'avais compris mais pour le plaisir d'apprendre, est-il possible de faire l'affichage du pays puis de la ville avec une seule table ?
Exemple de table :
cid country city
1 France Lyon
2 France Nantes
3 France Paris
4 Germany Hanover
5 Germany Munchen
6 Italy Milan
7 Italy Naples
8 Italy Rome
Merci pour votre implication
Cordialement
Copy link to clipboard
Copied
Yes, all you have to do is use nested CFOUTPUT tags. The primary CFOUTPUT tag would use the GROUP attribute, and the nested tag would use no attributes.
Oui, tout ce que vous avez à faire est d'utiliser des tags CFOUTPUT imbriqués. La balise CFOUTPUT primaire utiliserait l'attribut GROUP et la balise imbriquée n'utiliserait aucun attribut.
<cfquery name='country_city' datasource='#application.dsn#'>
SELECT cid, country, city
FROM table_country_city
ORDER BY country ASC, city ASC
</cfquery>
<cfoutput query='country_city' group='country'>
#country_city.country#<br />
<cfoutput>
- #country_city.city#<br />
</cfoutput><br />
</cfoutput>
One query, nested loops. Not quite as nice as my previous suggestion, for no reason other than I much prefer to normalize data and condense code and use OUTER JOIN whenever possible.
Une requête, boucles imbriquées. Pas tout à fait aussi agréable que ma suggestion précédente, pour aucune autre raison que je préfère beaucoup normaliser les données et condenser le code et utiliser OUTER JOIN chaque fois que possible.
HTH,
^_^
Copy link to clipboard
Copied
Merci ! dans les 2 cas, cela marche Très très bien !
Toujours pour apprendre ;-), est-il possible de ne voir la liste des villes que pour le pays choisi, dans un autre select ?
Exemple :
France Lyon
Germany Nantes
Italy Paris
Merci par avance
Copy link to clipboard
Copied
If I understand your query correctly, you would like to have each country in text, and next to it a SELECT of all the associated cities?
Certainly. To modify what I posted, most recently:
Si je comprends bien votre requête, vous aimeriez que chaque pays soit en texte, et à côté de lui un SELECT de toutes les villes associées?
Certainement. Pour modifier ce que j'ai affiché, plus récemment:
<cfquery name='country_city' datasource='#application.dsn#'>
SELECT cid, country, city
FROM table_country_city
ORDER BY country ASC, city ASC
</cfquery>
<cfoutput query='country_city' group='country'>
#country_city.country# <select name="citySelect" id="cs_#replace(country_city.country,' ','_','all')#"> <!--- replace space with underscore in country name for the SELECT ID --->
<cfoutput><option value="#country_city.city#">#country_city.city#</option></cfoutput></select><br />
</cfoutput>
HTH,
^_^
PS.. I just re-read your message. Basically, a select of countries that will change the select of cities is basically the same, but more involved. It will include some Javascript or jQuery (but don't load jQuery just for this; use it only if you are already using jQuery.)
Copy link to clipboard
Copied
FOLLOW UP: Raymond Camden wrote a blog on this very subject that might be helpful. It's in English, but you should be able to translate it, easily, with Google Translate.
https://www.raymondcamden.com/2014/05/30/Related-selects-with-multiple-options/
SUIVI: Raymond Camden a écrit un blog sur ce sujet qui pourrait être utile. C'est en anglais, mais vous devriez pouvoir le traduire, facilement, avec Google Translate.
https://www.raymondcamden.com/2014/05/30/Related-selects-with-multiple-options/
V/r,
^_^
Copy link to clipboard
Copied
Bonjour,
En effet, il faut passer par Javascript !
Mais c'est ma limite. Je ne connais pas cette technologie.
J'ai copié l'ensemble du script et cela ne fonctionne pas 😞
Tant pis
Cordialement
Copy link to clipboard
Copied
You copied Raymond's script and tried it on your system? I don't mean to sound trite, but are you sure you put Javascript and CFscript in their proper places? (You do say that Javascript is your limit. I assume, then, that you are not that versed in CFscript.) Did you load jQuery before the jQuery code? The jQuery code won't work unless jQuery is loaded first. Were there any error messages, either CF error messages, or Javascript error messages in the browser? I'm curious.
Vous avez copié le script de Raymond et l'avez essayé sur votre système? Je ne veux pas paraître banal, mais êtes-vous sûr de mettre Javascript et CFscript à leur place? (Vous dites que Javascript est votre limite. Je suppose, alors, que vous n'êtes pas aussi versé dans CFscript.) Avez-vous chargé jQuery avant le code jQuery? Le code jQuery ne fonctionnera pas à moins que jQuery soit chargé en premier. Y at-il eu des messages d'erreur, soit des messages d'erreur des FC, soit des messages d'erreur Javascript dans le navigateur? Je suis curieux.
V/r (avec respect),
^_^
Copy link to clipboard
Copied
Bonjour,
Vous avez parfaitement raison (intuition féminine ? ).
Je me suis contenté de copier le code !
Je ne connais pas du tout cfscript et la façon de le mettre en place. La même chose avec JQuery. Je me suis formé tout seul.
De plus, en France, CF est un peu délaissé !
Dommage, que vous soyez si loin. J'aurais bien aimé prendre des cours avec vous !
Cordialement
Jean-Marie
Copy link to clipboard
Copied
Veuillez indiquer la bonne réponse. Merci.
Copy link to clipboard
Copied
AH! Okay. That is most likely the issue.
The way that Raymond coded his example has the inclusion of the jQuery library, first, followed by a hard-coded SELECT that contains the first choices, followed by an empty SELECT with no options, followed by the jQuery code that he wrote. In that code, he is using AJaX to send the choice of the first select to a ColdFusion Component (CFC) which retrieves the values related to that first choice, puts that data into a JSON object, and returns that to the page. AJaX will detect this returned data, clear all options from the second SELECT, and generates the options for that second SELECT from the returned data. There are a lot of steps involved, but it is pretty simple to do, actually. I wish I could provide better instructions, but I am at work and cannot take away too much time from my assigned tasks.
La façon dont Raymond a codé son exemple a inclus la bibliothèque jQuery, suivie d'un SELECT hard-coded qui contient les premiers choix, suivi d'un SELECT vide sans options, suivi du code jQuery qu'il a écrit. Dans ce code, il utilise AJaX pour envoyer le choix de la première sélection à un composant ColdFusion (CFC) qui récupère les valeurs associées à ce premier choix, place ces données dans un objet JSON et renvoie celle-ci à la page. AJaX détecte ces données renvoyées, efface toutes les options de la seconde SELECT et génère les options pour cette seconde SELECT à partir des données renvoyées. Il ya beaucoup d'étapes impliquées, mais il est assez simple à faire, en fait. J'aimerais pouvoir fournir de meilleures instructions, mais je suis au travail et ne peut pas prendre trop de temps de mes tâches assignées.
V/r,
^_^
Copy link to clipboard
Copied
Merci pour toutes ces explications ... mais insuffisantes pour que je comprenne
Je ne suis aucunement pressé !
Si un jour, ...
Cordialement
Jean-Marie
Copy link to clipboard
Copied
I attempted to provide an example based upon Raymond's code, but the Jive platform that Adobe is using for their forum is completely worthless, and turned my code into garbage. I hope you can figure it out.
J'ai essayé de fournir un exemple basé sur le code de Raymond, mais la plateforme Jive qu'Adobe utilise pour son forum est totalement sans valeur, et a transformé mon code en ordures. J'espère que vous pouvez le comprendre.
V/r,
^_^
Copy link to clipboard
Copied
Bonjour,
Merci pour le code que vous m'avez envoyé !
J'ai presque tout compris ;-).
Je ne sais où mettre la dernière partie : app.js.
D'autre part, il doit y avoir un fichier type clé pays ville ou 2 fichiers type idpays pays et idville ville ?
Merci par avance
Copy link to clipboard
Copied
Le fichier app.js doit être placé au bas de la page, avant le tag de fermeture /body. Mais la chose importante à retenir est que le fichier app.js doit aller après le code qui charge la bibliothèque jQuery.
Si vous utilisez une table pour contenir le pays et la ville, il n'y aura pas besoin d'ID. Toutefois, si vous utilisez des tables distinctes pour le pays et la ville, les deux doivent avoir un ID unique, et le tableau pour la ville aura besoin d'une colonne pour faire référence au pays dans lequel il est.
V/r,
^_^
Copy link to clipboard
Copied
Bonjour,
Voici votre script remanié :
<!--- created by WolfShade in ColdFusion --->
<!--- Dans un répertoire vierge, pour les tests, procédez comme suit : --->
<!--- selects.htm --->
<html>
<head>
<title>My Page</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<!--- jQuery doit être chargé avant la balise html de fermeture; Je le garde ici pour plus de simplicité --->
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
</head>
<body>
<!--- La première sélection est le code statique, mais vous pouvez le créer à partir d'une requête, ainsi --->
<form>
<select id="country">
<option value="0">-- Select a Country --</option>
<option value="1">France</option>
<option value="2">Germany</option>
<option value="3">Italy</option>
</select>
<!--- Laissez la deuxième sélection sans options; JQuery lui donnera des options lorsque le premier select change --->
<select id="city">
<option>-- Select a City --</option>
</select>
</form>
<!--- Incluez un fichier .js qui contient votre code jQuery et AJaX --->
<script src="app.js"></script>
</body>
</html>
app.js
$(document).ready(function() { $country= $("#country"); $city = $("#city"); $country.on("change", function(e) { var country = $(this).val();
// Pays est un tableau, le convertir en une liste
country = country.join(','); //always clear //toujours clair $city.empty(); //reinject the default //réinitialiser la valeur par défaut $city.append("<option value=''>-- Select a City --</option>"); //if blank, do nothing if(state === 0) return; $.getJSON("service.cfc?method=getCities", {country:country}).done(function(res) { for(var i=0, len=res.length; i<len; i++) { $city.append("<option value='"+res.CITY+"'>"+res.CITY+"</option>"); } }); }); });
<!--- service.cfc contiendra une fonction appelée "getCities" qui a un argument, une valeur, "country".
Créer une requête à l'intérieur de la fonction qui prend la valeur qui lui est passée et on obtient toutes les villes où le pays est égal à cette valeur retournée par cette requête. --->
Je ne sais que faire avec la dernière partie.
Merci par avance
Copy link to clipboard
Copied
Create a CFC (ColdFusion component) called 'service.cfc' that has a CFFUNCTION called 'getCities'.
Inside getCities, accept the parameter 'country' and use that to query the database for cities of that country, and CFRETURN the data. I cannot remember, however, if it needs to return a query object, or a JSON object. I think you should return a JSON object of the query data. But the AJaX will populate the second SELECT based upon that data.
Créez un CFC (composant ColdFusion) appelé 'service.cfc' qui a un CFFUNCTION appelé 'getCities'.
À l'intérieur de getCities, acceptez le paramètre 'country' et utilisez-le pour interroger la base de données pour les villes de ce pays, et CFRETURN les données. Je ne me souviens pas, cependant, s'il doit retourner un objet de requête, ou un objet JSON. Je pense que vous devriez retourner un objet JSON des données de la requête. Mais l'AJaX remplira le second SELECT en fonction de ces données.
V/r,
^_^
PS Désolé pour la réponse tardive. Le Mid-West était sous la menace d'une tempête de verglas qui était censée détruire les lignes électriques, donc je n'ai pas été en ligne beaucoup pour les derniers jours. Heureusement, la tempête n'a pas été aussi mauvaise que prévu.
Copy link to clipboard
Copied
Désolé mais jamais fait de CFC[ ]
Cordialement
Jean-Marie
Copy link to clipboard
Copied
I had a thought that you may not be familiar with CFC, immediately after I submitted my response.
I do not know how much ColdFusion experience you have, but CFC files are pretty easy to learn. While it is typical to place CFC files in a /components folder, you can place the CFC within the same folder as the CFM file that is calling it.
The basic structure of a CFC is:
CFCOMPONENT
CFFUNCTION
CFARGUMENT (could be more than one)
... code for processing ... (in this case, your database query)
CFRETURN (data - your query object, or JSON object, whichever is required)
/CFFUNCTION (closing tag)
/CFCOMPONENT (closing tag)
J'ai pensé que vous ne connaissiez peut-être pas les CFC, immédiatement après avoir soumis ma réponse.
Je ne sais pas combien d'expérience ColdFusion vous avez, mais les fichiers CFC sont assez faciles à apprendre. Bien qu'il soit typique de placer des fichiers CFC dans un dossier / components, vous pouvez placer le CFC dans le même dossier que le fichier CFM qui l'appelle.
La structure de base d'un CFC est la suivante:
CFCOMPONENT
CFFUNCTION
CFARGUMENT (pourrait être plus d'un)
... code pour le traitement ... (dans ce cas, votre requête de base de données)
CFRETURN (données - votre objet de requête ou objet JSON, selon le cas)
/CFFUNCTION (balise de fermeture)
/CFCOMPONENT (balise de fermeture)
HTH,
^_^