Précédent   Forum des professionnels en informatique > Bases de données > MS SQL-Server
MS SQL-Server Forum Microsoft SQL-Server. Avant de poster -> FAQ SQL-Server, Tutoriels SQL-Server
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 05/06/2011, 03h59   #1
Candidat au titre de Membre du Club
 
Inscription : janvier 2009
Messages : 107
Détails du profil
Informations forums :
Inscription : janvier 2009
Messages : 107
Points : 13
Points : 13
Par défaut Concatenation du resultat d'un SELECT sur une colonne sans la première et dernière ligne

Salut,


je vous donne une idée sur ce que je veux faire :

exemple : select VAL from TABLE

resultat :

1
2
...
5

je dois récupérer une chaine de caractères de cette manière :

chaine résultat : 2, 3 et 4

Y'a t-il un moyen pour qu'une requête SELECT sur une colonne retourne touts les lignes sauf la première et la dernière ?
Merci d'avance
LePassager est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/06/2011, 10h23   #2
Responsable SQL Server

 
Avatar de mikedavem
 
Homme David BARBARIN
Expert SQL Server
Inscription : août 2005
Messages : 3 723
Détails du profil
Informations personnelles :
Nom : Homme David BARBARIN
Localisation : France, Haute Savoie (Rhône Alpes)

Informations professionnelles :
Activité : Expert SQL Server
Secteur : Conseil

Informations forums :
Inscription : août 2005
Messages : 3 723
Points : 6 844
Points : 6 844
Bonjour,

Quel est vote but ?

++
mikedavem est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/06/2011, 15h03   #3
Candidat au titre de Membre du Club
 
Inscription : janvier 2009
Messages : 107
Détails du profil
Informations forums :
Inscription : janvier 2009
Messages : 107
Points : 13
Points : 13
Citation:
Envoyé par mikedavem Voir le message
Bonjour,

Quel est vote but ?

++
Bonjour, je voudrais récupérer dans un jeu de résultats d'un SELECT toutes les lignes sauf la première et la dernière

Merci
LePassager est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/06/2011, 18h04   #4
Modérateur

 
Avatar de elsuket
 
Homme Nicolas Souquet
Administrateur de base de données
Inscription : janvier 2005
Messages : 4 669
Détails du profil
Informations personnelles :
Nom : Homme Nicolas Souquet
Âge : 30
Localisation : Thaïlande

Informations professionnelles :
Activité : Administrateur de base de données
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : janvier 2005
Messages : 4 669
Points : 8 729
Points : 8 729
Bonjour,

Il n'y a pas d'ordre en SQL.
Donc vous êtes obligé de le générer, ce qui peut être coûteux :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
;WITH
	CTE_ORDER AS
	(
		SELECT	val
			, ROW_NUMBER() OVER(ORDER BY val) AS n
		FROM	dbo.maTable
	)
SELECT		O.val
FROM		CTE_ORDER AS O
CROSS APPLY	(
			SELECT	MAX(n) - 1 AS max_n 
			FROM	CTE_ORDER
		) AS M
WHERE		O.n BETWEEN 2 AND M.max_n
@++
__________________
En bases de données relationnelles SQL, il n'y a ni tableaux, ni enregistrements, ni champs: il y a des tables, des lignes et des colonnes.
Blog | Profil| Consulter ou télécharger les fichiers d'aide de SQL Server, des versions 2000 à 2012
elsuket est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/06/2011, 20h12   #5
Candidat au titre de Membre du Club
 
Inscription : janvier 2009
Messages : 107
Détails du profil
Informations forums :
Inscription : janvier 2009
Messages : 107
Points : 13
Points : 13
Citation:
Envoyé par elsuket Voir le message
Bonjour,

Il n'y a pas d'ordre en SQL.
Donc vous êtes obligé de le générer, ce qui peut être coûteux :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
;WITH
	CTE_ORDER AS
	(
		SELECT	val
			, ROW_NUMBER() OVER(ORDER BY val) AS n
		FROM	dbo.maTable
	)
