0

我正在做一个子查询来为每个供应商选择前 5 个产品。需要对每个供应商的产品随机进行选择。

为此,我进行了以下查询(基于 Allen Browne 的示例):

SELECT tblProducts_temp.SupplierID, tblProducts_temp.GTIN
FROM tblProducts_temp
GROUP BY tblProducts_temp.SupplierID, tblProducts_temp.GTIN
HAVING (((tblProducts_temp.GTIN) In (SELECT TOP 5 Dupe.GTIN 
FROM tblProducts_temp AS Dupe 
WHERE Dupe.SupplierID = tblProducts_temp.SupplierID 
ORDER BY RND(Dupe.GTIN) DESC)))
ORDER BY tblProducts_temp.SupplierID, tblProducts_temp.GTIN;

查询返回随机数量的产品,但不是前 5 个。因此,供应商 X 一次是 3 个产品,下一次是供应商 X 7 个产品。

没有 RND 函数的查询,所以只有前 5 个可以正常工作:

SELECT tblProducts_temp.SupplierID, tblProducts_temp.GTIN
FROM tblProducts_temp
GROUP BY tblProducts_temp.SupplierID, tblProducts_temp.GTIN
HAVING (((tblProducts_temp.GTIN) In (SELECT TOP 5 Dupe.GTIN 
FROM tblProducts_temp AS Dupe 
WHERE Dupe.SupplierID = tblProducts_temp.SupplierID 
ORDER BY Dupe.GTIN DESC)))
ORDER BY tblProducts_temp.SupplierID, tblProducts_temp.GTIN;

我真的被困住了。谁能帮帮我!

谢谢!

4

1 回答 1

0

如果Rnd()似乎在同一个查询中搞砸了,TOP 5那么您可以尝试将其移动Rnd()到它自己的子查询中,也许像这样(未经测试)?

SELECT 
    tblProducts_temp.SupplierID, 
    tblProducts_temp.GTIN
FROM tblProducts_temp
GROUP BY 
    tblProducts_temp.SupplierID, 
    tblProducts_temp.GTIN
HAVING 
    tblProducts_temp.GTIN IN 
        (
            SELECT TOP 5 Dupe.GTIN 
            FROM 
                (
                    SELECT GTIN, Rnd(GTIN) AS rndSeq
                    FROM tblProducts_temp AS t3
                    WHERE t3.SupplierID = tblProducts_temp.SupplierID
                ) AS Dupe 
            ORDER BY Dupe.rndSeq DESC
        )
ORDER BY 
    tblProducts_temp.SupplierID, 
    tblProducts_temp.GTIN;

编辑

我对上述查询的主题尝试了几种不同的变体,似乎Rnd()在这种子查询中具有动态函数确实会混淆数据库引擎。我怀疑这是因为重复调用子查询Rnd()时,值每次都在变化,因此记录的“排序顺序”不断变化。

该问题的解决方案是使用AutoNumber(Random)主键字段(在下面的示例中名为 [rndID])创建 [tblProducts_temp] 表,因此当通过类似这样的方式插入 [SupplierID] 和 [GTIN] 值时...

INSERT INTO tblProducts_temp ( SupplierID, GTIN )
SELECT tblProducts.SupplierID, tblProducts.GTIN
FROM tblProducts;

...然后 [tblProducts_temp] 中的每一行都有一个随机键值,它是持久的(并且不变,至少在手头任务的持续时间内):

rndID        SupplierID  GTIN
-----------  ----------  ----
-1615446985           1     1
  132251564           1     2
  -43091651           1     3
-1416094278           1     4
  552752563           1     5
-1319640456           1     6
 1743429401           1     7
  409890150           2     1
 1563614959           2     2
 1727785476           2     3
 -611861835           2     4
 1826254802           2     5
-1118022677           2     6
 -530587056           2     7

有了这个,问题中的原始查询可以通过简单地替换ORDER BY RND(Dupe.GTIN)ORDER BY Dupe.rndID

SELECT 
    tblProducts_temp.SupplierID, 
    tblProducts_temp.GTIN
FROM tblProducts_temp
GROUP BY 
    tblProducts_temp.SupplierID, 
    tblProducts_temp.GTIN
HAVING tblProducts_temp.GTIN In 
    (
        SELECT TOP 5 Dupe.GTIN 
        FROM tblProducts_temp AS Dupe 
        WHERE Dupe.SupplierID = tblProducts_temp.SupplierID 
        ORDER BY Dupe.rndID DESC
    )
ORDER BY 
    tblProducts_temp.SupplierID, 
    tblProducts_temp.GTIN;
于 2013-06-02T12:52:21.930 回答