Précédent   Forum des professionnels en informatique > Bases de données > Langage SQL
Langage SQL Forum d'entraide sur le langage SQL et sur les questions liées à la conception de schéma (DDL). Cours SQL
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 21/09/2011, 14h59   #1
Invité de passage
 
Inscription : septembre 2011
Messages : 4
Détails du profil
Informations forums :
Inscription : septembre 2011
Messages : 4
Points : 0
Points : 0
Par défaut Recherche algorithme plus simple

Bonjour a tous

Voici mon problème

j'essaie de trouver un moyen simple de "ranké" par groupe de valeur sur une ligne , je ne sais pas si je suis clair donc voici en image ce que j’essaie de faire simplement.
j'ai identifié un mes groupe j'affecte un ID (rank)

SID RID rank
1 1 1
1 2 1
1 3 1
2 1 2
2 2 2
3 1 1
3 2 1
3 3 1
4 2 3
4 3 3
4 4 3
5 2 4
5 3 4
6 1 2
6 2 2


voici la table Test
Code :
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
CREATE TABLE [dbo].[TestApp](
	[SId] [numeric](18, 0) NOT NULL,
	[RId] [numeric](18, 0) NOT NULL,
 CONSTRAINT [PK_TestApp] PRIMARY KEY NONCLUSTERED 
(
	[SId] ASC,
	[RId] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON, FILLFACTOR = 90) ON [PRIMARY]
) ON [PRIMARY]
 
 
 
INSERT INTO [dbo].[TestApp]([SId],[RId]) VALUES (1,1)
INSERT INTO [dbo].[TestApp]([SId],[RId]) VALUES (1,2)
INSERT INTO [dbo].[TestApp]([SId],[RId]) VALUES (1,3)
INSERT INTO [dbo].[TestApp]([SId],[RId]) VALUES (2,1)
INSERT INTO [dbo].[TestApp]([SId],[RId]) VALUES (2,2)
INSERT INTO [dbo].[TestApp]([SId],[RId]) VALUES (2,3)
INSERT INTO [dbo].[TestApp]([SId],[RId]) VALUES (2,33)
INSERT INTO [dbo].[TestApp]([SId],[RId]) VALUES (3,1)
INSERT INTO [dbo].[TestApp]([SId],[RId]) VALUES (3,2)
INSERT INTO [dbo].[TestApp]([SId],[RId]) VALUES (3,3)
INSERT INTO [dbo].[TestApp]([SId],[RId]) VALUES (4,1)
INSERT INTO [dbo].[TestApp]([SId],[RId]) VALUES (4,2)
INSERT INTO [dbo].[TestApp]([SId],[RId]) VALUES (5,1)
INSERT INTO [dbo].[TestApp]([SId],[RId]) VALUES (5,3)
INSERT INTO [dbo].[TestApp]([SId],[RId]) VALUES (6,2)
INSERT INTO [dbo].[TestApp]([SId],[RId]) VALUES (6,3)
Voici ma solution, mais je la trouve compliquée et de plus je suis obligé de connaitre le nombre de combinaisons max possible


Code :
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
 
 
 
WITH test AS 
(
	SELECT [SID] ,RID 
    ,row_number() OVER(PARTITION BY [SID] ORDER BY RID ASC) AS resultat  
	FROM [dbo].[TestApp]
)SELECT max(resultat) FROM test;
 
==> ON connait la valeur max pour le pivot puis :
 
WITH test AS 
(
	SELECT [SID] ,RID 
    ,row_number() OVER(PARTITION BY [SID] ORDER BY RID ASC) AS resultat  
	FROM [dbo].[TestApp]
),
test2 AS 
(
	SELECT [SID] , [1] AS "rnum1" ,  [2] AS "rnum2" , [3] AS "rnum3" , [4] AS "rnum4"
	FROM test 
	PIVOT (MAX(RID) FOR resultat IN ([1],[2],[3],[4]))AS pvt
),test3 AS
(
	SELECT [SID] ,rnum1,rnum2,rnum3,rnum4
    ,dense_rank() OVER(ORDER BY rnum1,rnum2,rnum3,rnum4 ASC) AS resultat  
	FROM test2
 ) SELECT T1.[SID] ,T2.RID , T1.resultat
 FROM test3 T1
	INNER JOIN [dbo].[TestApp] T2  ON T1.[SID] = T2.[SID]
