2009-07-06 9 views
0

J'ai un problème que je l'ai déjà résolu à l'aide de T-SQL (boucle curseur &). (Serveur SQL 2005)Afficher les enregistrements du tableau maître/maître-détail en utilisant requête SQL uniquement

Mais je cherche la solution en utilisant SQL.

J'ai une table principale avec une colonne dire MasterRecord (tous sont uniques et tapez VARCHAR et PK)

MasterRecord 
------------ 
MRecord1 
MRecord2 
MRecord3 
MRecord4 
................ 
.................. 
MRecord[n] 

Maintenant la table maître-détail a deux colonnes MasterRecord (Varchar & FK) et DetailRecord (Varchar)

MasterRecord   DetailRecord 
--------------------------------------------- 
MRecord1    MRecord1_DetailRecord1 
MRecord1    MRecord1_DetailRecord2 
MRecord1    MRecord1_DetailRecord3 
MRecord1    MRecord1_DetailRecord4 
MRecord2    MRecord2_DetailRecord1 
MRecord2    MRecord2_DetailRecord2 
MRecord2    MRecord2_DetailRecord3 
MRecord2    MRecord2_DetailRecord4 
............................................... 
................................................ 
MRecord[n]   MRecord[n] _DetailRecord1 
MRecord[n]   MRecord[n] _DetailRecord2 
MRecord[n]   MRecord[n] _DetailRecord3 
MRecord[n]   MRecord[n] _DetailRecord4 

où [n] peut être un nombre

le problème est que pour chaque enregistrement maître unique, je dois aller chercher le top 2 enregistrements détaillés

O/P:

MasterRecord   DetailRecord 
--------------------------------------------- 
MRecord1    MRecord1_DetailRecord1 
MRecord1    MRecord1_DetailRecord2 
MRecord2    MRecord2_DetailRecord1 
MRecord2    MRecord2_DetailRecord2 
MRecord3    MRecord3_DetailRecord1 
MRecord3    MRecord3_DetailRecord2 
............................................... 
.............................................. 
MRecord[n]   MRecord[n] _DetailRecord1 
MRecord[n]   MRecord[n] _DetailRecord2 

Espoir J'ai clairement expliqué mon problème.

Veuillez me le faire savoir pour plus de précisions.

+0

où voulez-vous afficher dans un format de détail maître? quelle langue/cadre? .net/java/vb6? winforms/asp.net/silverlight? – shahkalpesh

+0

