【问题标题】:Select random values from temp table从临时表中选择随机值
【发布时间】:2015-08-12 03:59:02
【问题描述】:

我在尝试从 SQL SERVER 的临时表中选择随机值时遇到了一些麻烦。

这是临时表的架构和数据:

DECLARE @Colours TABLE 
(ID TINYINT PRIMARY KEY NOT NULL,
COLOR VARCHAR(30) NOT NULL)

INSERT INTO @Colours
SELECT 0 AS ID, '418CF0' as COLOUR
UNION ALL
SELECT 1, 'FCB441'
UNION ALL
SELECT 2, 'DF3A02'
UNION ALL
SELECT 3, '056492'
UNION ALL
SELECT 4, 'BFBFBF'
UNION ALL
SELECT 5, '1A3B69'
UNION ALL
SELECT 6, 'FFE382'
UNION ALL
SELECT 7, '129CDD'
UNION ALL
SELECT 8, 'CA6B4B'
UNION ALL
SELECT 9, '005CDB'
UNION ALL
SELECT 10, 'F3D288'
UNION ALL
SELECT 11, '506381'
UNION ALL
SELECT 12, 'F1B9A8'
UNION ALL
SELECT 13, 'E0830A'
UNION ALL
SELECT 14, '7893BE'

我想从临时表中为此查询的每一行选择不同的颜色值:

SELECT 
    PRV.NOM_PROVEE AS PROVEEDOR,
    SUM(IMPORTE_TO) AS TOTAL
FROM 
    FCA_VENTA_HEADER_HIST AS CAB
INNER JOIN
    PORTE_MAILLOT_SA.dbo.CPA01 AS PRV
        ON PRV.COD_PROVEE COLLATE Modern_Spanish_CI_AS = CAB.COD_PROVEE
WHERE
    YEAR(FECHA_EMIS) = 2015
    AND MONTH(FECHA_EMIS) = 7
    AND COD_EMPRESA = 1
GROUP BY
    PRV.NOM_PROVEE

为了更清楚,我将举一个我想要实现的例子。

假设这些是主查询的结果:

+-----------------------------+----------+
|          PROVEEDOR          |  TOTAL   |
+-----------------------------+----------+
| GRANJA MARTIN S.R.L.        | 5116,34  |
| RUSSAN de Antonio Russo     | 705,59   |
| GUACCI EZEQUIEL ADRIAN      | 6908,54  |
| RUSSAN de Antonio Russo     | 3929,26  |
| ARGON PACK S.R.L            | 14716,63 |
| GRANJA MARTIN S.R.L.        | 6800,2   |
| CREMAS HELADAS BAIRES SRL   | 10564,81 |
| LUSTROL ARGENTINA SRL       | 10496,51 |
| DE SANTO S.R.L.             | 4210,8   |
| GALLETITAS BELGRANO         | 5606,7   |
| RUSSAN de Antonio Russo     | 2320,54  |
| UNIVERSAL FISHING S.A       | 1608,82  |
| SADELAR S.R.L               | 8634,41  |
| DE SANTO S.R.L.             | 4210,8   |
| RUSSAN de Antonio Russo     | 2820,07  |
| SERVIFRIO S.A.              | 1928,57  |
| CREMAS HELADAS BAIRES SRL   | 4864,7   |
| ALIMENTOS PUEYRREDON S.R.L. | 15678,67 |
+-----------------------------+----------+

我想得到这样的东西:

+-----------------------------+--------+----------+
|          PROVEEDOR          | COLOUR  |  TOTAL  |
+-----------------------------+--------+----------+
| GRANJA MARTIN S.R.L.        | 418CF0 | 5116,34  |
| RUSSAN de Antonio Russo     | FCB441 | 705,59   |
| GUACCI EZEQUIEL ADRIAN      | DF3A02 | 6908,54  |
| RUSSAN de Antonio Russo     | 56492  | 3929,26  |
| ARGON PACK S.R.L            | BFBFBF | 14716,63 |
| GRANJA MARTIN S.R.L.        | 1A3B69 | 6800,2   |
| CREMAS HELADAS BAIRES SRL   | FFE382 | 10564,81 |
| LUSTROL ARGENTINA SRL       | 129CDD | 10496,51 |
| DE SANTO S.R.L.             | CA6B4B | 4210,8   |
| GALLETITAS BELGRANO         | 005CDB | 5606,7   |
| RUSSAN de Antonio Russo     | F3D288 | 2320,54  |
| UNIVERSAL FISHING S.A       | 506381 | 1608,82  |
| SADELAR S.R.L               | F1B9A8 | 8634,41  |
| DE SANTO S.R.L.             | E0830A | 4210,8   |
| RUSSAN de Antonio Russo     | 7893BE | 2820,07  |
| SERVIFRIO S.A.              | 005CDB | 1928,57  |
| CREMAS HELADAS BAIRES SRL   | 129CDD | 4864,7   |
| ALIMENTOS PUEYRREDON S.R.L. | 1A3B69 | 15678,67 |
+-----------------------------+--------+----------+

