Okay very new to SQL Server, so please be patient.
I'm trying to find the start time for everyday to generate an automated report for work for the last 30 days. I've managed to get some information working but I'm struggling with what I thought would be a basic one.
So some basic back ground. when we are in production the step number is 30. that would be enough if production ran smoothly every day. What I'm trying to do is find the time we go into step 30 and vats produced = 1
I thought I had it with this:
use Runtime
SET NOCOUNT ON
DECLARE #StartDate DateTime
DECLARE #EndDate DateTime
SET #EndDate = GETDATE()
SET #StartDate = DATEADD(DAY, -30, #enddate)
SET NOCOUNT OFF
SELECT
a.TagName, a.DateTime, a.Value,
b.tagname, b.value, b.DateTime, a.StartDateTime
FROM
History A, History B
WHERE
a.tagname = ('H20W01_Prod_StepNo')
AND b.tagname = ('H20W01_Par_VatsProduced')
AND a.Value = '30'
AND b.value = '1'
AND a.DateTime BETWEEN #StartDate AND #EndDate
AND b.DateTime BETWEEN #StartDate AND #EndDate
However this returns this result
Results
I seem to get the start time for going into step 30 for each of the 30 days. but 30 rows for each day with datetime for the 1st vat for each of the last 30.
Any help would be appreciated. I'm thinking I need a join but both are stored in the same table
Thank you in advance
The final answer would depend on knowing the whole problem but reading from the question I would say that this could work.
DECLARE #History TABLE (TagName VARCHAR(MAX), [DateTime] DATETIME, Value INT)
-- on 24th the 30 is reached at 10 am (10:00), Vats value 1 reached at 11 am (11:00)
INSERT INTO #History VALUES ('H20W01_Prod_StepNo', '20200624 09:00', 1)
INSERT INTO #History VALUES ('H20W01_Prod_StepNo', '20200624 10:00', 30)
INSERT INTO #History VALUES ('H20W01_Prod_StepNo', '20200624 11:00', 40)
INSERT INTO #History VALUES ('H20W01_Prod_StepNo', '20200624 12:00', 50)
INSERT INTO #History VALUES ('H20W01_Par_VatsProduced', '20200624 00:00', 0)
INSERT INTO #History VALUES ('H20W01_Par_VatsProduced', '20200624 10:00', 0)
INSERT INTO #History VALUES ('H20W01_Par_VatsProduced', '20200624 11:00', 1)
INSERT INTO #History VALUES ('H20W01_Par_VatsProduced', '20200624 12:00', 1)
-- on 25th the 30 is reached at 1 pm (13:00); Vats value 1 reached at 2 pm (14:00)
INSERT INTO #History VALUES ('H20W01_Prod_StepNo', '20200625 00:00', 1)
INSERT INTO #History VALUES ('H20W01_Prod_StepNo', '20200625 10:00', 4)
INSERT INTO #History VALUES ('H20W01_Prod_StepNo', '20200625 11:00', 6)
INSERT INTO #History VALUES ('H20W01_Prod_StepNo', '20200625 12:00', 28)
INSERT INTO #History VALUES ('H20W01_Prod_StepNo', '20200625 13:00', 30)
INSERT INTO #History VALUES ('H20W01_Prod_StepNo', '20200625 15:00', 30)
INSERT INTO #History VALUES ('H20W01_Par_VatsProduced', '20200625 00:00', 0)
INSERT INTO #History VALUES ('H20W01_Par_VatsProduced', '20200625 10:00', 0)
INSERT INTO #History VALUES ('H20W01_Par_VatsProduced', '20200625 11:00', 0)
INSERT INTO #History VALUES ('H20W01_Par_VatsProduced', '20200625 14:00', 1)
INSERT INTO #History VALUES ('H20W01_Par_VatsProduced', '20200625 15:00', 1)
-- create a help table of last 10 days
DECLARE #Pivot DATETIME = DATEADD(day, -10, GETDATE())
DECLARE #Days TABLE (Day DATETIME)
WHILE (#Pivot < GETDATE()) BEGIN
INSERT INTO #Days VALUES (#Pivot)
SET #Pivot = DATEADD(day, 1, #Pivot)
END
SELECT
D.Day,
MIN(HA.DateTime) AS ProductionStepReachedOn,
MIN(HB.DateTime) AS VatsReachedOn
FROM
#Days D
LEFT JOIN #History HA ON
HA.TagName = 'H20W01_Prod_StepNo' AND
HA.[DateTime] BETWEEN D.Day AND DATEADD(second, -1, DATEADD(day, 1, D.Day)) AND
HA.Value = 30
LEFT JOIN #History HB ON
HB.TagName = 'H20W01_Par_VatsProduced' AND
HB.[DateTime] BETWEEN D.Day AND DATEADD(second, -1, DATEADD(day, 1, D.Day)) AND
HB.Value = 1
GROUP BY
D.Day
Related
I need to query all production records by 12 hr. shift. 7am-7am. if the date is after midnight and before 7am it's actually the previous day shift. In the below example I need to make them all 2022-01-01 like the last column. If I query by 2022-01-01 I don't get all the rows. Can I use a function for this to compare the time and make it the previous day?
declare #temp table
(
Emp_id int,
Time datetime,
shiftDate date
);
insert into #temp values (1, '2022-01-01 08:10:00:000', '2022-01-01')
insert into #temp values (1, '2022-01-01 10:21:00:000', '2022-01-01')
insert into #temp values (1, '2022-01-01 13:10:00:000', '2022-01-01')
insert into #temp values (1, '2022-01-01 22:22:00:000', '2022-01-01')
insert into #temp values (1, '2022-01-02 02:15:00:000', '2022-01-01')
insert into #temp values (1, '2022-01-02 04:22:00:000', '2022-01-01')
insert into #temp values (1, '2022-01-02 06:18:00:000', '2022-01-01')
insert into #temp values (1, '2022-01-02 06:55:00:000', '2022-01-01')
select * from #temp
select * from #temp
where convert(date, [time]) = '2022-01-01'
I have this table and sample data. I want to get the entire month's or specific dates attendance and information like hours he worked or days he was absent.
CREATE TABLE Attendance
(
[EmpCode] int,
[TimeIn] datetime,
[TimeOut] datetime
)
INSERT INTO Attendance VALUES (12, '2018-08-01 09:00:00', '2018-08-01 17:36:00');
INSERT INTO Attendance VALUES (12, '2018-08-02 09:00:00', '2018-08-02 18:10:00');
INSERT INTO Attendance VALUES (12, '2018-08-03 09:25:00', '2018-08-03 16:56:00');
INSERT INTO Attendance VALUES (12, '2018-08-04 09:13:00', '2018-08-05 18:09:00');
INSERT INTO Attendance VALUES (12, '2018-08-06 09:00:00', '2018-08-07 18:15:00');
INSERT INTO Attendance VALUES (12, '2018-08-07 09:27:00', '2018-08-08 17:36:00');
INSERT INTO Attendance VALUES (12, '2018-08-08 09:35:00', '2018-08-09 17:21:00');
INSERT INTO Attendance VALUES (12, '2018-08-10 09:00:00', '2018-08-10 17:45:00');
INSERT INTO Attendance VALUES (12, '2018-08-11 09:50:00', '2018-08-11 17:31:00');
INSERT INTO Attendance VALUES (12, '2018-08-13 09:23:00', '2018-08-13 17:19:00');
INSERT INTO Attendance VALUES (12, '2018-08-15 09:21:00', '2018-08-15 17:36:00');
INSERT INTO Attendance VALUES (12, '2018-08-16 09:00:00', '2018-08-16 17:09:00');
INSERT INTO Attendance VALUES (12, '2018-08-17 09:34:00', '2018-08-17 17:29:00');
INSERT INTO Attendance VALUES (12, '2018-08-18 09:00:00', '2018-08-18 17:10:00');
INSERT INTO Attendance VALUES (12, '2018-08-20 09:34:00', '2018-08-20 17:12:00');
INSERT INTO Attendance VALUES (12, '2018-08-21 09:20:00', '2018-08-21 17:15:00');
INSERT INTO Attendance VALUES (12, '2018-08-22 09:12:00', '2018-08-22 17:19:00');
INSERT INTO Attendance VALUES (12, '2018-08-23 09:05:00', '2018-08-23 17:21:00');
INSERT INTO Attendance VALUES (12, '2018-08-24 09:07:00', '2018-08-24 17:09:00');
INSERT INTO Attendance VALUES (12, '2018-08-25 09:12:00', '2018-08-25 17:05:00');
INSERT INTO Attendance VALUES (12, '2018-08-27 09:21:00', '2018-08-27 17:46:00');
INSERT INTO Attendance VALUES (12, '2018-08-28 09:17:00', '2018-08-28 17:12:00');
INSERT INTO Attendance VALUES (12, '2018-08-29 09:00:00', '2018-08-29 17:36:00');
INSERT INTO Attendance VALUES (12, '2018-08-30 09:12:00', '2018-08-30 17:24:00');
I have a query that tells how many hours employee have worked, but it is only showing days on which data was present in table. I want to show all dates between provided dates and in case there is no data it should NULL in columns.
Here is the query:
SELECT
[EmpCode],
FirstIN = CAST(MIN([TimeIn]) AS TIME),
LastOUT = CAST(MAX([TimeOut]) AS TIME),
CONVERT(VARCHAR(6), Datediff(second, CAST(MIN([TimeIn]) AS TIME), CAST(MAX([TimeOut]) AS TIME))/3600)
+ ':'
+ RIGHT('0' + CONVERT(VARCHAR(2), (Datediff(second, CAST(MIN([TimeIn]) AS TIME), CAST(MAX([TimeOut]) AS TIME)) % 3600) / 60), 2)
+ ':'
+ RIGHT('0' + CONVERT(VARCHAR(2), Datediff(second, CAST(MIN([TimeIn]) AS TIME), CAST(MAX([TimeOut]) AS TIME)) % 60) , 2 ) AS HoursSpent,
CAST(COALESCE(TimeIn, TimeOut) AS DATE) [Date]
FROM Attendance
WHERE CAST(COALESCE(TimeIn, TimeOut) AS DATE) BETWEEN '2018-08-01' AND '2018-08-25'
GROUP BY EmpCode, TimeIn, TimeOut
For that you need to use recursive way to generate possible dates :
with t as (
select '2018-08-01' as startdt
union all
select dateadd(day, 1, startdt)
from t
where startdt < '2018-08-25'
)
select . . .
from t left join
Attendance at
on cast(coalesce(at.TimeIn, at.TimeOut) as date) = t.startdt;
Just make sure to use date from t instead of Attendance table in SELECT statement.
Note : If you have a large no of date period, then don't forgot to use Query hint OPTION (MAXRECURSION 0), By defalut it has 100 recursion levels.
You May Try Recursive CTE to populate the Dates and Then Join With that to Get the Interval
DECLARE #From DATETIME = '2018-08-01' ,#To DATETIME= '2018-08-25'
;WITH CTE
AS
(
SELECT
[EmpCode] EmpId,
MyDate = #From
FROM Attendance A
UNION ALL
SELECT
EmpId,
MyDate = DATEADD(DAY,1,MyDate)
FROM CTE
WHERE MyDate < #To
)
SELECT
[EmpCode] = CTE.EmpId,
CTE.MyDate,
FirstIN = CAST(MIN([TimeIn]) AS TIME),
LastOUT = CAST(MAX([TimeOut]) AS TIME),
CONVERT(VARCHAR(6), Datediff(second, CAST(MIN([TimeIn]) AS TIME), CAST(MAX([TimeOut]) AS TIME))/3600)
+ ':'
+ RIGHT('0' + CONVERT(VARCHAR(2), (Datediff(second, CAST(MIN([TimeIn]) AS TIME), CAST(MAX([TimeOut]) AS TIME)) % 3600) / 60), 2)
+ ':'
+ RIGHT('0' + CONVERT(VARCHAR(2), Datediff(second, CAST(MIN([TimeIn]) AS TIME), CAST(MAX([TimeOut]) AS TIME)) % 60) , 2 )
AS HoursSpent,
CAST(CTE.MyDate AS DATE) [Date]
FROM CTE
LEFT JOIN Attendance A
ON A.EmpCode = CTE.EmpId
AND CAST(CTE.MyDate AS DATE) = CAST(COALESCE(TimeIn, TimeOut) AS DATE)
GROUP BY CTE.EmpId, TimeIn, TimeOut,CTE.MyDate
ORDER BY 6
A different method, using a Tally Table. The advantage here is that an rCTE is a form of RBAR. The idea of a Tally table isn't as obvious, but is quicker, and also, won't need the OPTION (MAXRECURSION 0) added if you have more than 100 days. in fact, this example handles up to 10,000 days, which shuold be more than enough:
DECLARE #EmpCode int = 12;
WITH N AS(
SELECT N
FROM (VALUES(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL)) N(N)),
Tally AS(
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) -1 AS I
FROM N N1 --10
CROSS JOIN N N2 --100
CROSS JOIN N N3 --1000
CROSS JOIN N N4 --10000
),
Dates AS(
SELECT DATEADD(DAY, T.I, TT.MinTimeIn) AS CalendarDate,
#EmpCode AS EmpCode
FROM Tally T
CROSS APPLY (SELECT MIN(CONVERT(date,TimeIn)) AS MinTimeIn,
MAX(CONVERT(date,TimeOut)) AS MaxTimeOut
FROM Attendance
WHERE EmpCode = #EmpCode) TT
WHERE DATEADD(DAY, T.I, TT.MinTimeIn) <= CONVERT(date, TT.MaxTimeOut))
SELECT CalendarDate
EmpCode,
TimeIn,
TimeOut
FROM Dates D
LEFT JOIN Attendance A ON D.CalendarDate = CONVERT(date,A.TimeIn)
AND D.EmpCode = A.EmpCode;
I need to see if one date span, in number of days, matches that of two date spans that cover the same period, but are added together.
For example...
DECLARE #Table1 TABLE
(
Id INT,
StartDate DATETIME,
EndDate DATETIME
)
INSERT INTO #Table1 VALUES (1, '2015-07-01 00:00:00.000', '2016-06-30 00:00:00.000')
DECLARE #Table2 TABLE
(
Id INT,
Fk INT,
StartDate DATETIME,
EndDate DATETIME
)
INSERT INTO #Table2 VALUES (1, 1, '2015-07-01', '2015-08-31')
INSERT INTO #Table2 VALUES (2, 1, '2015-09-01', '2016-03-31')
INSERT INTO #Table2 VALUES (3, 1, '2016-04-01', NULL)
SELECT DATEDIFF(DAY, T1.StartDate, T1.EndDate) AS SiteContractDays,
DATEDIFF(DAY, T2.StartDate, ISNULL(T2.EndDate, T1.EndDate)) AS SummedDayes
FROM #Table1 t1
INNER JOIN #Table2 t2
ON t2.fk = t1.Id
SELECT T1.Id, DATEDIFF(DAY, T1.StartDate, T1.EndDate) AS SiteContractDays,
SUM(DATEDIFF(DAY, T2.StartDate, ISNULL(T2.EndDate, T1.EndDate))) AS SummedDayes
FROM #Table1 t1
INNER JOIN #Table2 t2
ON t2.fk = t1.Id
GROUP BY T1.id, T1.StartDate, T1.EndDate
Dates are continuous.. they follow on for the full period. However, when I sum them up, we're short a few days. I'm not sure I can simply add a day to each DateDiff, because... then the total goes to 366, and the summed up values will go up as well.
I could add " + COUNT(*) -1 AS" to the SUM of the days when grouping them up, but that seems like a hack.
Maybe the + 1 is better but if you calculate by seconds it will be 1460 days in the end
SELECT (DATEDIFF(SECOND, '2015-07-01 00:00:00', '2016-06-30 23:59:59') + DATEDIFF(SECOND, '2016-07-01 00:00:00', '2019-06-30 23:59:59')) / 60 / 60 / 24
-- 1460
Two different statements that you need to understand.
SELECT DATEDIFF(DAY, '2015-07-01 00:00:00.000', '2019-06-30 00:00:00.000') -- 1460
No break thus count is continuous from day 1.
Day 1 from 2015-07-02
SELECT DATEDIFF(DAY, '2015-07-01', '2016-06-30') + DATEDIFF(DAY, '2016-07-01', '2019-06-30 00:00:00.000') -- 1459
Two different starting dates thus two different day 1s so you won't assume this is continuous...
day 1 from 2015-07-02 and day 1 from 2016-07-02... Day between 2016-06-30 and 2016-07-01 is your break and not counted.
Perhaps in breaking periods, you always need to add that 1 missing second explicitly.
SELECT
DATEDIFF(DAY, '2015-07-01 00:00:00.000', '2016-06-30') +
DATEDIFF(DAY, '2016-07-01', DATEADD(SECOND,1,'2019-06-30 23:59:59.000')) --1460
I hope you can help me.
I need to display the records in HH_Solution_Audit table -- if 2 or more staffs enter the room within 10 minutes. Here are the requirements:
Display only the events that have a timestamp (LAST_UPDATED) interval of less than or equal to 10 minutes. Therefore, I must compare the current row to the next row and previous row to check if their DATEDIFF is less than or equal to 10 minutes. I’m done with this part.
Show only the records if the number of distinct STAFF_GUID inside the room for less than or equal to 10 minutes is at least 2.
HH_Solution_Audit Table Details:
ID - PK
STAFF_GUID - staff id
LAST_UPDATED - datetime when a staff enters a room
Here's what I got so far. This satisfies requirement # 1 only.
CREATE TABLE HH_Solution_Audit (
ID INT PRIMARY KEY,
STAFF_GUID NVARCHAR(1),
LAST_UPDATED DATETIME
)
GO
INSERT INTO HH_Solution_Audit VALUES (1, 'b', '2013-04-25 9:01')
INSERT INTO HH_Solution_Audit VALUES (2, 'b', '2013-04-25 9:04')
INSERT INTO HH_Solution_Audit VALUES (3, 'b', '2013-04-25 9:13')
INSERT INTO HH_Solution_Audit VALUES (4, 'a', '2013-04-25 10:15')
INSERT INTO HH_Solution_Audit VALUES (5, 'a', '2013-04-25 10:30')
INSERT INTO HH_Solution_Audit VALUES (6, 'a', '2013-04-25 10:33')
INSERT INTO HH_Solution_Audit VALUES (7, 'a', '2013-04-25 10:41')
INSERT INTO HH_Solution_Audit VALUES (8, 'a', '2013-04-25 11:02')
INSERT INTO HH_Solution_Audit VALUES (9, 'a', '2013-04-25 11:30')
INSERT INTO HH_Solution_Audit VALUES (10, 'a', '2013-04-25 11:45')
INSERT INTO HH_Solution_Audit VALUES (11, 'a', '2013-04-25 11:46')
INSERT INTO HH_Solution_Audit VALUES (12, 'a', '2013-04-25 11:51')
INSERT INTO HH_Solution_Audit VALUES (13, 'a', '2013-04-25 12:24')
INSERT INTO HH_Solution_Audit VALUES (14, 'b', '2013-04-25 12:27')
INSERT INTO HH_Solution_Audit VALUES (15, 'b', '2013-04-25 13:35')
DECLARE #numOfPeople INT = 2,
--minimum number of people that must be inside
--the room for #lengthOfStay minutes
#lengthOfStay INT = 10,
--number of minutes of stay
#dateFrom DATETIME = '04/25/2013 00:00',
#dateTo DATETIME = '04/25/2013 23:59';
WITH cteSource AS
(
SELECT ID, STAFF_GUID, LAST_UPDATED,
ROW_NUMBER() OVER (ORDER BY LAST_UPDATED) AS row_num
FROM HH_SOLUTION_AUDIT
WHERE LAST_UPDATED >= #dateFrom AND LAST_UPDATED <= #dateTo
)
SELECT [current].ID, [current].STAFF_GUID, [current].LAST_UPDATED
FROM
cteSource AS [current]
LEFT OUTER JOIN
cteSource AS [previous] ON [current].row_num = [previous].row_num + 1
LEFT OUTER JOIN
cteSource AS [next] ON [current].row_num = [next].row_num - 1
WHERE
DATEDIFF(MINUTE, [previous].LAST_UPDATED, [current].LAST_UPDATED)
<= #lengthOfStay
OR
DATEDIFF(MINUTE, [current].LAST_UPDATED, [next].LAST_UPDATED)
<= #lengthOfStay
ORDER BY [current].ID, [current].LAST_UPDATED
Running the query returns IDs:
1, 2, 3, 5, 6, 7, 10, 11, 12, 13, 14
That satisfies requirement # 1 of having less than or equal to 10 minutes interval between the previous row, current row and next row.
Can you help me with the 2nd requirement? If it's applied, the returned IDs should only be:
13, 14
Here's an idea. You don't need ROW_NUMBER and previous and next records. You just need to queries unioned - one looking for everyone that have someone checked X minutes behind, and another looking for X minutes upfront. Each uses a correlated sub-query and COUNT(*) to find number of matching people. If number is greater then your #numOfPeople - that's it.
EDIT: new version: Instead of doing two queries with 10 minutes upfront and behind, we'll only check for 10 minutes behind - selecting those that match in cteLastOnes. After that will go in another part of query to search for those that actually exist within those 10 minutes. Ultimately again making union of them and the 'last ones'
WITH cteSource AS
(
SELECT ID, STAFF_GUID, LAST_UPDATED
FROM HH_SOLUTION_AUDIT
WHERE LAST_UPDATED >= #dateFrom AND LAST_UPDATED <= #dateTo
)
,cteLastOnes AS
(
SELECT * FROM cteSource c1
WHERE #numOfPeople -1 <= (SELECT COUNT(DISTINCT STAFF_GUID)
FROM cteSource c2
WHERE DATEADD(MI,#lengthOfStay,c2.LAST_UPDATED) > c1.LAST_UPDATED
AND C2.LAST_UPDATED <= C1.LAST_UPDATED
AND c1.STAFF_GUID <> c2.STAFF_GUID)
)
SELECT * FROM cteLastOnes
UNION
SELECT * FROM cteSource s
WHERE EXISTS (SELECT * FROM cteLastOnes l
WHERE DATEADD(MI,#lengthOfStay,s.LAST_UPDATED) > l.LAST_UPDATED
AND s.LAST_UPDATED <= l.LAST_UPDATED
AND s.STAFF_GUID <> l.STAFF_GUID)
SQLFiddle DEMO - new version
SQLFiddle DEMO - old version
I would like to generate a "random" integer for each row returned from a select statement where the random int only changes once per day (before and after 4am).
Example
declare #Date datetime
set #Date = dateadd(dd, 8, GETDATE())
declare #DateNumber int
set #DateNumber = LEFT(CONVERT(VARCHAR(8), #Date, 112),10)
+ cast(CASE WHEN DATEPART(hh, #Date) > 4 THEN 1 ELSE 0 END as varchar(1))
declare #Customers table (Id int, Customer varchar(150), OrderNo int)
insert into #Customers (Id, Customer) values (1, 'Cust A'), (2, 'Cust B'),
(3, 'Cust C'), (4, 'Cust D'), (5, 'Cust E'), (6, 'Cust F'),
(7, 'Cust G'), (8, 'Cust H'), (9, 'Cust I')
-- my 1st attempt which doesnt work
update #Customers set OrderNo = rand(#DateNumber) / rand(Id) * 100
select * from
#Customers order by OrderNo
The order of the results should remain constant until I change the dd value in the set #Date statement at the top.
Any ideas? Is this possible?
(outside of calculating this daily via a SQL job)
updated solution with HABO's recomendation
declare #Date datetime = dateadd(hh, 36, GETDATE())
declare #DateNumber int = LEFT(CONVERT(VARCHAR(8), #Date, 112),10) +
cast(CASE WHEN DATEPART(hh, #Date) > 4 THEN 1 ELSE 0 END as varchar(1))
declare #Customers table (Id int, Customer varchar(150), OrderNo int)
insert into #Customers (Id, Customer) values (1, 'Cust A'), (2, 'Cust B'),
(3, 'Cust C'), (4, 'Cust D'), (5, 'Cust E'), (6, 'Cust F'),
(7, 'Cust G'), (8, 'Cust H'), (9, 'Cust I')
declare #ThrowAway as Float = Rand(#DateNumber)
declare #ID int
set #ID = (select min(ID) from #Customers)
while #ID is not null
begin
update #Customers set OrderNo = Floor(Rand() * 100) + 1 where ID = #ID
set #ID = (select min(ID) from #Customers where ID > #ID)
end
select * from #Customers order by OrderNo
When you provide a seed to RAND( Seed ) it will return the same result. If you use a seed value prior to your UPDATE query it will initialize the sequence. Thereafter just use RAND() without an argument. Something like:
declare #ThrowAway as Float = Rand( #DateNumber )
update #Customers
set OrderNo = Floor( Rand() * 100 ) + 1
Do keep in mind that random values include duplicates.