2010-10-22 5 views
1

j'ai données comme suitlignes Passer à la requête sur la base des données

DECLARE @tmp TABLE(cid int, colspan int, rowspan int, corder int) 
INSERT INTO @tmp 
SELECT 1,2,null,1 
UNION 
SELECT 2,null,null,2 
UNION 
SELECT 3,null,null,3 
UNION 
SELECT 4,3,null,4 
UNION 
SELECT 5,null,null,5 
UNION 
SELECT 6,null,null,6 
UNION 
SELECT 7,null,null,7 

Je veux interroger retourner

cid colspan rowspan corder 
------------------------------------- 
1  2  null  1 
3  null null  3 
4  3  null  4 
7  null null  7 

dossiers seront classés par corder puis en utilisant la valeur colspan sauter enregistrements suivants (si colspan = 2, passez à la suivante 1, si 3 passez à la suivante 2). Est-ce possible de faire une requête? Pourquoi je veux ces données - J'essaye de lier ces données au contrôle de répéteur (modèle de table) pour créer une table dynamique et quand il y a colspan> 0 je ne veux pas que mon répéteur produise des articles de Td de sorte qu'il va s'étendre correctement.

+3

beaucoup plus facile de faire ce genre de choses dans le code, par opposition à SQL –

Répondre

0

Vous pouvez utiliser les fonctions CLR Table Valued qui renvoie la table réelle. Les fonctions CLR sont des fonctions que vous pouvez écrire dans votre langue maternelle C#, VB etc. et la DLL est intégrée dans la base de données.

En savoir plus sur d'ici:

http://msdn.microsoft.com/en-us/library/ms131103.aspx

3

Parce que (Comme dit Safran @ Sam dans les commentaires), il est en effet beaucoup plus facile de faire ce genre de choses dans le code de procédure, cela signifie que votre La table n'est pas conçue correctement pour SQL.

Dans une base de données SQL, chaque ligne doit décrire une entité unique (ou une relation unique entre entités). Ne pas le faire si un défaut de conception assez commun. Par exemple, considérez ce tableau de la paie:

CREATE TABLE Payroll 
(
employee_number CHAR(10) NOT NULL 
    REFERENCES Personnel (employee_number), 
effective_date DATE NOT NULL, 
salary_amount DECIMAL(19, 4) NOT NULL 
    CHECK (salary_amount >= 0), 
UNIQUE (effective_date, employee_number) 
); 

INSERT INTO Payroll (employee_number, effective_date, salary_amount) 
    VALUES ('U83GHVPSGP', '2001-01-01', 5000), 
      ('U83GHVPSGP', '2002-01-01', 7000), 
      ('U83GHVPSGP', '2002-01-01', 9000); 

Le problème ici est qu'il est des périodes de modélisation, mais la date de fin de chaque période est dervied de la date de début d'une autre ligne-à-dire l'entité (soit une période unique de salaire) est modélisé à l'aide deux lignes et chaque date de début joue deux rôles dans la base de données. Un effet secondaire est qu'une requête simple telle que "Get me l'employé de période U83GHVPSGP a été payé 5000 MNT" est non triviale (du point de vue de la mise en œuvre, elle impliquera une sous-requête corrélée qui risque de mal fonctionner sur un Plate-forme SQL). Le tableau ci-dessus souffrira d'anomalies non évidentes, par ex. supprimer la ligne pour laquelle U83GHVPSGP a reçu 7000 MNT changera implicitement les données sur une autre ligne, c'est-à-dire qu'il semble maintenant que U83GHVPSGP a été payé 5000 MNT jusqu'au "2002-01-01" alors que ce n'était pas le cas. Le fait que vous ayez une colonne nommée rowspan est l'exemple le plus parfait que j'ai jamais vu d'une «odeur» pour ce genre de défaut de conception.

Je ne veux pas paraître dur. Votre table est sans aucun doute parfaitement logique pour le code procédural, utilisez donc le code procédural et non SQL. SQL fonctionne mieux avec les solutions basées sur des ensembles, donc si vous voulez utiliser SQL, pensez à redéfinir votre table pour modéliser les entités dans des tables séparées de la relation entre les entités et assurez-vous que les deux données sur plusieurs lignes.

+0

pouvez-vous me donner un petit exemple de la conception de la table? Je ne suis toujours pas clair –

1

Essayez d'utiliser un CTE récursive, comme ceci:

with cte as (
select t.* from @tmp t where corder = 1 
union all 
select t.* from @tmp t join cte c on t.corder = (c.corder + coalesce(c.colspan,1)) 
) 
select * from cte 
+0

ça ne marche pas quand le cordon n'est pas en ordre Ex: changer le cordon pour le cid 4 à 5 et pour le cid, le corder à 4. –

+0

@rs, votre question a explicitement déclaré "Les enregistrements seront commandés par corder". Si vous voulez changer la question, veuillez changer la question. –

+0

désolé mon mauvais oui cela fonctionne quand je les commande. Je pensais à autre chose. –

Questions connexes