2015-08-12 4 views
0

У меня возникли проблемы с выбором случайных значений из таблицы temp в SQL SERVER.Выберите случайные значения из таблицы temp

Это схема и данные из временной таблицы:

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 | 
+-----------------------------+--------+----------+ 

Количество строк, возвращенных запросом может быть переменной, поэтому не имеет значения, повторяются ли цвета в наборе результатов. Мне нужно получить другой ЦВЕТ (когда я обращаюсь к разному COLOR, я говорю о порядке, в котором выбраны) значение, связанное с каждой отдельной строкой, каждый раз, когда я запускаю запрос.

ответ

3

Чтобы получить случайный ряд из таблицы, вы можете использовать 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) 

EDIT: Для того, чтобы иметь случайный 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 
+1

слишком быстро для меня. Я писал версию подзапроса, но cross apply выглядит более элегантно :-) –

+0

Этот запрос частично разрешает то, что я искал, но проблема в том, что мне нужно другое значение COLOR для каждого PROVEEDOR. Это делает его немного сложнее; с вашим решением я получил тот же ЦВЕТ для всех строк. Большое спасибо за советы SARGABLE. – jmrivas

+0

@jmrivas, см. Мое редактирование. –

Смежные вопросы