Cóż, wiem, że jest to stara sprawa, ale to było związane z nowszej więc ... Oto moje 2 centy:
- tabele bazy danych są nieposortowane przez naturę.
- Istnieje tylko 365 możliwych dat w danym roku, 366 jeśli jest to rok przestępny.
- Powielone dane są oznaką złego projektu.
Na podstawie tych przesłanek uważam, że tak naprawdę nie ma rzeczywistej potrzeby przechowywania 1000 losowych dat w tabeli, kiedy możliwe jest zapisanie tylko odpowiedniej daty i wystarczy wybrać liczbę wierszy w dowolnej kolejności potrzeba.
Najpierw zapisz dane w tabeli. możesz użyć Tally table, aby utworzyć odpowiedni zakres dat.
Tabela Tally jest tabelą zawierającą ciąg cyfr. ze względu na argument, załóżmy, że już stworzyłeś tabelę z liczbami od 0 do 1 000 000.
You can check this link dla najlepszej drodze do stworzenia jednego, osobiście lubię tę metodę:
-- create the tally table
SELECT TOP 100000 IDENTITY (int ,0, 1) as num
INTO Tally
FROM sys.sysobjects
CROSS JOIN sys.all_columns
Teraz masz tabelę Tally, jest to dość proste do stworzenia kalendarza:
DECLARE @FromDate datetime = GETDATE(),
@ToDate datetime = DATEADD(YEAR, 1, GETDATE()) -- a year from now in my example
;With CalendarCTE AS
(
SELECT DATEADD(DAY, num, @FromDate) As caneldarDate
FROM Tally
WHERE num < DATEDIFF(DAY, @FromDate, @ToDate)
)
teraz, że Mają kalendarz i tabelę, jest dość proste, aby użyć ich do uzyskania dowolnej liczby rekordów w dowolnej kolejności. Tysiąc losowo zamówionych dat? nie ma problemu:
SELECT TOP 1000 caneldarDate
FROM CalendarCTE c
CROSS JOIN Tally t
WHERE t.num < 1000
ORDER BY NEWID()
Pełny skrypt, w tym tworzenie i upuszczenie tabeli sygnalizacyjną trwało krócej niż sekundę, aby wykonać:
-- create the tally table
SELECT TOP 100000 IDENTITY (int ,0, 1) as num
INTO Tally
FROM sys.sysobjects
CROSS JOIN sys.all_columns
-- crealte the calendar cte:
DECLARE @FromDate datetime = GETDATE(),
@ToDate datetime = DATEADD(YEAR, 1, GETDATE())
;With CalendarCTE AS
(
SELECT DATEADD(DAY, num, @FromDate) As caneldarDate
FROM Tally
WHERE num < DATEDIFF(DAY, @FromDate, @ToDate)
)
-- select a 1000 random dates
SELECT TOP 1000 caneldarDate
FROM CalendarCTE c
CROSS JOIN Tally t
WHERE t.num < 1000
ORDER BY NEWID()
-- cleanup
DROP TABLE Tally
Jaka wersja SQL Server używacie? Testowałem w SQL Server 2012 i otrzymałem komunikat "Niewłaściwe użycie operatora" rand "w funkcji". –
Dzięki @MikaelEriksson, poprawiłem zapytanie. Pozdrowienia. – danihp