C'est SQL Server 2005. Je veux l'afficher dans DataGrid. C'est l'application Asp.net. Mais le problème doit être résolu uniquement dans le backend. Je ne suis pas censé le gérer dans le code derrière (selon l'instruction des supérieurs). –

Répondre

2

seulement des enregistrements avec deux ou dossiers avec un et deux.

Jetez un oeil ici et faites le moi savoir.

DECLARE @Master TABLE(
     MasterRecordID VARCHAR(20) 
) 

INSERT INTO @Master (MasterRecordID) VALUES ('MASTER1') 
INSERT INTO @Master (MasterRecordID) VALUES ('MASTER2') 
INSERT INTO @Master (MasterRecordID) VALUES ('MASTER3') 
INSERT INTO @Master (MasterRecordID) VALUES ('MASTER4') 

DECLARE @MasterDetail TABLE(
     MasterRecordID VARCHAR(20), 
     MasterDetailRecord VARCHAR(50) 
) 

INSERT INTO @MasterDetail (MasterRecordID,MasterDetailRecord) VALUES ('MASTER4','MASTERDETAIL10') 

INSERT INTO @MasterDetail (MasterRecordID,MasterDetailRecord) VALUES ('MASTER3','MASTERDETAIL09') 
INSERT INTO @MasterDetail (MasterRecordID,MasterDetailRecord) VALUES ('MASTER3','MASTERDETAIL08') 
INSERT INTO @MasterDetail (MasterRecordID,MasterDetailRecord) VALUES ('MASTER3','MASTERDETAIL07') 

INSERT INTO @MasterDetail (MasterRecordID,MasterDetailRecord) VALUES ('MASTER2','MASTERDETAIL06') 
INSERT INTO @MasterDetail (MasterRecordID,MasterDetailRecord) VALUES ('MASTER2','MASTERDETAIL05') 
INSERT INTO @MasterDetail (MasterRecordID,MasterDetailRecord) VALUES ('MASTER2','MASTERDETAIL04') 

INSERT INTO @MasterDetail (MasterRecordID,MasterDetailRecord) VALUES ('MASTER1','MASTERDETAIL03') 
INSERT INTO @MasterDetail (MasterRecordID,MasterDetailRecord) VALUES ('MASTER1','MASTERDETAIL02') 
INSERT INTO @MasterDetail (MasterRecordID,MasterDetailRecord) VALUES ('MASTER1','MASTERDETAIL01') 

DECLARE @MaxRecords INT 
SELECT @MaxRecords = 2 

SELECT md.MasterRecordID, 
     md.MasterDetailRecord 
FROM @MasterDetail md INNER JOIN 
     --this section ensures that we only return master records with at least MaxRecords as specified (2 in your case) 
     --if you wish to display al master records, with 1, 2 or MaxRecords, romove this section or see below 
     (
      SELECT MasterRecordID 
      FROM @MasterDetail 
      GROUP BY MasterRecordID 
      HAVING COUNT(MasterRecordID) >= @MaxRecords 
     ) NumberOfRecords ON md.MasterRecordID = NumberOfRecords.MasterRecordID INNER JOIN 
     @MasterDetail mdSmaller ON md.MasterRecordID = mdSmaller.MasterRecordID 
WHERE mdSmaller.MasterDetailRecord <= md.MasterDetailRecord 
GROUP BY md.MasterRecordID, 
      md.MasterDetailRecord 
HAVING COUNT(mdSmaller.MasterDetailRecord) <= @MaxRecords 
ORDER BY md.MasterRecordID, 
      md.MasterDetailRecord 



SELECT md.MasterRecordID, 
     md.MasterDetailRecord 
FROM @MasterDetail md INNER JOIN 
     --this will ensure that all master records will return with 1, 2 or MaxRecords 
     @MasterDetail mdSmaller ON md.MasterRecordID = mdSmaller.MasterRecordID 
WHERE mdSmaller.MasterDetailRecord <= md.MasterDetailRecord 
GROUP BY md.MasterRecordID, 
      md.MasterDetailRecord 
HAVING COUNT(mdSmaller.MasterDetailRecord) <= @MaxRecords 
ORDER BY md.MasterRecordID, 
      md.MasterDetailRecord 

Hope qui aide

0

Je n'ai pas le temps d'écrire la requête complète maintenant, mais ce que vous faites est de commencer par la table principale et de rejoindre deux fois la table de détails. La première jointure doit correspondre à l'enregistrement supérieur (où le nombre de ces lesser = 0, pour votre définition particulière de 'lesser') pour chaque enregistrement, et le second joint doit correspondre au second enregistrement (où le nombre de ces lesser = 1).

Mise à jour
Comme je pense, vous devrez faire un syndicat pour obtenir votre dossier supplémentaire (écrire toujours le même rejoindre, mais dans une requête de sélection complètement séparée que vous incluez dans les résultats via l'union). Sinon, vous devez renvoyer votre sortie avec les première et seconde clés de détail dans le même enregistrement.

3

Essayez ceci:

WITH cteCount as 
(
    Select 
     ROW_NUMBER() OVER(PARTITION BY MRecord ORDER BY MR_DETAIL_COLUMN) as TopCnt, 
     MR_DETAIL_COLUMN 
    FROM MASTER_DETAIL_TABLE 
) 
SELECT 
     * 
FROM MASTER_TABLE as MT 
JOIN cteCount as MDT ON MDT.MRecord = MT.MRecord 
WHERE TopCnt <= 2 

Edit: corriger typo orthographe

Edit: Je ne sais pas si vous vouliez corriger des erreurs vraiment stupide

+0

Je reçois cette erreur Msg 102, niveau 15, état 1, ligne 3 Syntaxe incorrecte près de 'PARTITON'. –

+0

La partition a été mal orthographiée. – RBarryYoung

+1

@RBarryYoung Est-ce censé fonctionner tel quel? J'essaie juste de comprendre pour mes besoins.Comment la deuxième requête est-elle informée de topcnt dans cteCount? La virgule est-elle manquante dans la première requête? – MicMit

Questions connexes