SELECT		O.val
FROM		CTE_ORDER AS O
CROSS APPLY	(
			SELECT	MAX(n) - 1 AS max_n 
			FROM	CTE_ORDER
		) AS M
WHERE		O.n BETWEEN 2 AND M.max_n
@++
Merci infiniment,
Peux tu m'expliquer ce bout de code STP ?
LePassager est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/06/2011, 22h47   #6
Rédacteur/Modérateur

 
Avatar de SQLpro
 
Homme Frédéric BROUARD
Expert SGBDR & SQL
Inscription : mai 2002
Messages : 10 954
Détails du profil
Informations personnelles :
Nom : Homme Frédéric BROUARD
Localisation : France

Informations professionnelles :
Activité : Expert SGBDR & SQL
Secteur : Conseil

Informations forums :
Inscription : mai 2002
Messages : 10 954
Points : 17 774
Points : 17 774
C'est une requête SQL... Il vous suffit d'apprendre le SQL. Mon site web, comme mon livre peuvent vous y aider !

A +
__________________
Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
Site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
Blog SQL, SQL Server, modélisation données : http://blog.developpez.com/sqlpro
http://www.sqlspot.com : modélisation, conseils, audit, optimisation, formation
* * * * * Enseignant CNAM PACA - ISEN Toulon - CESI Aix en Provence * * * * *
SQLpro est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/06/2011, 06h24   #7
Modérateur

 
Avatar de elsuket
 
Homme Nicolas Souquet
Administrateur de base de données
Inscription : janvier 2005
Messages : 4 669
Détails du profil
Informations personnelles :
Nom : Homme Nicolas Souquet
Âge : 30
Localisation : Thaïlande

