MySQL select all from list where value not in table - mysql

I cannot create a virtual table for this. Basically what I have, is a list of values:
'Succinylcholine','Thiamine','Trandate','Tridol Drip'
I want to know which of those values is not present in table1 and display them. Is this possible? I have tried using left joins and creating a variable with the list which I can compare to the table, but it returns the wrong results.
This is one of the things I have tried:
SET #list="'Amiodarone','Ammonia Inhalents','Aspirin';
SELECT #list FROM table1 where #list not in (
SELECT Description
FROM table1
);

With only narrow exceptions, you need to have data in table form to be able to obtain those data in your result set. This is the essential problem that all attempts at a solution to this problem run into, given that you cannot create a temporary table. If indeed you can provide the input in any form or format (per your comment), then you can provide it in the form of a subquery:
(
SELECT 'Amiodarone' AS description
UNION ALL
SELECT 'Ammonia Inhalents'
UNION ALL
SELECT 'Aspirin'
)
(Note that that exercises the biggest of the exceptions I noted: you can select scalars directly, without a base table. If you like, you can express that explicitly -- in MySQL and Oracle, at least -- by selecting FROM DUAL.)
In that case, this should work for you:
SELECT
a.description
FROM
(
SELECT 'Amiodarone' AS description
UNION ALL
SELECT 'Ammonia Inhalents'
UNION ALL
SELECT 'Aspirin'
) a
LEFT JOIN table1
ON a.description = table1.description
WHERE table1.description IS NULL