ORDER BY T2.[SID] ,T2.RID
je sais pas terrible est-ce que quelqu’un a une idée

merci de votre aide
malzer est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/09/2011, 17h29   #2
Modérateur
 
Homme Fabien
Ingénieur d'études en décisionnel
Inscription : septembre 2008
Messages : 5 686
Détails du profil
Informations personnelles :
Nom : Homme Fabien
Âge : 34
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Ingénieur d'études en décisionnel
Secteur : Arts - Culture

Informations forums :
Inscription : septembre 2008
Messages : 5 686
Points : 10 431
Points : 10 431
Envoyer un message via ICQ à Waldar Envoyer un message via Skype™ à Waldar
Vous montrez du code, des données de départ, des données intermédiaires et c'est une très bonne chose.

Il manque encore la finalité de votre requête, tant en terme de données qu'en terme d'algorithme !

Vous n'avez pas précisé votre SGBD non plus, j'imagine qu'il s'agit de MS SQL-Server 2005 ou 2008.
__________________
Email : http://scr.im/waldar
Waldar est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/09/2011, 17h36   #3
Membre Expert
 
Homme Sylvain Devidal
Chef de projets Générix
Inscription : février 2010
Messages : 1 062
Détails du profil
Informations personnelles :
Nom : Homme Sylvain Devidal
Âge : 33
Localisation : France, Rhône (Rhône Alpes)

Informations professionnelles :
Activité : Chef de projets Générix
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : février 2010
Messages : 1 062
Points : 1 515
Points : 1 515
Pour la finalité, je me suis crâmé pas mal de neuronnes pour comprendre, et effectivement, c'est bien pire à formuler...

En fait, dans la colonne "RID" on voit des successions identiques de valeurs qui se suivent pour un même SID pour des SID différents.

Grmpf, super clair...

Si on regarde dans son résultat attendu, en rouge, on a RID = "1, 2, 3" pour SID = 1 et SID = 3.
=> Ils ont le même "rank".

Idem pour les autres couleurs.

En fait, il cherche à identifier (et regrouper sous un même numéro de "rank") les suites identiques de valeurs de SID pour des RID différents.

En gros, si SID c'est des voitures et RID des options, alors il cherche à regrouper les voitures qui ont les mêmes options sous un "rank" identique (qui serait un "pack" en marketing de voitures).

