每组[日期]删除随机记录[0-4个删除]
Delete random records [0-4 deletions] per group [date]
我需要为演示文稿创建虚拟数据。
我得到了 10 条记录,我需要复制它们并在每个月的每一天每次更改它们的日期。然后我需要删除每个日期的随机记录,每天从 0 到 4 条记录不等(因此它们看起来更随机)
一个简化的例子
dummyId Name onDate
1 xd 2016-07-01
2 gd 2016-07-01
3 yd 2016-07-01
4 ad 2016-07-01
5 bd 2016-07-01
6 zd 2016-07-01
7 md 2016-07-01
8 qd 2016-07-01
9 nd 2016-07-01
10 dd 2016-07-01
11 xd 2016-07-02
12 gd 2016-07-02
13 yd 2016-07-02
14 ad 2016-07-02
15 bd 2016-07-02
16 zd 2016-07-02
17 md 2016-07-02
18 qd 2016-07-02
19 nd 2016-07-02
20 dd 2016-07-02
..
在上面的例子中,7 月 1 日的记录被复制到 7 月 2 日。这将持续到每个七月的日期。之后,我需要从每组日期中删除 [7 月 1 日除外](按日期分组)0-4 条记录,以便数据看起来是随机的。
例如,7 月 2 日删除了以下 3 条记录
dummyId Name onDate
1 xd 2016-07-01
2 gd 2016-07-01
3 yd 2016-07-01
4 ad 2016-07-01
5 bd 2016-07-01
6 zd 2016-07-01
7 md 2016-07-01
8 qd 2016-07-01
9 nd 2016-07-01
10 dd 2016-07-01
11 xd 2016-07-02
13 yd 2016-07-02
14 ad 2016-07-02
16 zd 2016-07-02
17 md 2016-07-02
18 qd 2016-07-02
20 dd 2016-07-02
..
如果需要删除0-4条记录,可以使用随机数。这很痛苦,但在 SQL 服务器中你可以这样做:
delete s
from simplified s
where onDate <> '2016-07-01' and
rand(checksum(newid())) < 0.15;
这将删除大约 15% 的记录。这应该是每个日期的 1-4 条记录(尽管不能保证每个日期的确切数量)。
为每个日期删除固定数字的另一种方法是。例如,return 每个日期的三个记录:
with todelete as (
select s.*, row_number() over (partition by date order by newid()) as seqnum
from simplified s
)
delete todelete
where seqnum <= 3 and onDate <> '2016-07-01';
一种方法是为每个日期的记录创建一个 cte that will generate a random number for each record and a row number 随机排序:
创建并填充样本 table(请在下一个问题中省去这一步):
DECLARE @T as table
(
dummyId int,
Name char(2),
onDate date
)
INSERT INTO @T VALUES
(1, 'xd', '2016-07-01'),
(2, 'gd', '2016-07-01'),
(3, 'yd', '2016-07-01'),
(4, 'ad', '2016-07-01'),
(5, 'bd', '2016-07-01'),
(6, 'zd', '2016-07-01'),
(7, 'md', '2016-07-01'),
(8, 'qd', '2016-07-01'),
(9, 'nd', '2016-07-01'),
(10, 'dd', '2016-07-01'),
(11, 'xd', '2016-07-02'),
(12, 'gd', '2016-07-02'),
(13, 'yd', '2016-07-02'),
(14, 'ad', '2016-07-02'),
(15, 'bd', '2016-07-02'),
(16, 'zd', '2016-07-02'),
(17, 'md', '2016-07-02'),
(18, 'qd', '2016-07-02'),
(19, 'nd', '2016-07-02'),
(20, 'dd', '2016-07-02')
创建一个cte。请注意,它包含一个介于 0 到 5(含)之间的随机数,以及每个日期的 1 到 10 之间的行号,随机排序:
;WITH CTE AS
(
SELECT dummyId,
Name,
onDate,
ABS(CHECKSUM(NEWID()) % 6) as random,
ROW_NUMBER() OVER(PARTITION BY onDate ORDER BY NEWID()) As rowNumber
FROM @T
WHERE onDate <> '2016-07-01'
)
从cte中删除。请注意,where 子句正在检查随机数是否小于行号。 where 子句确保对于每个日期,将删除随机数的 0 到 4 条记录:
DELETE
FROM CTE
WHERE rowNumber < random
我需要为演示文稿创建虚拟数据。
我得到了 10 条记录,我需要复制它们并在每个月的每一天每次更改它们的日期。然后我需要删除每个日期的随机记录,每天从 0 到 4 条记录不等(因此它们看起来更随机)
一个简化的例子
dummyId Name onDate
1 xd 2016-07-01
2 gd 2016-07-01
3 yd 2016-07-01
4 ad 2016-07-01
5 bd 2016-07-01
6 zd 2016-07-01
7 md 2016-07-01
8 qd 2016-07-01
9 nd 2016-07-01
10 dd 2016-07-01
11 xd 2016-07-02
12 gd 2016-07-02
13 yd 2016-07-02
14 ad 2016-07-02
15 bd 2016-07-02
16 zd 2016-07-02
17 md 2016-07-02
18 qd 2016-07-02
19 nd 2016-07-02
20 dd 2016-07-02
..
在上面的例子中,7 月 1 日的记录被复制到 7 月 2 日。这将持续到每个七月的日期。之后,我需要从每组日期中删除 [7 月 1 日除外](按日期分组)0-4 条记录,以便数据看起来是随机的。
例如,7 月 2 日删除了以下 3 条记录
dummyId Name onDate
1 xd 2016-07-01
2 gd 2016-07-01
3 yd 2016-07-01
4 ad 2016-07-01
5 bd 2016-07-01
6 zd 2016-07-01
7 md 2016-07-01
8 qd 2016-07-01
9 nd 2016-07-01
10 dd 2016-07-01
11 xd 2016-07-02
13 yd 2016-07-02
14 ad 2016-07-02
16 zd 2016-07-02
17 md 2016-07-02
18 qd 2016-07-02
20 dd 2016-07-02
..
如果需要删除0-4条记录,可以使用随机数。这很痛苦,但在 SQL 服务器中你可以这样做:
delete s
from simplified s
where onDate <> '2016-07-01' and
rand(checksum(newid())) < 0.15;
这将删除大约 15% 的记录。这应该是每个日期的 1-4 条记录(尽管不能保证每个日期的确切数量)。
为每个日期删除固定数字的另一种方法是。例如,return 每个日期的三个记录:
with todelete as (
select s.*, row_number() over (partition by date order by newid()) as seqnum
from simplified s
)
delete todelete
where seqnum <= 3 and onDate <> '2016-07-01';
一种方法是为每个日期的记录创建一个 cte that will generate a random number for each record and a row number 随机排序:
创建并填充样本 table(请在下一个问题中省去这一步):
DECLARE @T as table
(
dummyId int,
Name char(2),
onDate date
)
INSERT INTO @T VALUES
(1, 'xd', '2016-07-01'),
(2, 'gd', '2016-07-01'),
(3, 'yd', '2016-07-01'),
(4, 'ad', '2016-07-01'),
(5, 'bd', '2016-07-01'),
(6, 'zd', '2016-07-01'),
(7, 'md', '2016-07-01'),
(8, 'qd', '2016-07-01'),
(9, 'nd', '2016-07-01'),
(10, 'dd', '2016-07-01'),
(11, 'xd', '2016-07-02'),
(12, 'gd', '2016-07-02'),
(13, 'yd', '2016-07-02'),
(14, 'ad', '2016-07-02'),
(15, 'bd', '2016-07-02'),
(16, 'zd', '2016-07-02'),
(17, 'md', '2016-07-02'),
(18, 'qd', '2016-07-02'),
(19, 'nd', '2016-07-02'),
(20, 'dd', '2016-07-02')
创建一个cte。请注意,它包含一个介于 0 到 5(含)之间的随机数,以及每个日期的 1 到 10 之间的行号,随机排序:
;WITH CTE AS
(
SELECT dummyId,
Name,
onDate,
ABS(CHECKSUM(NEWID()) % 6) as random,
ROW_NUMBER() OVER(PARTITION BY onDate ORDER BY NEWID()) As rowNumber
FROM @T
WHERE onDate <> '2016-07-01'
)
从cte中删除。请注意,where 子句正在检查随机数是否小于行号。 where 子句确保对于每个日期,将删除随机数的 0 到 4 条记录:
DELETE
FROM CTE
WHERE rowNumber < random