查询返回的行数可以是可变的,因此颜色是否在结果集中重复并不重要。每次运行查询时,我都需要获得与每一行关联的不同颜色(当我提到不同颜色时,我指的是选择的顺序)。

【问题讨论】:

    标签: sql-server random temp-tables


    【解决方案1】:

    要从表中获取随机行,您可以使用ORDER BY NEWID()。对于您的情况,您想使用 CROSS APPLY:

    SELECT 
        PRV.NOM_PROVEE AS PROVEEDOR,
        SUM(IMPORTE_TO) AS TOTAL,
        x.COLOR
    FROM 
        FCA_VENTA_HEADER_HIST AS CAB
    INNER JOIN
        PORTE_MAILLOT_SA.dbo.CPA01 AS PRV
            ON PRV.COD_PROVEE COLLATE Modern_Spanish_CI_AS = CAB.COD_PROVEE
    CROSS APPLY(
        SELECT TOP 1 COLOR FROM @Colours ORDER BY NEWID()
    )x
    WHERE
        YEAR(FECHA_EMIS) = 2015
        AND MONTH(FECHA_EMIS) = 7
        AND COD_EMPRESA = 1
    GROUP BY
        PRV.NOM_PROVEE
    

    要查询SARGABLE,您不应在列上使用函数。而不是使用:

    YEAR(FECHA_EMIS) = 2015
    AND MONTH(FECHA_EMIS) = 7
    

    你可以使用:

    FECHA_EMIS >= CAST('20150701' AS DATE)
    AND FECHA_EMIS < CAST('20150801' AS DATE)
    

    编辑:每行都有一个随机的COLOR

    WITH CteQ AS(   
        SELECT
            RN = ROW_NUMBER() OVER(ORDER BY (SELECT NULL)),
            PRV.NOM_PROVEE AS PROVEEDOR,
            SUM(IMPORTE_TO) AS TOTAL,
            x.COLOR
        FROM 
            FCA_VENTA_HEADER_HIST AS CAB
        INNER JOIN
            PORTE_MAILLOT_SA.dbo.CPA01 AS PRV
                ON PRV.COD_PROVEE COLLATE Modern_Spanish_CI_AS = CAB.COD_PROVEE
        CROSS APPLY(
            SELECT TOP 1 COLOR FROM @Colours ORDER BY NEWID()
        )x
        WHERE
            YEAR(FECHA_EMIS) = 2015
            AND MONTH(FECHA_EMIS) = 7
            AND COD_EMPRESA = 1
        GROUP BY
            PRV.NOM_PROVEE
    ),
    CteColours AS(
        SELECT *, RN = ROW_NUMBER() OVER(ORDER BY NEWID())
        FROM @Colours
    )
    SELECT
        q.PROVEEDOR,
        c.COLOR,
        q.TOTAL
    FROM CteQ q
    OUTER APPLY(
        SELECT TOP 1 Color 
        FROM CteColours
        WHERE q.RN % RN = 0
        ORDER BY NEWID()
    )c
    

    【讨论】:

    • 对我来说太快了。我正在写一个子查询版本,但交叉应用更优雅:-)
    • 此查询部分解决了我正在寻找的内容,但问题是我需要为每个 PROVEEDOR 设置不同的 COLOR 值。这使它变得更加困难。使用您的解决方案,所有行的颜色都相同。非常感谢 SARGABLE 的建议。
    • 你是个天才,这正是我想要的。非常感谢。
    猜你喜欢
    • 2019-07-30
    • 2015-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-11
    • 1970-01-01
    相关资源
    最近更新 更多