我在这里发布了一个类似的问题: Shuffle column values per row
Pரதீப்给出的查询是这样的:
WHILE 1 = 1
BEGIN
DECLARE @answer SYSNAME = (SELECT TOP 1 COLUMN_NAME
FROM INFORMATION_SCHEMA.columns
WHERE TABLE_NAME = 'yourtable' AND COLUMN_NAME NOT IN ( 'question', 'answer')
ORDER BY Newid())
DECLARE @distractor1 SYSNAME = (SELECT TOP 1 COLUMN_NAME
FROM INFORMATION_SCHEMA.columns
WHERE TABLE_NAME = 'yourtable' AND COLUMN_NAME NOT IN ( 'question', @answer, 'distractor1' )
ORDER BY Newid())
DECLARE @distractor2 SYSNAME = (SELECT TOP 1 COLUMN_NAME
FROM INFORMATION_SCHEMA.columns
WHERE TABLE_NAME = 'yourtable' AND COLUMN_NAME NOT IN ( 'question', @answer, 'distractor2', @distractor1 )
ORDER BY Newid())
DECLARE @distractor3 SYSNAME = (SELECT TOP 1 COLUMN_NAME
FROM INFORMATION_SCHEMA.columns
WHERE TABLE_NAME = 'yourtable' AND COLUMN_NAME NOT IN ( 'question', @answer, 'distractor3', @distractor2, @distractor1 )
ORDER BY Newid())
IF @distractor1 IS NOT NULL
AND @distractor2 IS NOT NULL
AND @distractor3 IS NOT NULL
AND @answer IS NOT NULL
BREAK
END
--select @distractor1,@distractor2,@distractor3
exec( 'update yourtable set answer = '+@answer+', distractor1 = '+@distractor1+', distractor2 = '+@distractor2+', distractor3 = '+@distractor3)
select * from yourtable

有效。但是,它看起来像这样:https://prnt.sc/hwraqa
查询中出现了一种模式。无论第一行的顺序如何,下一行也将具有相同的顺序。我想要发生的是这样的事情:
-----------------------------------------------------
|question|answer|distractor1|distractor2|distractor3|
|q1 |d3q1 |d2q1 |d1q1 |ansq1 |
|q2 |d1q2 |d3q3 |ansq2 |d2q2 |
|q3 |ansq3 |d1q3 |d3q3 |d2q3 |
-----------------------------------------------------
每一行都应该有一个独特的顺序并且被洗牌。
答案 0 :(得分:1)
问题的根源是非规范化数据结构。您应该将答案存储在单独的表格中,这样可以更容易随机化答案的顺序。
-- sample data
declare @questions table (
question varchar(10),
answer varchar(10),
distractor1 varchar(10),
distractor2 varchar(10),
distractor3 varchar(10)
)
insert @questions
select 'q1','a1','d11','d12','d13'
union all select 'q2','a2','d21','d22','d23'
union all select 'q3','a3','d31','d32','d33'
select results.*, q.answer
from
(
select question, response, row_number() over (partition by question order by newid()) rn
from
(
select question, answerType, response
from @questions
unpivot (answerType for response in (distractor1, distractor2, distractor3)) u
union all
select question, 'answer', answer as answerorder from @questions
) normalised -- the answers in a normalised form
) randomised -- randomise the order
pivot (max(response) for rn in ([1],[2],[3],[4])) results
inner join @questions q on results.question = q.question
答案 1 :(得分:1)
这是一种做法。 Demo
它类似于podiluska的答案,但更简单,因为它仅适用于随机化,非透视和旋转到当前行中的值。
UPDATE YourTable
SET answer = CA.[1],
distractor1 = CA.[2],
distractor2 = CA.[3],
distractor3 = CA.[4]
FROM YourTable
CROSS APPLY (SELECT *
FROM (SELECT x,
ROW_NUMBER() OVER (ORDER BY CRYPT_GEN_RANDOM(4)) AS rn
FROM (VALUES(answer),
(distractor1),
(distractor2),
(distractor3)) V(x)) ps
PIVOT (MAX(x) FOR rn IN ([1], [2], [3], [4])) p) CA
注意:我假设您正在根据您之前链接的问题寻找UPDATE
声明。如果您需要SELECT
,只需将UPDATE YourTable
SET
替换为SELECT question,
- demo
答案 2 :(得分:0)
您的问题有点广泛且难以回答。回答它有点长,但它是:
1)表的准备 - 首先你已经,这是源表,但我们还需要目标表(毕竟你可以清除旧表并填充新表中的值):
create table #Q_and_A(
question char(2),
answer varchar(5),
distractor1 varchar(5),
distractor2 varchar(5),
distractor3 varchar(5)
)
create table #Q_and_A_shuffled(
question char(2),
answer varchar(5),
distractor1 varchar(5),
distractor2 varchar(5),
distractor3 varchar(5)
)
insert into #Q_and_A values
('q1','ansq1', 'd1q1', 'd2q1', 'd3q1'),
('q2','ansq2', 'd1q2', 'd2q2', 'd3q2'),
('q3','ansq3', 'd1q3', 'd2q3', 'd3q3')
2)有了这个,我们可以从一些程序开始随意洗牌。为此,我们需要列出所有列的名称组合,因此我们会这样做:
declare @ColumnCombination table (col varchar(20))
insert into @ColumnCombination values ('answer'),('distractor1'),('distractor2'),('distractor3')
现在,查询:
select top 1 @insertQuery = 'insert into #Q_and_A_shuffled select question,' + Combinations + ' from #Q_and_A where question = ''' + @qst + '''' from (
select CC1.col + ',' + CC2.col + ',' + CC3.col + ',' + CC4.col Combinations from @ColumnCombination CC1
cross join @ColumnCombination CC2 cross join @ColumnCombination CC3 cross join @ColumnCombination CC4
where CC1.col <> CC2.col and CC1.col <> CC3.col and CC1.col <> CC4.col and
CC2.col <> CC3.col and CC2.col <> CC4.col and CC3.col <> CC4.col
) as a order by newid()
将返回单个SQL insert语句,该语句将特定问题(变量@qst
)的混洗行插入到新表中。
将所有这些考虑因素放在一起,我们获得:
declare @cnt int, @i int, @qst char(2), @insertQuery nvarchar(1000)
set @i = 1
select @cnt = count(*) from #Q_and_A
declare @ColumnCombination table (col varchar(20))
insert into @ColumnCombination values ('answer'),('distractor1'),('distractor2'),('distractor3')
while @i <= @cnt
begin
set @qst = 'q' + cast(@i as varchar(2))
select top 1 @insertQuery = 'insert into #Q_and_A_shuffled select question,' + Combinations + ' from #Q_and_A where question = ''' + @qst + '''' from (
select CC1.col + ',' + CC2.col + ',' + CC3.col + ',' + CC4.col Combinations from @ColumnCombination CC1
cross join @ColumnCombination CC2 cross join @ColumnCombination CC3 cross join @ColumnCombination CC4
where CC1.col <> CC2.col and CC1.col <> CC3.col and CC1.col <> CC4.col and
CC2.col <> CC3.col and CC2.col <> CC4.col and CC3.col <> CC4.col
) as a order by newid()
exec sp_executesql @insertQuery
set @i = @i + 1
end
select * from #Q_and_A
select * from #Q_and_A_shuffled
示例结果: