mysql: find (and display) strings that are not in a table - mysql

I have a list of strings, and I'd like to see only the ones that are not in the database.
For example I have this string: "Conducteur(trice) de bus" that is in the database:
So if I do something like:
mysql> select * from job where description = "Conducteur(trice) de bus";
+-------+--------------------------+
| id | description |
+-------+--------------------------+
| 14495 | Conducteur(trice) de bus |
+-------+--------------------------+
1 row in set (0.00 sec)
mysql>
Now if the job "Cinéaste" doesn't exist:
mysql> select * from job where description = "Cinéaste";
Empty set (0.00 sec)
mysql>
But I want the exact opposite, i.e. if the string is here I don't want a result to show up, and if it's not here, I'd like the string to show up.
Here's what I'd like for the same strings explained before:
mysql> select * from job [clause i don't know] "Conducteur(trice) de bus";
Empty set (0.00 sec)
mysql>
mysql> select * from job [clause i don't know] "Cinéaste";
+-------------+
| description |
+-------------+
| Cinéaste |
+-------------+
mysql>
So when the record is found, nothing is shown, and when it's not found, the string I was looking for is shown.
Any idea how I could do such queries with MySQL?

Edit: Try
SELECT 'Cinéaste' AS 'description' FROM `job` WHERE NOT EXISTS
(SELECT * FROM `job` WHERE description = 'Cinéaste')
LIMIT 1

You should create a table (can be a temporary table) with the list of strings to check, one per row. Let's consider you create a table named check, with a column description containing the values to be checked. Then you could use this query:
SELECT description
FROM check
WHERE description NOT IN (
SELECT DISTINCT description FROM metier
);

Related

Left Join Overrides Non-Null Value with Null value when record is empty on second table

I have two tables:
Table 1: qtrade
qtrade columns
qtrade values
Table 2: qsale
qsale columns
qsale values
These two table have common "tid" which is unique trade id. I need to get tid's with their qsale values if it is available. So, i tried to LEFT JOIN method like this:
'SELECT *
FROM `qtrade`
LEFT JOIN `qsale` ON qtrade.tid = qsale.tid'
The query retrieves joined data, but for tid=11 there is no qsale record, so it retrieves NULL valeus as expected, but also overrides tid with NULL value as not expected. It gets tid NULL.
I have serached that and found COALESCE trick. It might work, but i would write down all column names in qtrade and qsale, these are around 32 columns. Too long. If there any trick to overcome this issue. I think 'SELECT *, COALESCE(qsale.tid, qtrade.tid) tid' will not work. Meaning only coalesce tid, and get all column data. Is there any other way ?
What you describe does work.
Demo:
mysql> create table qtrade (tid int);
Query OK, 0 rows affected (0.01 sec)
mysql> create table qsale (tid int);
Query OK, 0 rows affected (0.01 sec)
mysql> insert into qtrade set tid=42;
Query OK, 1 row affected (0.01 sec)
mysql> SELECT *
-> FROM `qtrade`
-> LEFT JOIN `qsale` ON qtrade.tid = qsale.tid;
+------+------+
| tid | tid |
+------+------+
| 42 | NULL |
+------+------+
1 row in set (0.00 sec)
mysql> SELECT *, COALESCE(qsale.tid, qtrade.tid) AS tid
FROM `qtrade` LEFT JOIN `qsale` ON qtrade.tid = qsale.tid;
+------+------+------+
| tid | tid | tid |
+------+------+------+
| 42 | NULL | 42 |
+------+------+------+
1 row in set (0.00 sec)
MySQL query result sets allow multiple columns to have the same name.
But the problem arises when you have a client that fetches the results into an associative array or hashmap, which only allows one entry per name.
In that case, the only alternative is to change the client code to fetch results into an ordinal array instead of an associative array, and then reference the columns of the result by position instead of by name.
I never use SELECT * in production code anyway. Just write out the columns. If typing 32 column names is the bottleneck in your programming productivity, then you're doing it wrong.

SELECT rows NOT ending in a specific character

I have a table of questions. I need to find rows which have '?' in the question text because of bad character encoding/collation. I need to find all the rows which have '?' but also need to ignore the question marks at the end of the questions. I tried this query but I still get rows with questions marks at end of the question
SELECT *
FROM `kc_questions`
WHERE `question` LIKE "%?%" /* WHICH CONTAINS '?' */
AND `question` NOT LIKE "%?" /* DOES NOT END WITH '?' */
EDIT: phpmyadmin actually tells me there is something wrong with the query:
The query however runs successfully returning rows which end with'?'.
Based on the sample data I tried the following demo and it works as expected.
SQL:
create table kc_questions(question varchar(200));
insert into kc_questions values
('Ex1. ?-particles are harmul for human body. Select True or False.'),
('Ex2. What is your name?');
SELECT question FROM kc_questions;
SELECT *
FROM `kc_questions`
WHERE `question` LIKE "%?%"
AND `question` NOT LIKE "%?";
Output:
mysql> SELECT question FROM kc_questions;
+-------------------------------------------------------------------+
| question |
+-------------------------------------------------------------------+
| Ex1. ?-particles are harmul for human body. Select True or False. |
| Ex2. What is your name? |
+-------------------------------------------------------------------+
2 rows in set (0.00 sec)
mysql> SELECT *
-> FROM `kc_questions`
-> WHERE `question` LIKE "%?%"
-> AND `question` NOT LIKE "%?";
+-------------------------------------------------------------------+
| question |
+-------------------------------------------------------------------+
| Ex1. ?-particles are harmul for human body. Select True or False. |
+-------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> select version();
+-----------+
| version() |
+-----------+
| 5.7.8-rc |
+-----------+
1 row in set (0.00 sec)
You could use a regular expression
SELECT *
FROM `kc_questions`
WHERE `question` REGEXP '.*\?.+$'
Basicly you search for questions which contains '?' with at least one character after the '?'

MySQL SELECT returns empty set when there is data

mysql> SELECT title FROM pages WHERE id=111;
+------------+
| title |
+------------+
| 'Theology' |
+------------+
1 row in set (0.00 sec)
mysql> SELECT id FROM pages WHERE title='Theology';
Empty set (0.00 sec)
The results conflicted. I can't understand that.
Change
'Theology'
to
'\'Theology\''
Seems that the data stored is 'Theology' instead of Theology. Thanks to Abhik Chakraborty.
Use query like this . You need to escape the '
1st Way
SELECT id FROM pages WHERE title = '\'Theology\''
2nd Way
SELECT id FROM pages WHERE title = "'Theology'"
3rd Way
SELECT id FROM pages WHERE title='''Theology''';

searching multiple columns with one or more keywords using sql

I have one search box that I would like to have search 6 columns in my schools database when an input is made. So far the search box searches the name field only and returns a match for exact or partial inputs.
I would like to search for a specific city and have all results show up from the name AND city columns (instead of just the name column) and so on.
Say I wanted to search with a zip code, I would like the listings to be all schools in that zip code. And finally if I input 2 words (e.g. penn Philadelphia) I would like all penn schools to show that are in the name column AND city column only. (not just all the penns in the name or every school in Philadelphia) and so on. These may be an elementary questions on the matter but I've been searching for days with no success. Maybe better use of wildcards and the "AND" "OR" clauses would benefit me.
Can someone help me structure a sql query to accomplish this?
this is what I have so far:
SELECT * FROM schools
WHERE (name='%name%' OR address='%name%' OR city='%name%'OR zip='%name%')
There are few ways to do that-
The very basic strategy is to match input with our table columns by the query like as you mentioned -
1. SELECT * FROM table WHERE (name='%name%' or zip='%name%' or city='%name%');
2. SELECT * FROM table WHERE LOCATE(name, GROUP_CONCAT(name,city,zip)) > 0;
3.
SELECT * FROM table WHERE name like '%name%'
UNION
SELECT * FROM table WHERE name like '%name%'
UNION
SELECT * FROM table WHERE name like '%name%';
but suppose the case where input box have the string- "varun bharti" but actual name in database is "varun bal bharti" So when you search you will missed the record. for that case you should break the string by space in to array elements and use these queries for elements or either you can replace the space in name column and match.
set #var=REPLACE ('varun bharti', ' ', '%');
SELECT * FROM table WHERE name like concat('%',#var,'%') or
zip like concat('%',#var,'%') or
city like concat('%',#var,'%');
You can also use regualar expressions for that.
For example input string the day boss get
Hitesh> select * from test;
+--------------------+
| name |
+--------------------+
| i am the boss |
| You will get soon |
| Happy birthday bro |
| the beautiful girl |
| oyee its sunday |
+--------------------+
5 rows in set (0.00 sec)
Hitesh> set #var=CONCAT('.*',REPLACE('the day boss get',' ','.*|.*'),'.*');
Query OK, 0 rows affected (0.00 sec)
Hitesh> select #var;
+----------------------------------+
| #var |
+----------------------------------+
| .*the.*|.*day.*|.*boss.*|.*get.* |
+----------------------------------+
1 row in set (0.00 sec)
Hitesh> select * from test where name REGEXP #var;
+--------------------+
| name |
+--------------------+
| i am the boss |
| You will get soon |
| Happy birthday bro |
| the beautiful girl |
| oyee its sunday |
+--------------------+
5 rows in set (0.00 sec)

MySQL : When stored procedure parameter name is the same as table column name [continue]

Let's say a have a stored procedure SetCustomerName which has an input parameter Name, and I have a table customers with column Name. So inside my stored procedure I want to set customer's name. If I write
UPDATE customers SET Name = Name;
this is incorrect and I have to write (for example)
UPDATE customers SET `Name` = Name;
So, there is a link about backticks (http://dev.mysql.com/doc/refman/5.0/en/identifiers.html) but it's not explained deep enough how to use them (how to use them with parameters and column names).
And there is a very strange thing (at least for me): You can use backticks either way:
UPDATE customers SET Name = `Name`;
//or
UPDATE customers SET `Name` = Name;
//or even
UPDATE customers SET `Name` = `Name`;
and they all work absolutely the same way.
Don't you think this is strange? Is this strange behavior explained somewhere?
I do not understand why you need to escape using backticks in the first place.
In a statement UPDATE x SET a = b, a must always refer to a column of x. b however can either be a variable or a column. Given how local scope and variable resolution works in stored procedures, b will always refer to the local variable, even if a column with the same name in x exists.
Thus, I am unable to reproduce your problem. I tried this way:
mysql> SELECT * FROM comments;
+----+-----------+---------+
| id | parent_id | content |
+----+-----------+---------+
| 1 | 0 | bar |
| 2 | 0 | baz |
+----+-----------+---------+
2 rows in set (0.00 sec)
mysql> delimiter //
mysql> CREATE PROCEDURE foo(IN content TEXT)
-> BEGIN
-> UPDATE comments SET content = content;
-> END //
Query OK, 0 rows affected (0.00 sec)
mysql> delimiter ;
mysql> CALL foo('changed!');
Query OK, 2 rows affected (0.00 sec)
mysql> SELECT * FROM comments;
+----+-----------+----------+
| id | parent_id | content |
+----+-----------+----------+
| 1 | 0 | changed! |
| 2 | 0 | changed! |
+----+-----------+----------+
2 rows in set (0.00 sec)
As you can see, the comment-table's column content gets updated, even though content is also the name of the parameter of the stored procedure foo.
Are you sure that UPDATE customers SET Name = Name; gives you an error?
With the above explanation, it seems logical that
UPDATE customers SET Name = `Name`;
UPDATE customers SET `Name` = Name;
UPDATE customers SET `Name` = `Name`;
all have the same effect.
Edit: The situation would be different for SELECT statements, of course.