Update a column by each value - sql-server-2008-r2

Below is my table contains duration as HH:MM:SS
i could convert it into seconds by
SELECT (SUBSTRING(CAST('00:01:15' AS NVARCHAR(MAX)),1,2) * 360)
+ (SUBSTRING(CAST('00:01:15' AS NVARCHAR(MAX)),4,2) * 60)
+ SUBSTRING(CAST('00:01:15' AS NVARCHAR(MAX)),7,2)
and now i need to update that table into seconds by reading each row of records how?
like instead of having '00:01:15' i need each row of #DURATIONINSECONDS

Try like below
If your table have value like this
Table1
DurationInSeconds
00:01:15
00:00:15
00:01:16
00:01:17
and you want to Update the field DurationInSeconds into Seconds...
then just try like the below query....
update Table1 set DurationInSeconds = (SUBSTRING(CAST(DurationInSeconds AS NVARCHAR(MAX)),1,2) * 360) + (SUBSTRING(CAST(DurationInSeconds AS NVARCHAR(MAX)),4,2) * 60) + SUBSTRING(CAST(DurationInSeconds AS NVARCHAR(MAX)),7,2)
then it give the Result like below
SELECT * from Table1
DurationInSeconds
75
15
76
77

Related

PostgreSQL non-overlapping ranges

I use PostgreSQL database and have a cards table.
Each record(card) in this table have card_drop_rate integer value.
For example:
id | card_name |card_drop_rate
-------------------------------
1 |card1 |34
2 |card2 |16
3 |card3 |54
max drop rate is 34 + 16 + 54 = 104.
In accordance to my application logic I need to find a random value between 0 and 104 and then retrieve card according to this number, for example:
random value: 71
card1 range: 0 - 34(0 + 34)
card2 range: 34 - 50(34 + 16)
card3 range: 50 - 104(50 + 54)
So, my card is card3 because 71 is placed in the range 50 - 104
What is the proper way to reflect this structure in PostgreSQL ? I'll need to query this data often under so the performance is a criterion number one for this solution.
Following query works fine:
SELECT
b.id,
b.card_drop_rate
FROM (SELECT a.id, sum(a.card_drop_rate) OVER(ORDER BY id) - a.card_drop_rate as rate, card_drop_rate FROM cards as a) b
WHERE b.rate < 299 ORDER BY id DESC LIMIT 1
You can do this using cumulative sums and random. The "+ 1"s might be throwing me off, but it is something like this:
with c as (
select c.*,
sum(card_drop_rate + 1) - card_drop_rate as threshhold
from cards c
),
r as (
select random() * (sum(card_drop_rate) + count(*) - 1) as which_card
from cards c
)
select c.*
from c cross join
r
where which_card >= threshhold
order by threshhold
limit 1;
For performance, I would simply take the cards and generate a new table with 106 slots. Assign the card value to the slots and build an index on the slot number. Then get a value using:
select s.*
from slots s
where s.slotid = floor(random() * 107);

Updating just day from an existent dateandtime column for all table