Informations professionnelles :
Activité : Administrateur de base de données
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : janvier 2005
Messages : 4 669
Points : 8 729
Points : 8 729
Même si SQLPro a totalement raison, (je vous invite d'ailleurs fortement à parcourir son site !), voici les détails :

Code :
1
2
3
4
5
6
7
;WITH
	CTE_ORDER AS
	(
		SELECT	val
			, ROW_NUMBER() OVER(ORDER BY val) AS n
		FROM	dbo.maTable
	)
C'est une expression de table commune (Common Table Expression / CTE dans la littérature Anglaise) : il s'agit d'une vue qui n'a d'existence que pour la durée de la transaction.
Ici on lui fait ordonner les valeurs de la colonne val, en affectant un numéro de ligne (ROW_NUMBER()) suivant cet ordre (clause OVER()).

Code :
1
2
3
4
CROSS APPLY	(
			SELECT	MAX(n) - 1 AS max_n 
			FROM	CTE_ORDER
		) AS M
Nous avons besoin de connaître le nombre de lignes que comprend la CTE.
Donc on recherche le MAX(n), et on l'applique (APPLY) à l'ensemble des lignes retournées par la CTE.
En fait d'utilisation de APPLY, on force SQL Server à n'effectuer qu'une seule fois ce calcul, plutôt que de l'effectuer pour chaque ligne.

Code :
WHERE		O.n BETWEEN 2 AND M.max_n
Ici on prend les indices de lignes numéro 2 et MAX(n) - 1 : l'avant dernier.
Cela nous filtrera donc les valeurs de la colonne val comme vous le souhaitiez.

@++
__________________
En bases de données relationnelles SQL, il n'y a ni tableaux, ni enregistrements, ni champs: il y a des tables, des lignes et des colonnes.
Blog | Profil| Consulter ou télécharger les fichiers d'aide de SQL Server, des versions 2000 à 2012
elsuket est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 06/06/2011, 14h20   #8
Membre Expert
 
Inscription : janvier 2010
Messages : 1 084
Détails du profil
Informations personnelles :
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : janvier 2010
Messages : 1 084
Points : 1 573
Points : 1 573
Bonjour

si vous voulez le résultat sous forme de chaine de caractères, vous pouvez aussi faire comme ça :

Code SQL :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
 
/* jeu d'essai */
DECLARE @T TABLE(val varchar(8000))
 
;WITH T (n) AS (
	SELECT 'a'
	UNION ALL
	SELECT 'b'
	UNION ALL
	SELECT 'c'
	UNION ALL
	SELECT 'd'
)
INSERT INTO @T
SELECT *
FROM T
 
/* /jeu essai */
 
 
DECLARE @Res VARCHAR(8000)
DECLARE @Tmp VARCHAR(8000)
 
SELECT 
	@Res = 
		CASE 
			WHEN @Tmp IS NULL 
				THEN NULL 
			ELSE 
				CASE 
					WHEN @Res IS NULL 
						THEN ''
					ELSE 
						@Res 
						+ CASE WHEN @Res <> '' THEN ',' ELSE '' END
						+ @Tmp
				END
		END,
	@Tmp = val
FROM @T T
ORDER BY val --mettre ici l'ordre voulu
 
SELECT @Res

Avec un petite bidouille supplémentaire, vous pouvez aussi remplacer la dernière virgule par un "et"...

par contre, quant à la question de mikedavem :
Citation:
Quel est vote but ?
je pense que le fond de la question était plutôt :
Que voulez vous faire de cette chaine par la suite ?

Ce type d'opération aurait plus sa place dans le code client...
aieeeuuuuu est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 06/06/2011, 14h48   #9
Modérateur

 
Avatar de elsuket
 
Homme Nicolas Souquet
Administrateur de base de données
Inscription : janvier 2005
Messages : 4 669
Détails du profil
Informations personnelles :
Nom : Homme Nicolas Souquet
Âge : 30
Localisation : Thaïlande

Informations professionnelles :
Activité : Administrateur de base de données
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : janvier 2005
Messages : 4 669
Points : 8 729
Points : 8 729
Ho j'avais pas vu

Une autre possibilité :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
DECLARE @sql varchar(max)
 
;WITH
	CTE_ORDER AS
	(
		SELECT	val
			, ROW_NUMBER() OVER(ORDER BY val) AS n
		FROM	dbo.maTable
	)
SELECT		@sql = CASE
				WHEN @sql IS NULL THEN CAST(O.val AS varchar(10))
				ELSE @sql + ', ' + CAST(O.val AS varchar(10))
			END
FROM		CTE_ORDER AS O
CROSS APPLY	(
			SELECT	MAX(n) - 1 AS max_n 
			FROM	CTE_ORDER
		) AS M
WHERE		O.n BETWEEN 2 AND M.max_n
 
SELECT	@sql
@++
__________________
En bases de données relationnelles SQL, il n'y a ni tableaux, ni enregistrements, ni champs: il y a des tables, des lignes et des colonnes.
Blog | Profil| Consulter ou télécharger les fichiers d'aide de SQL Server, des versions 2000 à 2012
elsuket est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/06/2011, 18h54   #10
Candidat au titre de Membre du Club
 
Inscription : janvier 2009
Messages : 107
Détails du profil
Informations forums :
Inscription : janvier 2009
Messages : 107
Points : 13
Points : 13
Citation:
Envoyé par elsuket Voir le message
Même si SQLPro a totalement raison, (je vous invite d'ailleurs fortement à parcourir son site !), voici les détails :

Code :
1
2
3
4
5
6
7
;WITH
	CTE_ORDER AS
	(
		SELECT	val
			, ROW_NUMBER() OVER(ORDER BY val) AS n
		FROM	dbo.maTable
	)
C'est une expression de table commune (Common Table Expression / CTE dans la littérature Anglaise) : il s'agit d'une vue qui n'a d'existence que pour la durée de la transaction.
Ici on lui fait ordonner les valeurs de la colonne val, en affectant un numéro de ligne (ROW_NUMBER()) suivant cet ordre (clause OVER()).

Code :
1
2
3
4
CROSS APPLY	(
			SELECT	MAX(n) - 1 AS max_n 
			FROM	CTE_ORDER
		) AS M
Nous avons besoin de connaître le nombre de lignes que comprend la CTE.
Donc on recherche le MAX(n), et on l'applique (APPLY) à l'ensemble des lignes retournées par la CTE.
En fait d'utilisation de APPLY, on force SQL Server à n'effectuer qu'une seule fois ce calcul, plutôt que de l'effectuer pour chaque ligne.

Code :
WHERE		O.n BETWEEN 2 AND M.max_n
Ici on prend les indices de lignes numéro 2 et MAX(n) - 1 : l'avant dernier.
Cela nous filtrera donc les valeurs de la colonne val comme vous le souhaitiez.

@++
Un grand Merci ^^
j'ai voulu avoir des explications parce que j'aime pas faire du copier coller, il faut comprendre les choses quand meme...
LePassager est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/06/2011, 18h59   #11
Candidat au titre de Membre du Club
 
Inscription : janvier 2009
Messages : 107
Détails du profil
Informations forums :
Inscription : janvier 2009
Messages : 107
Points : 13
Points : 13
Citation:
Envoyé par SQLpro Voir le message
C'est une requête SQL... Il vous suffit d'apprendre le SQL. Mon site web, comme mon livre peuvent vous y aider !

A +
Merci,
j'ai rien trouvé dans SQL pour extraire toutes les lignes sauf la premiere et la derniere
LePassager est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/06/2011, 19h01   #12
Candidat au titre de Membre du Club
 
Inscription : janvier 2009
Messages : 107
Détails du profil
Informations forums :
Inscription : janvier 2009
Messages : 107
Points : 13
Points : 13
Merci tout le monde, je vais consulter le site c'est promis ^^

Merci encore.
LePassager est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/06/2011, 19h09   #13
Candidat au titre de Membre du Club
 
Inscription : janvier 2009
Messages : 107
Détails du profil
Informations forums :
Inscription : janvier 2009
Messages : 107
Points : 13
Points : 13
Citation:
Envoyé par aieeeuuuuu Voir le message
Bonjour

si vous voulez le résultat sous forme de chaine de caractères, vous pouvez aussi faire comme ça :

Code SQL :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
 
/* jeu d'essai */
DECLARE @T TABLE(val varchar(8000))
 
;WITH T (n) AS (
	SELECT 'a'
	UNION ALL
	SELECT 'b'
	UNION ALL
	SELECT 'c'
	UNION ALL
	SELECT 'd'
)
INSERT INTO @T
SELECT *
FROM T
 
/* /jeu essai */
 
 
DECLARE @Res VARCHAR(8000)
DECLARE @Tmp VARCHAR(8000)
 
SELECT 
	@Res = 
		CASE 
			WHEN @Tmp IS NULL 
				THEN NULL 
			ELSE 
				CASE 
					WHEN @Res IS NULL 
						THEN ''
					ELSE 
						@Res 
						+ CASE WHEN @Res <> '' THEN ',' ELSE '' END
						+ @Tmp
				END
		END,
	@Tmp = val
FROM @T T
ORDER BY val --mettre ici l'ordre voulu
 
SELECT @Res

Avec un petite bidouille supplémentaire, vous pouvez aussi remplacer la dernière virgule par un "et"...

par contre, quant à la question de mikedavem :


je pense que le fond de la question était plutôt :
Que voulez vous faire de cette chaine par la suite ?

Ce type d'opération aurait plus sa place dans le code client...

l'objectif principal c'est d'avoir à partir d'un ID l'ensemble des villes qu'un autocar doit visiter sans mettre les villes de depart et d'arrivé... ( vu la conception de la BD les villes de depart et d'arrivé sont stockés dans d'autres tables a part la table contenant les villes à visiter...
et le resultat c pour l'imprimer avec Crystal reaport
j'ai simplifier dans le but de faciliter la comprehesion
LePassager est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/06/2011, 09h56   #14
Membre Expert
 
Inscription : janvier 2010
Messages : 1 084
Détails du profil
Informations personnelles :
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : janvier 2010
Messages : 1 084
Points : 1 573
Points : 1 573
Citation:
Envoyé par LePassager Voir le message
j'ai simplifier dans le but de faciliter la compréhension
Vous avez surtout compliqué le problème

Si vos villes de départ et d'arrivée sont clairement identifiées... alors il suffit de les retirer du résultat avec un filtre, ce qui a plus de sens pour SQL que de retirer "la première et la dernière ligne".
aieeeuuuuu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/06/2011, 12h06   #15
Modérateur

 
Avatar de elsuket
 
Homme Nicolas Souquet
Administrateur de base de données
Inscription : janvier 2005
Messages : 4 669
Détails du profil
Informations personnelles :
Nom : Homme Nicolas Souquet
Âge : 30
Localisation : Thaïlande

Informations professionnelles :
Activité : Administrateur de base de données
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : janvier 2005
Messages : 4 669
Points : 8 729
Points : 8 729
En fait c'est votre modèle qui est faux : il suffit pour cela d'ajouter une colonne avec la liste des points / arrêts du parcours, et leur indice dans le parcours.

Comme ce genre de table change peu, vous pouvez ensuite créer une vue indexée qui vous donne pour chaque parcours le MIN() et le MAX() de l'indice.

La requête est alors enfantine ...

@++
__________________
En bases de données relationnelles SQL, il n'y a ni tableaux, ni enregistrements, ni champs: il y a des tables, des lignes et des colonnes.
Blog | Profil| Consulter ou télécharger les fichiers d'aide de SQL Server, des versions 2000 à 2012
elsuket est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/06/2011, 13h01   #16
Rédacteur/Modérateur

 
Avatar de SQLpro
 
Homme Frédéric BROUARD
Expert SGBDR & SQL
Inscription : mai 2002
Messages : 10 954
Détails du profil
Informations personnelles :
Nom : Homme Frédéric BROUARD
Localisation : France

Informations professionnelles :
Activité : Expert SGBDR & SQL
Secteur : Conseil

Informations forums :
Inscription : mai 2002
Messages : 10 954
Points : 17 774
Points : 17 774
Si vous cherchez à parcourir des chemins à partir d'une table de distance, il vous faut une requête récursive.
D'autant plus si vous voulez retrouver le plus court chemin !
Lisez l'article que j'ai écrit à ce sujet : http://sqlpro.developpez.com/cours/s...ursives/#LIV-B

A +
__________________
Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
Site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
Blog SQL, SQL Server, modélisation données : http://blog.developpez.com/sqlpro
http://www.sqlspot.com : modélisation, conseils, audit, optimisation, formation
* * * * * Enseignant CNAM PACA - ISEN Toulon - CESI Aix en Provence * * * * *
SQLpro est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/06/2011, 01h38   #17
Candidat au titre de Membre du Club
 
Inscription : janvier 2009
Messages : 107
Détails du profil
Informations forums :
Inscription : janvier 2009
Messages : 107
Points : 13
Points : 13
Citation:
Envoyé par elsuket Voir le message
En fait c'est votre modèle qui est faux : il suffit pour cela d'ajouter une colonne avec la liste des points / arrêts du parcours, et leur indice dans le parcours.

Comme ce genre de table change peu, vous pouvez ensuite créer une vue indexée qui vous donne pour chaque parcours le MIN() et le MAX() de l'indice.

La requête est alors enfantine ...

@++
Merci encore, je suis encore debutant SQL ^^
LePassager est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/06/2011, 01h40   #18
Candidat au titre de Membre du Club
 
Inscription : janvier 2009
Messages : 107
Détails du profil
Informations forums :
Inscription : janvier 2009
Messages : 107
Points : 13
Points : 13
Citation:
Envoyé par SQLpro Voir le message
Si vous cherchez à parcourir des chemins à partir d'une table de distance, il vous faut une requête récursive.
D'autant plus si vous voulez retrouver le plus court chemin !
Lisez l'article que j'ai écrit à ce sujet : http://sqlpro.developpez.com/cours/s...ursives/#LIV-B

A +
Interessant comme idée, Merci
LePassager est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 18h44.


 
 
 
 
Partenaires

Hébergement Web