Query 1:
set #userName = 'harry';
set #previousRegionId = (
select Region as RegionID
from log
where User = #userName
order by stamp desc
limit 1);
select #previousRegionId;
Query 2:
set #previousRegionId = (
select Region as RegionID
from log
where User = 'harry'
order by stamp desc
limit 1);
select #previousRegionId;
I expect the same result for both queries, but the result is different and it is reproduceable!
The log table contains same value in User column for all rows ('harry').
Changed the order by clause. Order by id works "better". Order by timestamp column is suspect ...
I am not 100% sure if this approach will work in all scenarios/aspects.
Related
I'm moving a few boolean columns from the 1st row of a generic settings table into the 1st row of a website_settings table across a few MYSQL databases. I've created the new columns in my new table with a default false value.
I have a working query to copy data from the old table:
UPDATE website_settings
SET
dark_mode_enabled = (SELECT dark_mode_enabled FROM settings ORDER BY id LIMIT 1),
header_enabled = (SELECT header_enabled FROM settings ORDER BY id LIMIT 1),
footer_enabled = (SELECT footer_enabled FROM settings ORDER BY id LIMIT 1)
LIMIT 1;
However for my own knowledge, I'm curious if there is a more cleaner way to write this, perhaps without the repetitive select queries to the same table?
You could use a join:
UPDATE website_settings ws CROSS JOIN
(SELECT s.*
FROM settings s
ORDER id DESC
LIMIT 1
) s
SET ws.dark_mode_enabled = s.dark_mode_enabled,
ws.header_enabled = s.header_enabled,
ws.footer_enabled = s.footer_enabled
LIMIT 1;
Here's a solution that does not use JOIN:
INSERT INTO website_settings (id, dark_mode_enabled, header_enabled, footer_enabled)
SELECT id, dark_mode_enabled, header_enabled, footer_enabled
FROM settings ORDER BY id LIMIT 1
ON DUPLICATE KEY UPDATE
dark_mode_enabled = VALUES(dark_mode_enabled),
header_enabled = VALUES(header_enabled),
footer_enabled = VALUES(footer_enabled);
I have a dynamic MySQL-Table with 20 columns and 1 Row where id = 1. The new data will be added to the table as the sencond row where id = 2, And so an. I need to read the newest data row (always the last id). How should I write the query to read the last row?
How should I change this:
$sql = "SELECT id, AbW_L, PuVor_L ,Durchfluss ,... FROM table order by id desc ";
Order by id descending, and limit the results to one row:
SELECT * from table order by id desc limit 1;
You might want to take a look at: http://www.techonthenet.com/sql/order_by.php
It will give you more detailed information on what to do, however based on that one line of code, just change it to:
$sql = "SELECT * FROM `table_name` ORDER BY `id` DESC";
Should work no problem. If you want to add limits, you can do:
$sql = "SELECT * FROM `table_name` ORDER BY `id` DESC LIMIT 10";
I selected 10 as the limit in the example, you can pick whatever number you would like to use.
I have a data base that I imported into a table called ip2city that contains 3 columns (startipint,endipint,country)
that is linking a given IP range (represented in integer) to a specific country
I have another table called Test2 that containing columns source and dest (INT representing IP) and empty columns countryS, countryD
I want to fill the empty columns based on the the data from the table ip2city
I am new to mysql
I tried something that looks like :
UPDATE Test2
SET CountryS = (SELECT Country FROM `ip2city` WHERE startipint <= Test2.`Source`
ORDER BY startipint DESC LIMIT 1);
where select... is suppose to return the value I want to insert to the table
but it dosnt seem to work
when I just use
SELECT * FROM `ip2city` WHERE startipint <= 3232235521 ORDER BY startipint DESC LIMIT 1
with specific ip, I get a good result so how can i use it on an entire table.. ?
Try this:
UPDATE Test2
JOIN ip2city s ON Test2.Source between s.startipint and s.endipint
JOIN ip2city d ON Test2.Dest between d.startipint and d.endipint
SET CountryS = s.country, CountryD = d.country
Note that this is a mysql-only solution, because this query uses mysql's multiple-table update syntax.
$result = mysql_query("SELECT * FROM ip2city WHERE startipint <= 3232235521 ORDER BY startipint DESC LIMIT 1");
while ($row = mysql_fetch_array($result) {
echo $row['columnname'];
Now you can use this in your UPDATE query like this:
UPDATE Test2
SET CountryS = $row['columnname']
I got two MySQL working fine and i'm trying to find a way to combine them into one single query.
First, it selects ID of an employee.
SELECT 'ID' FROM `employee` ORDER BY ID DESC LIMIT 1;
Let's say it returns ID 100;
Then update data of employees whose ID is 100
UPDATE 'LOG' SET `TIME_EXIT`='2013/02/22' WHERE `ID`='100';
Can i do it all in a single query?
Just add them together:
UPDATE LOG SET TIME_EXIT = '2013/02/22'
WHERE ID = (
SELECT ID
FROM employee
ORDER BY ID DESC
LIMIT
);
But based on that code currently it'll only ever update the last employee, you will need to select the correct employee by using some other identifier to ensure you have the correct one.
UPDATE LOG SET TIME_EXIT = '2013/02/22'
WHERE ID = (
SELECT ID
FROM employee
WHERE NAME = 'JOHN SMITH'
ORDER BY ID DESC
LIMIT 1
);
It's now a few months old, but maybe helps you or others finding this via google…
If you want to UPDATE a field in the same selected table use this:
UPDATE LOG SET
TIME_EXIT = '2013/02/22'
WHERE ID = (
SELECT ID
FROM (
SELECT ID
FROM LOG
WHERE whatEverYouWantToCheck = whateverYouNeed
) AS innerResult
)
So, you SELECT id from a subselect. If you try to subselect it directly, mySQL quites with your error message You can't specify target table 'log' for update in FROM clause, but this way you hide your subsubquery in a subquery and that seems to be fine. Don't forget the AS innerResult to avoid getting the error message #1248 - Every derived table must have its own alias. Also match the subsubquery field name to the subquery field name in case you do something like SELECT COUNT(*) or SELECT CONCAT('#', ID)
Assume the following records:
ID Value
=========
1. No
2. No
3. No
4. No
5. No
6. No
7. Yes
8. No
9. No
10. No
Each "page" of my records-display contains 5 records (so page 1 has records 1-5, page 2 has records 6-10, and so on ...). I want to display the page that contains the record with the value of Yes. Keep in mind that I don't really know where this Yes is in the records.
How do I query this?
How about something like this:
/* Work out the page */
SELECT #MatchID = ID
FROM tbl
WHERE Value = 'Yes'
ORDER BY ID ASC
LIMIT 1;
SELECT #Page = CEIL(COUNT(*) / 5)
FROM tbl
WHERE ID <= #MatchID;
/* Select the items on that page */
SET #Offset = (#Page - 1) * 5;
SELECT *
FROM tbl
ORDER BY ID ASC
LIMIT #Offset, 5;
Note: The above doesn't cater for #MatchID not being found.
I'm unsure whether MySQL limits have to be constants, hence if they do you would have to calculate the offset in PHP, or whatever programming language you're using to connect to MySQL. Alternatively, maybe this would work, instead of the last SELECT statement in the above example:
SET #selectSQL = CONCAT('SELECT * FROM tbl ORDER BY ID ASC LIMIT ', #Offset, ', 5');
PREPARE stmt FROM #selectSQL;
EXECUTE stmt;
SELECT ID FROM tbl WHERE Value = "Yes" Order by ID ASC LIMIT 1;
divide the ID through the "records-per-page" (in your case: 5).
Then you get the "page" where the first yes-record exists.
Assuming your ID is Primary Key (auto_increment) and without gaps.
SELECT Value, ID / 5 AS Page WHERE Value = "Yes"
EDIT
SELECT Value, ID DIV 5 + 1 AS Page WHERE Value = "Yes"
Alright, I think I got this now.
select all records on the same page as the record with Value = 'YES'
SET #c:=0;
SELECT tbl.* FROM tbl WHERE CEIL((#c:=#c+1) / 5) = (SELECT CEIL(COUNT(temp_table.id) / 5) FROM tbl temp_table WHERE temp_table.id <= (SELECT temp2.id FROM tbl temp2 WHERE temp2.value = 'YES')) ORDER BY tbl.id ASC;