I'm trying to create a query that updates the timestamp of all existent rows of a specific table.
Below is an example table to exemplify:
"DateAndTime"; ID; value
"2014-04-01 00:00:03"; 44; 10
"2014-04-01 00:00:03"; 45 ; 120
"2014-04-01 00:00:03"; 46 ; 80
"2014-04-01 00:00:03"; 47 ; 30000
"2014-04-01 00:00:13"; 44 ; 11
"2014-04-01 00:00:13"; 45 ; 122
"2014-04-01 00:00:13"; 46 ; 76
"2014-04-01 00:00:13"; 47 ; 30200
Now I want to change JUST the day by the current date but maintain the time
the result would be something like
"DateAndTime" | ID| value
Current_date + '00:00:03'; 44; 10
Current_date + '00:00:03'; 45; 120
Current_date + '00:00:03'; 46; 80
Current_date + '00:00:03'; 47; 30000
Current_date + 00:00:13"; 44; 11
Current_date + 00:00:13"; 45; 122
Current_date + 00:00:13"; 46; 76
Current_date + 00:00:13"; 47; 30200
I know that I can do the following
UPDATE "MyTable"
SET "DateAndTime"= (Select date_trunc('day',Localtimestamp) + ''00:00:03' )
And this works, But I have thousands of rows so i need replace + ''00:00:03' by each row dateandtime column default value with all time extracted. Like if there was an inverted date_trunc witch truncates from the seconds until the hours.
Do you now what can I use to replace the time with the default row value. Or do you know a better way to implement this query.
Thanks in advance
I found the solution; Instead of trying to manipulate separatly the date and time I just need to find the difference between the current_timmestamp and the timmestamp that I want to update and add that interval
The code is :
UPDATE "MyTable"
SET "DateAndTime"= "DateAndTime" + age(date_trunc('day',"DateAndTime"));
You have to trunc the timestamp by the day so the hours, minutes, second and beyond does not enter in the equation.
update MyTable set DateAndTime = now()::date + DateAndTime::time;

current time minus mod_date_time

I want to be able to subtract the current time from the mod_date_time field.
This is what I have so far:
SELECT * FROM PROD_TRKG_TRAN.MOD_DATE_TIME - CURRENT_TIME WHERE USER_ID = '12345' * 24 * 60 "INTERVAL IN MINUTES"
Any help?
If you are using Oracle, you can use the following query:
SELECT (MOD_DATE_TIME - SYSDATE) * 24 * 60
FROM PROD_TRKG_TRAN
WHERE USER_ID = '12345';

Changes from SQL Query and Update Statement

I have a query that produces a random departure dates from 1 to 28 days after the arrival date field:
--Query--
SELECT ArrivalDate, DATEADD(day, 1 + RAND(checksum(NEWID()))
* LengthOfStay.LengthofStay, ArrivalDate) AS DepartureDate
FROM Bookings, LengthOfStay
However when I run the Update query the randomisng reduced down to 1 or 2 days, can anyone advise why this is?
--Update Statement--
USE Occupancy
Update B
Set DepartureDate = DATEADD(day, 1 + RAND(checksum(NEWID()))*1.5 * L.LengthofStay, B.ArrivalDate)
FROM LengthOfStay L, Bookings B
Thanks
Wayne
I used the solution below:
UPDATE BOOKINGS
SET DepartureDate =
DATEADD(day,
CASE WHEN Rand(CHECKSUM(NEWID())) BETWEEN 0 and 0.3 THEN 2 ELSE
CASE WHEN Rand(CHECKSUM(NEWID())) BETWEEN 0.3 and 0.5 THEN 3 ELSE
Round(Rand(CHECKSUM(NEWID())) * 28,0) END END,ArrivalDate)

Convert HH:MM:SS string to number of minutes

I have the below query.
select cast(dateadd(minute, datediff(minute, TimeIn, TimeOut), 0) as time(0) )
I get the results from two columns in the format of hrs-min-seconds.
I would like it in the format of min only. So 02:47:00 will read 167.
SQL Server Query:
SELECT cast(substring('02:47:00',1,2) AS int)*60+
cast(substring('02:47:00',4,2) AS int)+
cast(substring('02:47:00',7,2) AS int)/60.0 AS minutes
MYSQL Query:
SELECT TIME_TO_SEC('02:47:00') / 60
Result:
| MINUTES |
-----------
| 167 |
declare #Time DATETIME = '01:05:00'
select ((DATEPART(HOUR, #Time)*60) + (DATEPART(MINUTE, #Time)))
For SQL Server (works for 2005 too):
select Datediff(mi,convert(datetime,'00:00:00',108), convert(datetime,'02:47:00',108))
Try this:
datediff(minute, 0, '02:47')
Expanding on Justin's answer. This allows for situations where hours is larger than 2 digits.
declare #time varchar(50) = '102:47:05'
SELECT cast(right(#time,2) AS int)+
cast(left(right(#time,5),2) AS int)*60+
cast(left(#time,len(#time)-6) AS int)*3600 AS seconds,
(cast(right(#time,2) AS int)+
cast(left(right(#time,5),2) AS int)*60+
cast(left(#time,len(#time)-6) AS int)*3600)/60.0 AS minutes
Result:
seconds minutes
----------- ---------------------------------------
370025 6167.083333
SELECT DATEDIFF(minute,CAST('00:00' AS TIME), CAST('02:47' AS TIME)) AS difference
Gives you:
| DIFFERENCE |
--------------
| 167 |
Unfortunately, if you want to use DATEPART function for values with more than 24 hours, you will receive an error:
Conversion failed when converting date and/or time from character string."
You can test it with this code:
declare #Time DATETIME = '32:00:00'
select ((DATEPART(HOUR, #Time)*60) + (DATEPART(MINUTE, #Time)))
To solve this, I worked with this another approach:
declare #tbl table(WorkHrs VARCHAR(8))
insert into #tbl(WorkHrs) values ('02:47:00')
insert into #tbl(WorkHrs) values ('32:00:00')
-- Sum in minutes
SELECT TRY_CAST(([HOURS] * 60) + [MINUTES] + ([SECOND] / 60) AS INT) as TotalInMinutes
FROM (
SELECT
-- Use this aproach to get separated values
SUBSTRING(WorkHrs,1,CHARINDEX(':',WorkHrs)-1) AS [HOURS],
SUBSTRING(WorkHrs,4,CHARINDEX(':',WorkHrs)-1) AS [MINUTES],
SUBSTRING(WorkHrs,7,CHARINDEX(':',WorkHrs)-1) AS [SECOND] -- probably you can ignore this one
FROM #tbl
)
tbl
-- Sum in seconds
SELECT TRY_CAST(([HOURS] * 3600) + ([MINUTES] * 60) + [SECOND] AS INT) as TotalInSeconds
FROM (
SELECT
-- Use this aproach to get separated values
SUBSTRING(WorkHrs,1,CHARINDEX(':',WorkHrs)-1) AS [HOURS],
SUBSTRING(WorkHrs,4,CHARINDEX(':',WorkHrs)-1) AS [MINUTES],
SUBSTRING(WorkHrs,7,CHARINDEX(':',WorkHrs)-1) AS [SECOND]
FROM #tbl
)
tbl
This code will return like this:
$time = '02:47:00';
$time = explode(":",$time);
$total = ($a[0]*60)+$a[1];
echo 'Minutes : '.$total;<br>
echo 'Seconds : '.$a[2];