That won't work. the variable's contents will be treated as a monolithic string - one solid block of letters, not 3 separate comma-separated values. The query will be parsed/executed as:
SELECT ... WHERE "'Amio.....rin'" IN (x,y,z,...)
^--------------^--- string
Plus, since you're just doing a sub-select on the very same table, there's no point in this kind of a construct. You could try mysql find_in_set() function:
SELECT #list
FROM table1
WHERE FIND_IN_SET(Description, #list) <> ''

Related

mySQL "IN" function to Return the list of not found

Just wanted to ask if this is possible or a way to determine the strings that is not on my table. for example
select name from table_person where name IN('name1','name2','name3')
scenario is name1 and name2 is available on my table but what I want to display is name3, since I want to know what are the things I haven't added.
Just playing around with the worst approach (may be).
Not Recommended
SELECT
suppliedArgTable.name
FROM
(
SELECT 'name1' AS name
UNION
SELECT 'name2'
UNION
SELECT 'name3'
) AS suppliedArgTable
LEFT JOIN
table_person TP ON TP.name = suppliedArgTable.name
WHERE TP.name IS NULL;
http://sqlfiddle.com/#!9/edcbe/2/0
NOT IN combined with reversing your query is a solution.
With the 'list' ('name1','name2','name3') in a (temporary) table e.g. temp_list
and with the data in table_person
the query would be:
select name from temp_list
where name not in (
select distinct(name) from table_person
)
distinct removes doubles. (see also MySQL: Select only unique values from a column)
SELECT name_field
FROM (VALUES('name1'),
('name2'),
('name3'),
('name4'),
('name5')) V(name_field)
EXCEPT
SELECT name_field
FROM name_table
You can use a temporary table to hold a list of all names and find non-matching names with EXCEPT.

Find out values which are not available in table

Let assume Following simple table
Col1
======
one
two
Let assume Following simple query
Select count(*) from TABLE_A where Col1 in ('one','two','three','four')
In above query it will produce following result
2
Now I want to find out what are the values in IN- condition which is not available in table_A.
How to find out that values which are not available in table?
like below result
three
four
Above queries only example. In my real time query in have 1000 values in IN-Condition.
Working Database : DB2
This is the one of the work around to achieve your expectation.
Instead of hard-coding the values in IN condition, you can move those values in to a table. If it done simply using LEFT JOIN with NULL check you can get the not matching values.
SELECT MR.Col1
FROM MatchingRecords MR -- here MatchingRecords table contains the IN condition values
LEFT JOIN Table_A TA ON TA.Col1 = MR.Col1
WHERE TA.Col1 IS NULL;
Working DEMO
If the values are to be listed in the statement string rather than stored in a table, then perhaps a revision to the syntax being used for that list of values currently being composed [apparently, from some other input than a TABLE] for the IN predicate can be effected? The following revised syntax for a list of values could be used both for the original aggregate query [shown immediately below as the first of two queries], and for the query for which the how-to-code is being asked [the second of the two queries below]:
Select count(*)
from TABLE_A
where Col1 in ( values('one'),('two'),('three'),('four') )
; -- report from above query follows:
COUNT ( * )
2
[Bgn-Edit 05-Aug-2016: adding this text and example just below]Apparently at least one DB2 variant balks at unnamed columns for the derived table, so the query just below names the column; I chose COL1, so as to match the name from the actual TABLE, but that should not be necessary. The (col1) is added to the original query that remains from the original pre-edit version; that version remains after this edit\insertion and is missing the (col1) added here:
select *
from ( values('one'),('two'),('three'),('four') ) as x (col1)
except ( select * from table_a )
; -- report from above query follows:
COL1
three
four
The following is the original query given, for which the comment below suggests a failure for an unnamed column when run on some unstated DB2 variant; I should have noted that this SQL query functions without error, on DB2 for i 7.1
[End-Edit 05-Aug-2016]
select *
from ( values('one'),('two'),('three'),('four') ) as x
except ( select * from table_a )
; -- report from above query follows:
VALUES
three
four

SQL: Order by a list of foreign_key numbers

A simplified example:
I have a SQL table called things. Things by themselves have an id and a name. Things are part of a tree, e.g. a thing can have a parent; Exactly how to this is stored is not important, important is however that it is possible to obtain a list of thing ids from the root node to the current thing.
I have another table, called properties. A property has a thing_id column, a name column and a value column.
I now want, for the current thing, to obtain all properties, ordered by thing_id, in order of the paths from root thing to current thing.
e.g., if the current thing is nested like this: Root(1) > Vehicle(4) > Car(2) > Hybrid(3), I would want the list of properties be returned with the properties that have a thing_id==1 first, followed by the ones with thing_id == 4, then thing_id==2 and finally thing_id==3.
How can this be done using SQL? (without using N+1 selects)
In SQL this can be achieved with use of recursive query. Here is an example
DECLARE #item as varchar(10)
with CTE (main_part, sub_part, NestingLevel)
as
(
select main_part, sub_part, 1 from tblParts
where main_part = #item
union all
select tblParts.main_part, tblParts.sub_part, (NestingLevel + 1) from tblParts
inner join CTE on tblParts.main_part = CTE.sub_part
)
select * from CTE
In order to address this in MySQL you can try temporary table approach. Here is a good example of it: How to do the Recursive SELECT query in MySQL?

Split the field value in a mysql JOIN query

I've got a column "code" which may have a string of multiple values e.g. "CODE1&CODE2"... I just need the first one for my JOIN ... kind of like code.split("&")[0]
SELECT myTable.*, otherTable.id AS theID
FROM myTable INNER JOIN otherTable
ON myTable.(+++ code before the & +++) = otherTable.code
The value in myTable may also just be CODE1
SUBSTRING_INDEX will do exactly what you want - return the substring of your column up to the specified character:
SELECT
myTable.*,
otherTable.id AS theID
FROM myTable
INNER JOIN otherTable
ON SUBSTRING_INDEX(myTable.code, '&', 1) = otherTable.code
More info at: http://dev.mysql.com/doc/refman/5.0/en/string-functions.html
And here's a fiddle demoing it: http://sqlfiddle.com/#!2/96a6e/2
Please note that this will be SLOW if you're joining many columns. You're not only eliminating the possibility of using an index, but performing a very slow string operation on every comparison. I wouldn't suggest using this on very large tables. If your data set is huge, you may want to consider rearchitecting your DB.

Mysql Query from Two table

Is it possible to join Two queries of mysql in a query ??
Like:
select * from a + select * from b
So that I can use them in a single php loop.
If they have the same number of columns and the datatypes are the same in each column, then you can use a UNION or UNION ALL:
select *
from a
UNION ALL
select *
from b
If you provide more details about the tables, data, etc, then there might be another way of returning this data.
A UNION will return only the DISTINCT values, while a UNION ALL selects all values.
If this is the route that you need to take, and you still need to identify which table the data came from, then you can always create a column to identify which table the data is from , similar to this:
select *, 'a' TableName
from a
UNION ALL
select *, 'b' TableName
from b
This allows you to distinguish what table the data came from.
I think it is easier creating sql "variables" like:
select varA, varb from TableA, tableB;
and you can just play with values in PHP accessing properties.
That way you can take conditions in the query like:
select varA, varb from TableA, tableB where varA.id = varB.foreingId bla bla...
;)