MySQL query - condition (comparing strings) does not work - mysql

My table has only got 1 Column 'Name' with 100 unique entries.
I need to find out if a given Value exists in that table.
I am using:
SELECT 1 FROM `tbl_names` WHERE `Name` = "Lisa"
MySQL returns an empty result, so no 0 for not found and no 1 for found, even though the given name is an entry in that table.
What am I missing here?

select count(*) from tbl_name where name = 'Lisa' - will return count of entries with Lisa in the column. You can do as before with select 1, and calculate results - zero size means no occurance

If you want to return as 0 or 1, I would suggest:
select (exists (select 1 from tbl_names where Name = 'Lisa')) as flag
This will not fix the problem that you describe -- but it will always return one row with a single column whose value is 0 or 1.
'Lisa' is not in the table. You might try where Name like '%Lisa%'.

Related

Query with offset returns overlapping data sets

Initial attempts at getting a very simple pagination, using fetch n rows and then a subsequent call with offset, gives overlapping entries in Oracle.
I was expecting the following to give me two unique sets of results. 1-100 and then 101-200 of the results that would have been returned if the first line had been set with a limit of 200.
select * from "APPR" /*+ index(APPR APPR_IDX01) */ where ("APPROVER" = 'A') or ("APPROVER" > 'A') order by "APPROVER" fetch first 100 rows only ;
select * from "APPR" /*+ index(APPR APPR_IDX01) */ where ("APPROVER" = 'A') or ("APPROVER" > 'A') order by "APPROVER" offset 100 rows fetch next 100 rows only ;
So if there are 150 items for approver A the first results should be:
A, item1
....
A, item100
The subsequent call (offset by 100) giving
A, item101
...
A, item150
B, item1
B, item2
....
B, item201
Unfortunately the second set contains some entries from the first batch of values. Probably a really silly error, but I can't find an explanation as to why this should happen.
---- Updated as a result of comments
The Primary key consists of Approver and several other fields which together form a composite and unique primary.
The code will be called through ODBC and will be used on Oracle and MySQL back-end.
In Oracle, if you make "order by" to a column containing same values (like you have - 'A', 'A', 'A' ...) the order of records inside 'A' values will be random.
Please try to change your queries to ... order by "APPROVER", rowid ...
Presumably, APPROVER is not a unique column. Since there may be duplicates, the order by claus is not stable, and the offset clause might generate duplicates.
A simple solution is to add more columns to the order by to break the ties. Assuming that (approver, item) is a unique set of columns, that would be:
select *
from appr
where approver = 'A' or approver > 'A'
order by approver, item
fetch first 100 rows only
-- then: offset 100 rows fetch next 100 rows only
Notes:
there is no need to surround all-caps identifiers (tables or column names) with double quotes: that's the default in Oracle already
parentheses around the or conditions are superfluous in this simple case
if approver is always one character long, then the where clause can be simplified as where approver >= 'A'
use index hints only if you really know why you are doing it (I am not saying you don't, but I removed it, just in case); most of the time, the database knows better

Mysql querying with id and last_name yields 0 results

In mySql When I search with id and last name I see no results. Below
SELECT * FROM TableName
WHERE id = '-2105192515' AND last_name='JOHNSON'
0 Results ----- (id = mzb_indiv_id)
But when searching with only Id I get one record match. Below is the query
SELECT * FROM TableName
WHERE id = '-2105192515'
1 Record match . --- (id = mzb_indiv_id)
Also when searching with last_name I see the results too. But why is there a difference between the above two searches?
The first query only returns a row if it has that id and also has that last_name, in the same row.
(It does not mean : rows with this id and also rows with that last name.)
I guess the result from your second query doesn't have the last_name JOHNSON?
Perhaps you want an OR rather than an AND?
Edit
Your example data has ' JOHNSON' rather than 'JOHNSON' (an extra space at the start)
Try last_name LIKE '%JOHNSON%' or TRIM(last_name) = 'JOHNSON'
From your question, first thing I found
SELECT * FROM TableName
WHERE id = '-2105192515'
AND last_name='JOHNSON'
Here column name is 'last_name' but in in info below you wrote column name 'last_Name'.
Check your column names, as the missing column would give error in executing, so it is highly unlikely.
Second thing: are you spelling 'JOHNSON' the same way it is stored in your database? no spaces included?.
Please, post the result set with both queries to get a proper, and more valid answer.
The row which id is -2105192515 has a last_name column value which is not equal to JOHNSON
SELECT * FROM TableName
WHERE id = '-2105192515' AND last_name='JOHNSON'
This query means - return all the rows that their id = '-2105192515' AND the last_name='JOHNSON'
You may have wanted to use OR instead?

Subquery returns more than 1 row. Using SQL select to update a different tables results

I am trying to update a column in the following table 'jobqueue' using the results from a SELECT query performed on the 'mdtinfo' table.
The column I am trying to update is called ignore and I need to set the value to 1 from its default of 0.
update jobqueue
set jobqueue.`ignore`= '1'
where (SELECT JobQueue_job_queue_id
FROM mdtinfo
WHERE product_name = 'Example')
The above query returns the following error: SQL Error (1242): Subquery returns more than 1 row.
When running the select query on it's own it returns results successfully.
In MySQL, a value of zero appearing in a WHERE clause means false.
So, UPDATE something SET col=val WHERE (SELECT colx FROM sometable) has the potential to be a valid query. If the inner SELECT gets just one row, and its colx column has the value 0, the update won't do anything. If the colx column has a nonzero value the query means UPDATE something SET col=val WHERE true. Accordingly, every row in sometable will be updated. I doubt that's what you want.
If the inner SELECT happens to return more than one row, the query isn't valid. You'll get the error 1242 you actually received.
(This business of interpreting numbers as Boolean values causes MySQL to accept some otherwise dodgy query syntax, like the syntax in your question.)
I guess you want to retrieve the job_queue_id values for the row or rows you actually want to update. So try something like this.
update jobqueue
set jobqueue.`ignore`= '1'
where jobqueue.job_queue_id IN (SELECT JobQueue_job_queue_id
FROM mdtinfo
WHERE product_name = 'Example')
I guessed you have a column jobqueue.job_queue_id. You didn't tell us what columns you have in jobqueue.
update jobqueue
set jobqueue.`ignore`= '1'
where jobqueue.`job_queue_id` IN (SELECT GROUP_CONCAT(JobQueue_job_queue_id)
FROM mdtinfo
WHERE product_name = 'Example' GROUP BY product_name)
you should write column name in where condition.

mySQL/SQlite subtractive query

I need a query in which it starts off by selecting the entire table, then there would be a few more querys that would remove entries from the first query. Ive accomplished this by using several querys and then comparing the results in my application. I was wondering if I can accomplish this in a single query.
Algorithm
Select All AccountIDs from table
Select AccountIDs from table where parameter1 = true
Remove those matches from the original query result
Select AccountIDs from table where parameter2 = true
Remove those matches from the remaining query result
and so on up to N parameters.
This would need to also be compatible with both mySQL and SQLite
I think you are looking for this:
SELECT AccountID FROM the_table
LEFT JOIN (
SELECT AccountID FROM the_table
WHERE
parameter1 = true OR
... OR
parameterN = true ;
) AS not_included USING (AccountID)
WHERE not_included.AccountID IS NULL -- only items with no match in the "not_included" sub-query
The not_included subquery returns all items for which any parameter is set to TRUE. You actually want to exclude these records from your final result set.
Then LEFT-JOIN the_table (i.e. all items) to this sub-result. The WHERE...IS NULL clause excludes items present in the_table but not present in not_included.
Therefore only items which you do not want to exclude remain in the final result set.
The most direct way to implement your algorithm is to use a compound SELECT statement:
SELECT AccountID FROM MyTable
EXCEPT
SELECT AccountID FROM MyTable WHERE parameter1 = 1
EXCEPT
SELECT AccountID FROM MyTable WHERE parameter2 = 1
However, this is also possible with a single WHERE expression:
SELECT AccountID
FROM MyTable
WHERE NOT (parameter1 = 1 OR
parameter2 = 1 OR
...)

Returning a value even if no result

I have this kind of simple query that returns a not null integer field for a given id:
SELECT field1 FROM table WHERE id = 123 LIMIT 1;
The thing is if the id is not found, the resultset is empty. I need the query to always return a value, even if there is no result.
I have this thing working but I don't like it because it runs 2 times the same subquery:
SELECT IF(EXISTS(SELECT 1 FROM table WHERE id = 123) = 1, (SELECT field1 FROM table WHERE id = 123 LIMIT 1), 0);
It returns either field1 if the row exists, otherwise 0. Any way to improve that?
Thanks!
Edit following some comments and answers: yes it has to be in a single query statement and I can not use the count trick because I need to return only 1 value (FYI I run the query with the Java/Spring method SimpleJdbcTemplate.queryForLong()).
MySQL has a function to return a value if the result is null. You can use it on a whole query:
SELECT IFNULL( (SELECT field1 FROM table WHERE id = 123 LIMIT 1) ,'not found');
As you are looking for 1 record, (LIMIT 1) then this will work.
(SELECT field1 FROM table WHERE id = 123)
UNION
(SELECT 'default_value_if_no_record')
LIMIT 1;
Can be a handy way to display default values, or indicate no results found. I use it for reports.
See also http://blogs.uoregon.edu/developments/2011/03/31/add-a-header-row-to-mysql-query-results/ for a way to use this to create headers in reports.
You could include count(id). That will always return.
select count(field1), field1 from table where id = 123 limit 1;
http://sqlfiddle.com/#!2/64c76/4
You can use COALESCE
SELECT COALESCE(SUM(column),0)
FROM table
If someone is looking to use this to insert the result INTO a variable and then using it in a Stored Procedure; you can do it like this:
DECLARE date_created INT DEFAULT 1;
SELECT IFNULL((SELECT date FROM monthly_comission WHERE date = date_new_month LIMIT 1), 0)
INTO date_created
WHERE IFNULL((SELECT date FROM monthly_comission WHERE date = date_new_month LIMIT 1), 0) = 0;
With this you're storing in the variable 'date_created' 1 or 0 (if returned nothing).
Do search with LEFT OUTER JOIN. I don't know if MySQL allows inline VALUES in join clauses but you can have predefined table for this purposes.
k-a-f's answer works for selecting one column, if selecting multiple column, we can.
DECLARE a BIGINT DEFAULT 1;
DECLARE b BIGINT DEFAULT "name";
SELECT id, name from table into a,b;
Then we just need to check a,b for values.
if you want both always a return value but never a null value you can combine count with coalesce :
select count(field1), coalesce(field1,'any_other_default_value') from table;
that because count, will force mysql to always return a value (0 if there is no values to count) and coalesce will force mysql to always put a value that is not null