我遇到了一个问题,我已经使用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
希望我清楚地解释了我的问题。
请告知我们进一步说明。
答案 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包含在结果中的完全独立的选择查询中)。否则,您必须使用同一记录中的第一个和第二个详细信息键返回输出。