MySQL UPDATE and SELECT from same table in subquery - mysql

First off, I know this is impossible as of MySQL 5.1.x, it says so right here:
http://dev.mysql.com/doc/refman/5.1/en/update.html
What I'm asking though is if there is a clever way to execute a query using either a temporarily table/view without having to resort to writing a quick script to do the work. My query (which is COMPLETELY WRONG and DOES NOT work, just an FYI for folks trying this at home) looks something like this:
UPDATE some_table
set some_col = ( SELECT some_othercol
from some_table
WHERE some_col > some_othercol
);
I'm trying to ultimately set some_col to the value of some_othercol if sol_col > some_othercol.
What's the best way to handle this without resorting to a script?
EDIT
My subquery returns more than one row!

I don't really understand why you need a subquery. Doesn't this do what you want?:
UPDATE some_table
SET some_col = some_othercol
WHERE some_col > some_othercol

I'm not sure if this is quite what you're trying to do, but maybe I can show you something to put you on the right path.
UPDATE some_table ST
SET some_col = (
SELECT some_col
FROM some_table OT
WHERE OT.ID = ST.ID
)
WHERE ST.some_col > 2
That will set some_col to its own value, but only when some_col is already greater than 2. I know this doesn't do anything, but it shows a concept that may be closer to what you're looking for. If you give some more detail as to what you what to happen in the end, I can possibly help you find a solution closer to what you need.

http://www.xaprb.com/blog/2006/06/23/how-to-select-from-an-update-target-in-mysql/ is the best resource I know on that subject.

Related

SQL Query - Select a value, then use it again in following statements

I've tried looking it up, and while I think this should be possible I can't seem to find the answer I need anywhere.
I need to lookup a date from one table, then store it for use in a following query.
Below is statements that should work, with my setting the variable (which I know won't work, but I'm unsure the best way to do/show it otherwise - bar maybe querying it twice inside the if statement.)
I'm then wanting to in the latter statement, use either the date given in the second query, or if the date from the first query (that I'm thinking to set as a variable) is newer, use that instead.
startDateVariable = (SELECT `userID`, `startDate`
FROM `empDetails`
WHERE `userID` = 1);
SELECT `userID`, SUM(`weeksGROSS`) AS yearGROSS
FROM `PAYSLIP`
WHERE `date` <= "2021-11-15"
AND `date` >= IF( "2020-11-15" > startDateVariable , "2020-11-15" , startDateVariable )
AND `userID` IN ( 1 )
GROUP BY `userID`
Naturally all dates given in the query ("2021-11-15" etc) would be inserted dynamically in the prepared statement.
Now while I've set the userID IN to just query 1, it'd be ideal if I can lookup multiple users this way at once, though I can accept that I may need to make an individual query per user doing it this way.
Much appreciated!
So turns I was going about this the wrong way, looks like the best way to do this or something similar is by using SQL JOIN
This allows you to query the tables as if they are one.
I also realised rather then using an IF, i could simply make sure i was looking up newer or equal to both the date given and the start date.
Below is working as required. And allows lookup of multiple users at once as wanted.
SELECT PAYSLIP.userID, employeeDetails.startDate, SUM(PAYSLIP.weeksGROSS) AS yearGROSS
FROM PAYSLIP
INNER JOIN employeeDetails ON employeeDetails.userID=PAYSLIP.userID
WHERE PAYSLIP.date <= "2021-11-15"
AND PAYSLIP.date >= "2020-11-15"
AND PAYSLIP.date >= employeeDetails.startDate
AND PAYSLIP.userID IN ( 1,2,8 )
GROUP BY PAYSLIP.userID
See here for more usage examples: https://www.w3schools.com/sql/sql_join.asp
However along the lines of my particular question, it's possible to store variables. I.E.
SET #myvar= 'Example showing how to declare variable';
Then use it in the SQL statement by using
#myvar where you want the variable to go.

MySQL AND & OR operator