(c'est fou comme un exemple concret ça aide à la comprenette )
StringBuilder est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/09/2011, 17h51   #4
Invité de passage
 
Inscription : septembre 2011
Messages : 4
Détails du profil
Informations forums :
Inscription : septembre 2011
Messages : 4
Points : 0
Points : 0
merci pour vos réponse ,

Merci a StringBuilder de m'avoir compris

Citation:
si SID c'est des voitures et RID des options, alors il cherche à regrouper les voitures qui ont les mêmes options sous un "rank" identique (qui serait un "pack" en marketing de voitures).



Désolé , j'ai oublié de préciser le SGBD, je suis sur du MS SQL-Server 2005
Mon algorithme en résumé :
1 - j'identifie les différentes combinaisons
2 - je construis ma table (pivot)
3 - je rank


merci de votre
malzer est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/09/2011, 18h16   #5
Modérateur
 
Homme Fabien
Ingénieur d'études en décisionnel
Inscription : septembre 2008
Messages : 5 686
Détails du profil
Informations personnelles :
Nom : Homme Fabien
Âge : 34
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Ingénieur d'études en décisionnel
Secteur : Arts - Culture

Informations forums :
Inscription : septembre 2008
Messages : 5 686
Points : 10 431
Points : 10 431
Envoyer un message via ICQ à Waldar Envoyer un message via Skype™ à Waldar
Est-ce que le rang final a une importance ou il suffit que les même combinaisons possèdent le même rang ?
__________________
Email : http://scr.im/waldar
Waldar est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/09/2011, 19h43   #6
Membre confirmé
 
Homme
Développeur informatique
Inscription : octobre 2006
Messages : 181
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Développeur informatique

Informations forums :
Inscription : octobre 2006
Messages : 181
Points : 267
Points : 267
Peux tu avoir des doublons (SID, RID) ? PK pas de doublon
Combien as tu de RID ou max(RID) ?
Jean.Cri1 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/09/2011, 22h07   #7
Invité de passage
 
Inscription : septembre 2011
Messages : 4
Détails du profil
Informations forums :
Inscription : septembre 2011
Messages : 4
Points : 0
Points : 0
je peux avoir n RID , il faut juste que la combinaison de RID pour un SID identique possède le même rang pour répondre à Waldar
le numéro de rang n'a pas d'importance
la colonne rang dans mon exemple est le résultat que je veux l'inconvénient de ma solution est que je dois définir le nombre de RID groupé par SID manuellement, pour ensuite construire un tableau (rendre tous les RID possible en ligne)

Code :
1
2
3
4
5
6
WITH test AS 
(
	SELECT [SID] ,RID 
    ,row_number() OVER(PARTITION BY [SID] ORDER BY RID ASC) AS resultat  
	FROM [dbo].[TestApp]
)SELECT max(resultat) FROM test;
je voudrais supprimer cette étape, je ne sais pas si c'est possible
malzer est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/09/2011, 23h04   #8
Membre confirmé
 
Homme
Développeur informatique
Inscription : octobre 2006
Messages : 181
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Développeur informatique

Informations forums :
Inscription : octobre 2006
Messages : 181
Points : 267
Points : 267
Si tu as moins d'une cinquantaine de RID incrémentés de 1 en 1,
tu pourrais avoir une clé unique de rank ( type numeric 18 ) avec :
rank = somme (2 exposant RID ) groupé par SID.

En gros un bit de présence par RID possible.
Jean.Cri1 est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 22/09/2011, 09h03   #9
Membre Expert
 
Homme Sylvain Devidal
Chef de projets Générix
Inscription : février 2010
Messages : 1 062
Détails du profil
Informations personnelles :
Nom : Homme Sylvain Devidal
Âge : 33
Localisation : France, Rhône (Rhône Alpes)

Informations professionnelles :
Activité : Chef de projets Générix
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : février 2010
Messages : 1 062
Points : 1 515
Points : 1 515
D'après le jeu d'essai, il les RID ne se suivent pas forcément et ne partent pas forcément de 1.

Donc la solution du SUM, aussi séduisante soit-elle, ne peux pas répondre au problème : 1 + 2 = 3 ; 3 = 3 => On risque de croire qu'il s'agit du même groupe alors que ce sont des valeurs différentes;

En revanche, je pense que cette approche est la meilleure.

Pourquoi ne pas faire un truc du genre :
Code :
1
2
3
4
5
 
SELECT sid, sum(pow(2, rid - 1)) checksum
FROM latable
GROUP BY sid
ORDER BY checksum ASC
Puis englober cette requête dans une autre, qui va donner le même rank aux checksum identiques (bête fonction rank).

La seule limite, c'est qu'il ne fait pas que RID puisse avoir des valeurs trop grandes (au dela de 64, ça va commencer à être compliqué).
StringBuilder est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 22/09/2011, 09h30   #10
Membre confirmé
 
Homme
Développeur informatique
Inscription : octobre 2006
Messages : 181
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Développeur informatique

Informations forums :
Inscription : octobre 2006
Messages : 181
Points : 267
Points : 267
C'est bien ce que je pensais avoir proposé
Jean.Cri1 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/09/2011, 10h05   #11
Membre Expert
 
Homme Sylvain Devidal
Chef de projets Générix
Inscription : février 2010
Messages : 1 062
Détails du profil
Informations personnelles :
Nom : Homme Sylvain Devidal
Âge : 33
Localisation : France, Rhône (Rhône Alpes)

Informations professionnelles :
Activité : Chef de projets Générix
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : février 2010
Messages : 1 062
Points : 1 515
Points : 1 515
Citation:
Envoyé par Jean.Cri1 Voir le message
C'est bien ce que je pensais avoir proposé
Hmpf, excuse-moi, en effet, j'avais mal lu

Je croyais que partant du principe que c'était des suites "1, 2, 3" ; "1, 2, 3, 4, 5", etc. partant toujours de 1 et allant toujours de 1 en 1, tu proposais de faire un sum() tout simple. J'ai lu trop rapidement, désolé
StringBuilder est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/09/2011, 10h58   #12
Invité de passage
 
Inscription : septembre 2011
Messages : 4
Détails du profil
Informations forums :
Inscription : septembre 2011
Messages : 4
Points : 0
Points : 0
Merci a vous je vais essayer de suite
malzer 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 19h05.


 
 
 
 
Partenaires

Hébergement Web