I've a database that stores data read from different sensors. The table looks like this:
[SensorID][timestampMS][value]
[Sensor1][123420][10]
[Sensor1][123424][15]
[Sensor1][123428][6554]
[Sensor1][123429][20]
What I would like to do is the following: There are some reads that are corrupted (numbers that are 6554), and I would like to Update that with the next value that is not corrupted (in the example shown below that would be 20). So, if a number is 6554, I would like to update that with the next value (in timestamp), that is not corrupted.
I was thinking on doing this in PHP, but I wonder if it's possible to do it directly with a SQL script.
Appreciate :)
You can use a correlated sub-query...
UPDATE
myTable
SET
value = (SELECT value FROM myTable AS NextValue WHERE sensorID = myTable.SensorID AND timestampMS > myTable.timestampMS ORDER BY timestampMS ASC LIMIT 1)
WHERE
value = 6554
The sub-query gets all the following results, ordered by timestampMS and takes just the first one; That being the next value for that SensorID.
Note: If no "next" value exists, it will attempt to update with a value of NULL. To get around this, you can add this to the WHERE clause...
AND EXISTS (SELECT value FROM myTable AS NextValue WHERE sensorID = myTable.SensorID AND timestampMS > myTable.timestampMS ORDER BY timestampMS ASC LIMIT 1)
EDIT
Or, to be shorter, just use IFNULL(<sub_query>, value)...
Not sure if this is valid syntax, can't test it ATM. You may need to change this to be JOINs instead of the nested subqueries, but in concept you can do something like (for SQL Server):
UPDATE t1
SET Value = ( SELECT Value
from MyTable t2
WHERE t2.SensorID =t1.SensorID
AND t2.[timestamp] =
( SELECT MIN([TimeStamp])
FROM mytable t3
where t3.sensorid = t2.sensorID
AND t3.[timestamp] > t2.[timestamp]
)
)
FROM Mytable t1
WHERE t1.value = 6554
I did a workaround based on Dems solution, and it works in Mysql:
I've created a "copy" of the sensors table like this:
drop table if exists sensors_new;
create table if not exists sensors_new like sensors;
insert into sensors_new select * from sensors;
Then I do what Dems recommended me doing, but using this new aux table in the select (to avoid the error that Mysql launches when Updating a table while doing a select in the same table).
UPDATE
sensors
SET
raw_data = (SELECT raw_data FROM sensors_new AS NextValue WHERE sensor_id = sensors.sensor_id AND timestampMS > sensors.timestampMS ORDER BY timestampMS ASC LIMIT 1)
WHERE
value = 6554
Then, just drop this auxiliar table.
I hope this helps Mysql users.
Related
I want to select rows alternatively in mysql using php,
<?php
$result=mysql_query("select * from marker1 where date='$maxdate' and time BETWEEN '$mintime' AND '$maxtime' and imei_no='$vehicle_imei_no1'")or die(mysql_error());
?>
this is my query but it select all rows, in database i m not getting serialy data so i can't use this query
select t.id, name
from (select id, name, ROW_NUMBER() over (order by id) as srNo from Employee) t
where (t.srNo % 2) = 1
i only differentiate by time '11:05:30' in this formate
please guide me how to use query for alternative rows.
Thanks
Maybe this would work!:
select * from marker1 where date='$maxdate' and time BETWEEN '$mintime' AND '$maxtime' and imei_no='$vehicle_imei_no1'
AND (marker1.ID % 2) == 0
marker1.ID is the primary key and I'm supposing it as auto_increment.
This should select only the even values.
$sql = "SELECT * FROM Orders LIMIT 15, 10";
It would start from record 15th and return 10 records.
Ref: Link
I have table with 10 columns and I want to check input value in where clause of the MySQL query.
I want to do something like this. But, when I use this query I am getting an error.
for example :
SELECT * FROM user_data
where poll_title='$poll_title'
and '$voter' IN (user_vote_1,user_vote_2,user_vote_3...user_vote_10)
order by idpoll ASC
user_vote_1 to 10 (value is null'ed in the database) and I want to retrieve only that rows from a column which have $voter value.
I think you need this comparison (Not Sure OfCourse) :-
SELECT * FROM user_data
where poll_title = "$poll_title"
and (user_vote_1 = "$voter"
OR user_vote_2 = "$voter"
OR user_vote_3 = "$voter"
OR user_vote_4 = "$voter"......OR user_vote_10 = "$voter")
order by idpoll ASC
If I've understood what you want to do - return only the column with the value - then would coalesce do the job? This assumes that the value in user_vote_n will either match the value you're looking for or be null, since coalesce returns the first non-null argument.
(untested)
select coalesce(user_vote_1, user_vote_2, user_vote_3, ) as UserVote from user_data
where coalesce(user_vote_1, user_vote_2, user_vote_3, ) = '$voter';
That aside, this looks like a structure that could do with normalising - a single 'user_vote' column and a single 'user_vote_number' column.
I am new to MySQL and not too sure how can I update row from another table while checking if logged in user is the same:
Telefonist='".$_SESSION["UserName"]."
And also I need to check if date is the same so it gets to right person on right date in a row:
log.Datum=telefonisti_podaci.Datum
here I am trying to count all 1s and enter sum from table1 to table2 in specific place.
Code:
$sql_zapis_do30 = "UPDATE telefonisti_podaci
SET `Total tura do 30` = (Select COUNT(*) `Ture do 30` from log,telefonisti_podaci WHERE `Ture do 30` is not null AND `Ture do 30`=1 AND log.Datum=telefonisti_podaci.Datum )
WHERE `Telefonist`='".$_SESSION["UserName"]."'";
CustomQuery($sql_zapis_do30);
I get error:
You can't specify target table 'telefonisti_podaci' for update in FROM clause
Thanks
I have solved it like this:
$sql_zapis_do30 = "UPDATE telefonisti_podaci
SET `Total tura do 30` = (Select COUNT(`Ture do 30`) from log WHERE `Telefonist`='".$_SESSION["UserName"]."' AND `Ture do 30`=1 AND `Datum`='".$datum_danas."')
WHERE `Telefonist`='".$_SESSION["UserName"]."' AND `Datum`='".$datum_danas."'";
And it works for now
Thanks
$SQL = "
DELETE male_users from male_users
LEFT JOIN
(
select id from male_users order by date_time DESC LIMIT 0, 100
) t1
ON male_users.id=t1.id
where t1.id is null
";
if($row_male[0] > 100){
$result = $mysqli->query($SQL) or die($mysqli->error.__LINE__);
}
I'm using this query to delete all names in a list past the most recent 100.
However, each of the names have a URL of an image on the server associated with them. How can I use this query and actually get the names of each of the items its deleting into a for loop to delete their corresponding image URLs?
Typically I'd want to use unlink(URL)
With a join query such as this, how do I get the actual returned row usernames?
First SELECT to get all the image IDs, then run DELETE combined with WHERE IN, and also unlink each image.
Pseudo code would be:
SELECT image_id, image_path FROM table WHERE condition;
Fill the results into an array, then:
DELETE ... WHERE id IN (your ids) // (1, 2, 3, 5, 100)
Then loop the array, and for each do:
unlink($image_path);
You didn't show us your table structures, but that's roughly how you could do it. And don't forget you need image server path, not the url, for unlink.
I have two tables in different mysql databases.
I would like to copy from table A to table B. Only one way.
I need to read last datetime from table B and then check if there any data added to table A after this readed datetime. If there is some data added, then copy it.
I tried this:
It writes one row if I refresh page, but I need it to write everything in one load!
do
{
#TABLE A
$querylastA = "SELECT * FROM `stock` ORDER BY `jrk` DESC LIMIT 1";
$resultlastA = mysql_query($querylastA) or die(mysql_error());
while($rows=mysql_fetch_array($resultlastA)){
$lastcodeA = $rows['datetime'];
}
#TABLE B
$querylastB = "SELECT * FROM `stockcopy` ORDER BY `jrk` DESC LIMIT 1";
$resultlastB = mysql_query($querylastB) or die(mysql_error());
while($rows=mysql_fetch_array($resultlastB)){
$lastcodeB = $rows['datetime'];
}
#TABLE A - NEXT DATE AFTER LAST DATE IN TABLE B
$querynextA = "SELECT datetime FROM stock WHERE datetime > '$lastcodeB' ORDER BY datetime ASC LIMIT 1";
$resultnextA = mysql_query($querynextA) or die(mysql_error());
while($rows=mysql_fetch_array($resultnextA)){
$nextcodeA = $rows['datetime'];
}
mysql_query("INSERT INTO stockcopy(datetime, data1, data2) SELECT datetime, data1, data2 FROM stock WHERE datetime = '$nextcodeA'");
echo "Date from table A " . $lastcodeA . "<br>";
echo "Date from table B " . $lastcodeB . "<br>";
}
while ('$lastcodeA' == '$lastcodeB');
You can insert data on a table using a SELECT statement, so all you need to do is put the condition in the SELECT.
For instance:
INSERT INTO table_example(foo, bar)
SELECT foo, bar FROM table_example2
WHERE time_condition > {SOME DATE}
This will insert into table_example the rows that the SELECT statement returns, which are the ones that satisfy the time condition. You will need to replace {SOME DATE} with an actual date (without brackets).
Also, please see: INSERT with SELECT
And also: Select columns across different databases
You can do this with little to no knowledge of SQL, but with a bit of creativity :)
Create a temporary table (table_c), and copy the contents of table_a there.
Then manually (this means by running delete queries in phpmyadmim) delete the information that doesn't matter anymore ( DELETE FROM table_c WHERE id < 1000 for example ).
Then, export the info from table_c and import it into table_b (and delete table_c
Problem was in: while ('$lastcodeA' == '$lastcodeB');
Changed it to: while ($lastcodeA != $lastcodeB); now it works! Thank you all :)