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 Fiddle

中的示例