sql 服务器中的随机记录和顺序记录
Shuffle records and sequential records in sql server
我写了一个 SQL 查询,其中 returns 我使用 NEWID() 打乱了数据
在 SQL 服务器 2012 中。
场景:
我有一个 table,其中我们在 table - "tblquest" 中有问题,而在 "tblquestLinked" table 中,我们有一个与 table 中的主要问题相关的链接问题=39=] table,
现在下面的查询可以正确输出打乱后的数据。
select ROW_NUMBER() Over (Order by newid()) as sNo,*
from (select q.ID AS [QID], q.Question,
q.Solution,
isnull(q.IsLinked,0) as IsLinked, ql.LinkQuestion
from tblquest q
left join tblQuestLinked ql
on q.ID = ql.QID) a
我希望查询返回的数据集也应该有一个链接问题,但不应该被打乱,而是应该是链接 "main" 问题的下一行。
编辑
由于这些问题将提交给在线考试申请,因此必须对问题进行洗牌。
一个主要问题可以有 0 到多个链接问题。
链接的问题出现在相应“主要”问题的下一行。
因为这将传递给 UI 并且它将根据 sNO ( 序列号)
提供问题
请找截图(想要的结果):
架构脚本:
CREATE TABLE [dbo].[tblQuest](
[ID] [int] IDENTITY(1,1) NOT NULL,
[IsLinked] [bit] NULL,
[Question] [nvarchar](500) NULL,
[Solution] [nvarchar](500) NULL,
CONSTRAINT [PK_tblQuest] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
)
GO
CREATE TABLE [dbo].[tblQuestLinked](
[ID] [int] IDENTITY(1,1) NOT NULL,
[QID] [int] NULL,
[LinkQuestion] [nvarchar](max) NULL,
[CreatedDate] [datetime] NULL,
CONSTRAINT [PK_tblQuestLinked] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
)
GO
INSERT [dbo].[tblQuest] ([IsLinked], [Question], [Solution]) VALUES (0, N'Which of ... 1 ', 'Solution 1 ... ')
INSERT [dbo].[tblQuest] ([IsLinked], [Question], [Solution]) VALUES (0, N'Which of ... 2 ', 'Solution 2 ... ')
INSERT [dbo].[tblQuest] ([IsLinked], [Question], [Solution]) VALUES (0, N'Which of ... 3 ', 'Solution 3 ... ')
INSERT [dbo].[tblQuest] ([IsLinked], [Question], [Solution]) VALUES (0, N'Which of ... 4 ', 'Solution 4 ... ')
INSERT [dbo].[tblQuest] ([IsLinked], [Question], [Solution]) VALUES (0, N'Which of ... 5 ', 'Solution 5 ... ')
INSERT [dbo].[tblQuest] ([IsLinked], [Question], [Solution]) VALUES (0, N'Which of ... 6 ', 'Solution 6 ... ')
INSERT [dbo].[tblQuest] ([IsLinked], [Question], [Solution]) VALUES (1, N'Which of ... 7 ', 'Solution 7 ... ')
INSERT [dbo].[tblQuestLinked] ( [QID], [LinkQuestion]) VALUES (7, N'LINKED Q : SUB LINKED')
假设没有根问题就不可能有任何链接问题,您可以简单地 select 两个表中的所有记录并将它们与 UNION ALL
粘合在一起。然后我们首先要根据它们共有的 ID 进行排序。但只是按 qid 排序,newid() 实际上会按 ID 排序,而不是随机排序。所以我们需要一个随机函数,它接受 ID 并根据它给我们一个确定的 "random" 值:RAND(qid)
。但是,这仍然会在每次执行时给我们相同的顺序,所以我们添加一个随机发生器:
ORDER BY rand(rand(convert(int, getdate())) - qid)
它表明 SQL 服务器的 RAND
在播种方面有点缺陷(请参阅我对此的评论)。这对我有用:
ORDER BY rand((datepart(mm, getdate()) * 100000) +
(datepart(ss, getdate()) * 1000) +
datepart(ms, getdate()) ^ qid)
由于两个不同的种子仍然可以产生相同的随机数,因此我们需要向其添加 , qid
,以确保两个链接的条目在一起。此外,我们添加 , islinked desc
以获得链接问题之前的问题。
整个查询:
select qid, question, solution, islinked
from
(
select
id as qid,
question,
solution,
isnull(islinked, 0) as islinked,
id as linkkey
from tblquest
union all
select
id as qid,
linkquestion as question,
null as solution,
0 as islinked,
qid as linkkey
from tblquestlinked
) both
order by rand((datepart(mm, getdate()) * 100000) +
(datepart(ss, getdate()) * 1000) +
datepart(ms, getdate()) ^ qid), qid, islinked desc;
SQL fiddle: http://sqlfiddle.com/#!3/476fd/2
如果我没有理解错的话,您希望链接问题始终位于主要问题之下。这是一种方法:
select
q.id, case when Type = 0 then Question else LinkQuestion end, Solution
from
(
select row_number() over (order by newid()) as ORD, *
from tblQuest q
) q
outer apply (
select 0 as Type, 0 as QID, convert(varchar(max), NULL) as LinkQuestion
union all
select 1, QID, l.LinkQuestion
from tblQuestLinked l where q.ID = l.QID
) x
order by q.ORD, x.Type, x.QID
中的示例
我写了一个 SQL 查询,其中 returns 我使用 NEWID() 打乱了数据 在 SQL 服务器 2012 中。
场景: 我有一个 table,其中我们在 table - "tblquest" 中有问题,而在 "tblquestLinked" table 中,我们有一个与 table 中的主要问题相关的链接问题=39=] table, 现在下面的查询可以正确输出打乱后的数据。
select ROW_NUMBER() Over (Order by newid()) as sNo,*
from (select q.ID AS [QID], q.Question,
q.Solution,
isnull(q.IsLinked,0) as IsLinked, ql.LinkQuestion
from tblquest q
left join tblQuestLinked ql
on q.ID = ql.QID) a
我希望查询返回的数据集也应该有一个链接问题,但不应该被打乱,而是应该是链接 "main" 问题的下一行。
编辑
由于这些问题将提交给在线考试申请,因此必须对问题进行洗牌。
一个主要问题可以有 0 到多个链接问题。 链接的问题出现在相应“主要”问题的下一行。 因为这将传递给 UI 并且它将根据 sNO ( 序列号)
提供问题请找截图(想要的结果):
架构脚本:
CREATE TABLE [dbo].[tblQuest](
[ID] [int] IDENTITY(1,1) NOT NULL,
[IsLinked] [bit] NULL,
[Question] [nvarchar](500) NULL,
[Solution] [nvarchar](500) NULL,
CONSTRAINT [PK_tblQuest] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
)
GO
CREATE TABLE [dbo].[tblQuestLinked](
[ID] [int] IDENTITY(1,1) NOT NULL,
[QID] [int] NULL,
[LinkQuestion] [nvarchar](max) NULL,
[CreatedDate] [datetime] NULL,
CONSTRAINT [PK_tblQuestLinked] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
)
GO
INSERT [dbo].[tblQuest] ([IsLinked], [Question], [Solution]) VALUES (0, N'Which of ... 1 ', 'Solution 1 ... ')
INSERT [dbo].[tblQuest] ([IsLinked], [Question], [Solution]) VALUES (0, N'Which of ... 2 ', 'Solution 2 ... ')
INSERT [dbo].[tblQuest] ([IsLinked], [Question], [Solution]) VALUES (0, N'Which of ... 3 ', 'Solution 3 ... ')
INSERT [dbo].[tblQuest] ([IsLinked], [Question], [Solution]) VALUES (0, N'Which of ... 4 ', 'Solution 4 ... ')
INSERT [dbo].[tblQuest] ([IsLinked], [Question], [Solution]) VALUES (0, N'Which of ... 5 ', 'Solution 5 ... ')
INSERT [dbo].[tblQuest] ([IsLinked], [Question], [Solution]) VALUES (0, N'Which of ... 6 ', 'Solution 6 ... ')
INSERT [dbo].[tblQuest] ([IsLinked], [Question], [Solution]) VALUES (1, N'Which of ... 7 ', 'Solution 7 ... ')
INSERT [dbo].[tblQuestLinked] ( [QID], [LinkQuestion]) VALUES (7, N'LINKED Q : SUB LINKED')
假设没有根问题就不可能有任何链接问题,您可以简单地 select 两个表中的所有记录并将它们与 UNION ALL
粘合在一起。然后我们首先要根据它们共有的 ID 进行排序。但只是按 qid 排序,newid() 实际上会按 ID 排序,而不是随机排序。所以我们需要一个随机函数,它接受 ID 并根据它给我们一个确定的 "random" 值:RAND(qid)
。但是,这仍然会在每次执行时给我们相同的顺序,所以我们添加一个随机发生器:
ORDER BY rand(rand(convert(int, getdate())) - qid)
它表明 SQL 服务器的 RAND
在播种方面有点缺陷(请参阅我对此的评论)。这对我有用:
ORDER BY rand((datepart(mm, getdate()) * 100000) +
(datepart(ss, getdate()) * 1000) +
datepart(ms, getdate()) ^ qid)
由于两个不同的种子仍然可以产生相同的随机数,因此我们需要向其添加 , qid
,以确保两个链接的条目在一起。此外,我们添加 , islinked desc
以获得链接问题之前的问题。
整个查询:
select qid, question, solution, islinked
from
(
select
id as qid,
question,
solution,
isnull(islinked, 0) as islinked,
id as linkkey
from tblquest
union all
select
id as qid,
linkquestion as question,
null as solution,
0 as islinked,
qid as linkkey
from tblquestlinked
) both
order by rand((datepart(mm, getdate()) * 100000) +
(datepart(ss, getdate()) * 1000) +
datepart(ms, getdate()) ^ qid), qid, islinked desc;
SQL fiddle: http://sqlfiddle.com/#!3/476fd/2
如果我没有理解错的话,您希望链接问题始终位于主要问题之下。这是一种方法:
select
q.id, case when Type = 0 then Question else LinkQuestion end, Solution
from
(
select row_number() over (order by newid()) as ORD, *
from tblQuest q
) q
outer apply (
select 0 as Type, 0 as QID, convert(varchar(max), NULL) as LinkQuestion
union all
select 1, QID, l.LinkQuestion
from tblQuestLinked l where q.ID = l.QID
) x
order by q.ORD, x.Type, x.QID
中的示例