What is an operator in MySQL queries that covers AND and OR. So if I wanted to select a row where value1=lol OR value2=loly or both do.
this will look for one of the values or both.
SELECT * FROM my_table WHERE your_column IN ( 'lol','loly' )
With a query with the OR it'll work:
SELECT * FROM my_table WHERE my_field = 'lol' OR my_field = 'loly'
it'll give you all the results with the first or the second
As an extra, I think you could be looking for WHERE with regular expressions: Check this manual page: https://dev.mysql.com/doc/refman/5.1/en/regexp.html
Sorry, this wasn't a very good question.
I now understand that the OR operator will work with either condition met, or both.
AND only works with both.
XOR works with either one but not both.
Credit goes to the comments replying to my question.

Is it possible to SQL inject into this query?

So basically, in my PHPMYADMIN I'm toying around with SQL injections so that I can eventually become a pen tester
SELECT *
FROM `ip` as ipstr
WHERE 'id' = $USERINPUT_HERE
ORDER BY
ipstr.id ASC
LIMIT 0 , 30
I'm having difficulty because it says that 'ipstr' is no longer defined when I try to inject it into my phpmyadmin.
I know that if it were a subquery, I would be able to do this. But its not a subquery, so how can I make something like the following work?
SELECT *
FROM `ip` as ipstr
WHERE 'id' = $USERINPUT_HERE
UNION ALL SELECT 1,2,3,4,5
ORDER BY
ipstr.id ASC
LIMIT 0 , 30
Somebody I know is saying it is possible to do this kind of injection, but I cannot figure out how to do it without rewriting the whole query and using subqueries. Thanks.
Let's see. If the string contained ''; delete ip; select * from (select 1 as id) ipstr, then the code might do something you don't expect. (To be honest, the entire statement might get rejected because it is multiple statements, but this is an example.)
The solution to SQL injection is to use parameterized queries. This is not a hard concept. And it is a good habit. You should get into that habit.

mySql new rows can only be searched with LIKE, has anyone had this before?

A bit of background
I'm running mySQL on a mac
I have a few databases setup that have been working okay
I have recently created a new table from a sqlDump from another server.
I am having an issue with new rows that equal = a value that I know exists
e.g. Table setup
id=1 name='dave' - already exists in database
id=2 name='john' - I add a new row
Following are the sql I tried with results...
Select * from tablename where id=1 -- I get the correct Dave result.
Select * from tablename where `name` = 'dave' -- I get the correct Dave result.
Select * from tablename where id=2 -- I get the correct John result.
Select * from tablename where `name` like 'joh%' -- I get the correct John result.
Select * from tablename where `name` = 'john' -- (No result!) eek!
Anyone seen this before? it's in the database but a direct match on the name field is not yielding a result.
Thanks in advance
M
One possibility: there could be a trailing space after 'john' in the name column.
One way to check that:
select `name`,char_length(`name`), char_length('john')
from tablename
where id = 2
An easy way to not have to deal with that problem would be to trim your input (if you don't expect to ever have preceding or trailing white space.
In that case you could have a query like:
Select * from tablename where trim(`name`) = trim('john')
I agree with the comments on your question, that it is most likely a hidden space or something similar. If you include the column definitions so we can check the data that your using with the types we could help more. Remove the entry and and retry with a different name other than john and see if you can replicate the problem.

mysql query, reuse columnnames in query

I have a mysql query, something like this:
SELECT users*100 as totalusers, totalusers*90 AS totalsalerys FROM table
As you can see I want to reuse the totalusers when calculating totalsalerys so I son't have to write the same code again. That dosen't seem to work in mysql, is there another easy way to do this?
My query is just an example, change the *100 and *90 to some very long formula and you might see what i mean..
SELECT (#r := users * 100) as totalusers,
#r * 90 AS totalsalerys
FROM table
You can also use a subquery as #Tom Ritter advices, but it's not friendly to ORDER BY ... LIMIT ... clause.
In MySQL, all results of the inner subquery will be fetched before applying any filters in the outer subquery.
I believe you would have to copy/paste the formula or use a subquery. The below would work in T-SQL, but I imagine it'd work in MySQL as well since it's pretty simple.
SELECT
x.totalusers, x.totalusers*90 AS totalsalerys
FROM (
SELECT users*100 as totalusers FROM table
) x