仅使用SQL查询显示主/主 - 详细信息表中的记录

时间:2009-07-06 03:34:28

标签: sql-server-2005 sql

我遇到了一个问题,我已经使用T-SQL(游标和循环)解决了这个问题。(SQL server 2005)

但我正在寻找使用SQL的解决方案。

我有一个主表,其中一列表示MasterRecord(所有都是唯一的,并且类型为Varchar和PK)

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

现在,Master-Detail表有两列MasterRecord(Varchar& FK)和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

其中[n]可以是任何数字

问题在于,对于每个唯一的主记录,我应该获取前2个详细记录

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

希望我清楚地解释了我的问题。

请告知我们进一步说明。

3 个答案:

答案 0 :(得分:3)

试试这个:

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

编辑:更正的拼写错误

编辑:纠正真正的愚蠢错误

答案 1 :(得分:2)

不确定您是否只想要带有两个记录或带有一个和两个记录的记录。

看看这里,让我知道。

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

希望有所帮助

答案 2 :(得分:0)

我现在没有时间写出完整的查询,但你要做的是从主表开始并加入详细信息表两次。对于每个主记录,第一个连接应匹配顶部记录(其中较小的计数= 0,对于您的特定定义'较小'),第二个连接应与第二个记录匹配(其中较小的计数= 1) )。

<强>更新
在我考虑它时,你必须做一个联合以获得你的额外记录(仍然写相同的连接,但是在你通过union包含在结果中的完全独立的选择查询中)。否则,您必须使用同一记录中的第一个和第二个详细信息键返回输出。