Sandro Bizioli


Chi sogna di giorno conosce molte cose che sfuggono a chi sogna soltanto di notte. (E.A.Poe)
Mappa

Recuperare valori casuali da una tabella con SQL Server 2005

Qui di seguito ho voluto riportare due esempi per l'estrazione di numeri casuali da una tabella.
Il primo esempio recupera semplicemente un valore random, mentre il secondo estrae una serie di numeri, tipo estrazione dell'otto, che devono sì essere casuali, ma anche non ripetibili.
 
Primo esempio:
Potrebbe capitare di voler estrarre da una tabella un record a caso, per esempio per visuallizare una frase di benvenuto sulla home del proprio sito.
Una delle possibili soluzioni potrebbe essere quella riportata qui di seguito:

-- Definisco la tabella myTable
CREATE TABLE myTable
        (
        Numero SMALLINT NOT NULL
        )  ON [PRIMARY]
GO
-- La popolo
SET NOCOUNT ON
DECLARE @x AS INT
SELECT @x = 1
WHILE not @x > 90
  BEGIN
 INSERT dbo.myTable VALUES(@x) 
 SELECT @X = @X + 1
  END
SET NOCOUNT OFF
GO

--Estraggo un solo numero
DECLARE @myNumero AS SMALLINT
SELECT @myNumero = rand() * (select max(numero) from myTable)
SELECT TOP 1 * FROM myTable WHERE Numero >= @myNumero
GO
--Elimino le tabelle d'appoggio
DROP TABLE myTable

Attenzione che se i valori di Numero non fossero sequenziali, ad esempio 10,20,30 l'istruzione "rand() * (select max(numero) from myTable)" avrebbe restituito un numero casuale tra 0 e 30; se fosse uscito ad esempio 15 non avremmo avuto nessuna occorrenza nella tabella e nessun valore restituito. Impostando, però, Numero >= @myNumero il valore restituito sarebbe stato 20!

Secondo esempio: estrazioni dell'otto.
Qualche problema in più lo incontriamo qualora la nostra tabelle fosse usata per simulare, ad esempio, le estrazioni dell'otto.
Qui il procedimento diventa un po' più complesso, ma non impossibile.

-- Definisco la tabella myTable
CREATE TABLE myTable
        (
        Numero SMALLINT NOT NULL
        )  ON [PRIMARY]
GO
-- La popolo
SET NOCOUNT ON
DECLARE @x AS INT
SELECT @x = 1
WHILE not @x > 90
  BEGIN
        INSERT dbo.myTable VALUES(@x) 
        SELECT @X = @X + 1
  END
SET NOCOUNT OFF
GO

-- Creo una tabella di appoggio per memorizzare i numeri estratti
CREATE TABLE myEstratti
        (
        Numero SMALLINT NOT NULL
        )  ON [PRIMARY]
GO
-- Imposto il numero di valori che voglio estrarre dalla tabella
-- NB. Ovviamente non devono essere superiori al numero delle righe contenute
-- altrimenti andrebbe in loop.
DECLARE @numEstratti AS int
SELECT @numEstratti = 1
WHILE NOT @numEstratti > 5
  BEGIN
      -- Recupero all'interno della tabella una riga in modo casuale
      -- incrociando i valori con la tabella delle estrazioni in modo
      -- da non avere doppioni
      DECLARE @myNumero as int;
      SELECT @myNumero = rand() * (
         SELECT count(a.numero)
         FROM myTable A
         LEFT JOIN myEstratti B on a.Numero = B.numero
         WHERE b.numero is null
      );
      --Creo una Common Table Expression
      WITH getRow(RowNumber, Numero) AS
     (
      SELECT RowNumber = ROW_NUMBER() OVER (ORDER BY A.Numero),
      A.Numero
     FROM myTable A
     LEFT JOIN myEstratti B on a.Numero = B.numero
     WHERE b.numero is null
     )
     -- Aggiungo il valore estratta alla tabella di supporto
     INSERT INTO myEstratti (Numero) 
     SELECT Numero 
     FROM getrow
     WHERE Rownumber = @myNumero
     --Incremento il contatore
    SELECT @numEstratti = @numEstratti+ 1
  END
-- A questo punto posso visualizzare i valori ricavati
SELECT * FROM myEstratti ORDER BY Numero 

-- Elimino le tabelle d'appoggio
DROP TABLE myTable
DROP TABLE myEstratti
Categoria: SQL Server
mercoledì, 22 feb 2006 Ore. 09.05
Statistiche
  • Views Home Page: 110.016
  • Views Posts: 561.005
  • Views Gallerie: 109.927
  • n° Posts: 227
  • n° Commenti: 222
Copyright © 2002-2007 - Blogs 2.0
dotNetHell.it | Home Page Blogs
ASP.NET 2.0 Windows 2003