我有表1 - 比方说 - 10K记录。
我使用的是
ROW_NUMBER() OVER(BATCH_ID) as ROWLIST
获取行号
我需要的是:对于第一个1K行运行,让我们说(我将运行存储过程,由于CPU / RAM要求和限制,我需要一次运行x行数)< / p>
INSERT INTO dbo.[tbl_sub]
SELECT CIN
FROM tbl_Main
并且对于下一个1K行运行相同的事情。直到记录集(或rowcount)结束。
所以基本上将一个包含X个记录的表分成行,然后按X行数运行一个特定的代码。
这里的代码是一些令人敬畏的解决方案!我很难在这段代码中实现它:
CREATE TABLE [LTAC_TEST_1](
[CLAIM_ID] [nvarchar](15) NULL,
[CIN] [nvarchar](10) NULL,
[SVC_DATE] [datetime] NULL,
[SVC_DATE_TO] [datetime] NULL,
[TOTAL_DAYS] [int] NULL,
[CHAIN_COUNT] [int] NULL
) ON [PRIMARY]
;WITH chain_builder AS
(
SELECT ROW_NUMBER() OVER(ORDER BY s.CIN, s.CLAIM_ID) as chain_ID,
s.CIN,
s.SVC_DATE, s.SVC_DATE_TO, s.CLAIM_ID, 1 as chain_count
FROM [LTAC_FINBASE_BASE2] s
WHERE s.SVC_DATE <> ALL
(
SELECT DATEADD(d, 1, s2.SVC_DATE_TO)
FROM [LTAC_FINBASE_BASE2] s2
WHERE s.CIN = s2.CIN
)
UNION ALL
SELECT chain_ID, s.CIN, s.SVC_DATE, s.SVC_DATE_TO,
s.CLAIM_ID, chain_count + 1
FROM [LTAC_FINBASE_BASE2] s
JOIN chain_builder as c
ON s.CIN = c.CIN AND
s.SVC_DATE = DATEADD(d, 1, c.SVC_DATE_TO)
),
chains AS
(
SELECT chain_ID, CIN, SVC_DATE, SVC_DATE_TO,
CLAIM_ID, chain_count, ROW_NUMBER() OVER(PARTITION BY chain_ID, chain_count ORDER BY SVC_DATE_TO DESC) as link_row
FROM chain_builder
),
link_picker AS
(
SELECT chain_ID, CIN, SVC_DATE, SVC_DATE_TO,
CLAIM_ID, chain_count
FROM chains
WHERE link_row = 1
),
diff AS
(
SELECT c.chain_ID, c.CIN, c.SVC_DATE, c.SVC_DATE_TO,
c.CLAIM_ID, c.chain_count,
datediff(day,c.SVC_DATE,c.SVC_DATE_TO)+1 daysdiff
FROM link_picker c
),
diff_sum AS
(
SELECT chain_ID, CIN, SVC_DATE, SVC_DATE_TO,
CLAIM_ID, chain_count,
SUM(daysdiff) OVER (PARTITION BY chain_ID) as total_diff
FROM diff
),
diff_comp AS
(
SELECT chain_ID, CIN,
MAX(total_diff) OVER (PARTITION BY CIN) as total_diff
FROM diff_sum
)
INSERT INTO [LTAC_TEST_1]
SELECT DISTINCT ds.CLAIM_ID, ds.CIN, ds.SVC_DATE,
ds.SVC_DATE_TO, ds.total_diff as TOTAL_DAYS, ds.chain_count as CHAIN_COUNT
FROM diff_sum ds
JOIN diff_comp dc
ON ds.chain_ID = dc.chain_ID AND ds.CIN = dc.CIN
AND ds.total_diff = dc.total_diff
OPTION (maxrecursion 0)
答案 0 :(得分:0)
有多种方法可以做到这一点,这里有一个解决方案 - 并不是说效率最高:
假设您希望将所有行从tbl_Main移动到tbl_sub WHILE EXISTS
语句,请继续我们的LOOP
,前提是我们仍然在tbl_Main中显示尚不存在的值(NOT EXISTS
)在tbl_sub。
每次迭代将按BATCH_ID的顺序插入1000行,直到完成。在上面的示例中,不清楚为什么使用ROW_NUMBER()
窗口函数,因为您尚未指定该列是PARTITION BY
还是ORDER BY
而您可能不需要它。
WHILE EXISTS
(
SELECT
*
FROM
tbl_Main
WHERE
NOT EXISTS
(
SELECT *
FROM dbo.tbl_sub
WHERE CIN = tbl_Main.CIN
)
)
BEGIN
INSERT INTO dbo.tbl_sub
(
CIN
)
SELECT TOP 1000
CIN
FROM
tbl_Main
WHERE
NOT EXISTS
(
SELECT *
FROM dbo.tbl_sub
WHERE CIN = tbl_Main.CIN
)
ORDER BY
BATCH_ID
END
答案 1 :(得分:0)
一种方法是创建一个临时表,其中包含具有标识号(从0开始)的所有键值和两个将该标识号转换为BatchID和(0到999)之间的批号的计算列
CREATE TABLE #t
(
id int identity (0,1),
BatchID as ([id]/10),
BatchNumber as ([id]%10),
KeyColumn varchar(50)
)
INSERT INTO #t(KeyColumn)
SELECT KeyColumn FROM [DataTable_t]
然后,您可以循环遍历BatchID的所有值,并使用该组1000条记录执行您需要的任何操作
--Subquery to return a batch of 1000 records
(SELECT d.*
FROM #t t
JOIN DataTable_t] d
ON d.KeyColumn = t.KeyColumn
WHERE t.BatchID = @BatchID ) AS Batch
我不确定你的情况是否有用
答案 2 :(得分:0)
我会创建一个运行此
的存储过程DECLARE @RowsAffected INT =1
While(@RowsAffected<>0)
BEGIN
INSERT INTO dbo.[tbl_sub]
SELECT TOP 1000
tbl_Main.CIN
FROM tbl_Main
left join dbo.[tbl_sub] t2 on t2.CIN=tbl_Main.CIN
WHERE t2.CIN IS NULL
SET @RowsAffected=@@Rowcount
END