随机化,同时在组内保持上升

Randomise while keeping ascending inside the group

提问人:Hanericka 提问时间:11/16/2023 最后编辑:Thom AHanericka 更新时间:11/17/2023 访问量:147

问:

我有三个主要表格,如下所示:

SELECT
    Q.QPackID, Q.QGrpID, Q.QID
FROM
    dbo.SV_Q AS Q 
LEFT OUTER JOIN
    dbo.SV_Q_Pack AS P ON Q.QPackID = P.QPackID 
LEFT OUTER JOIN
    dbo.SV_QGrp AS G ON Q.QGrpID = G.QGrpID 
LEFT OUTER JOIN
    dbo.SV_QM AS M ON Q.QmID = M.QmID
WHERE
    Q.QID IN (SELECT QID FROM MyTable WHERE MyID = 123); 
QPackID QGrpID QID的
1 1 1
1 2 2
1 2 3
2 3 4
2 3 5
2 4 5
3 5 6
3 5 7
3 5 8
3 6 9
4 7 10
4 8 11
4 8 12
  • QID属于QGrpID
  • QGrpID属于QPackID

我想根据以下条件对此进行排序:

  • QPackID随机化,同时保持固定在相同范围内QPackID
  • QGrp随机化,同时保持固定在相同范围内QGrpID
  • QID继续上升QGrpID

预期结果如下:

QPackID QGrpID QID的
4 8 11
4 8 12
4 7 10
2 3 4
2 3 5
2 4 5
1 2 2
1 2 3
1 1 1
3 6 9
3 5 6
3 5 7
3 5 8

谁能帮我解决这个问题?

sql-server sql-server-2019

评论


答:

2赞 Caleb Carl 11/16/2023 #1

我相信这会给你你想要的结果,而不必多次加入表格本身——

DECLARE @X DECIMAL(5, 5);

SELECT @X = RAND();

SELECT Q.QPackID
     , Q.QGrpID
     , Q.QID
FROM dbo.SV_Q AS Q
    LEFT JOIN dbo.SV_Q_Pack AS P
        ON Q.QPackID = P.QPackID
    LEFT JOIN dbo.SV_QGrp AS G
        ON Q.QGrpID = G.QGrpID
    LEFT JOIN dbo.SV_QM AS M
        ON Q.QmID = M.QmID
WHERE Q.QID IN
      (
          SELECT QID FROM MyTable WHERE MyID = 123
      )
ORDER BY (CAST(Q.QPackID AS DECIMAL(23)) % @X) DESC
       , (CAST(Q.QGrpID AS DECIMAL(23)) % @X) DESC
       , QID ASC;

对于您的查询,将子句中的调整为所需的大小,即如果 QPackID 是最多包含 9 位数字的列,请使用 .DECIMAL(n)ORDER BYDECIMAL(9)

下面的示例 - DB Fiddle

评论

0赞 Hanericka 11/16/2023
非常感谢。由于每个 ID 字段实际上都是 9 位整数,因此我将“DECIMAL(2, 2)”替换为 DECIMAL(11, 2) 并且效果很好。
0赞 Caleb Carl 11/17/2023
我已将您的编辑添加到代码中。感谢您的反馈。
0赞 Hanericka 11/17/2023
我真的很感谢你的好意。
2赞 Stu 11/16/2023 #2

您需要为每组 Id 值分配一个随机值。

以下是如何使用 newid() 执行此操作的基础知识,下表是您的数据:t

select t.* 
from t
cross apply (
    select Max(NewId()) id
    from t t2
    where t2.QPackID = t.QPackID
    group by QPackID 
)qpid
cross apply (
    select Max(NewId()) id
    from t t2
    where t2.QGrpID = t.QGrpID
    group by QGrpID
)qgid
order by qpid.id, qgid.id, t.QID;

您可以查看以下演示

评论

0赞 Hanericka 11/16/2023
非常感谢。你给我的结果是完美的。如何使用现有的三个表执行此操作?我想每次都通过动态条件来做到这一点。