MySQL subqueries weird behavior - mysql

I was making a query for search but the result should be obtained from three tables and it works fine for only two characters after that it returns empty rows so can anyone help please
here is my query
SELECT *
FROM tables
WHERE table2_id
IN (
SELECT id
FROM table2
WHERE table3_id
IN (
SELECT id
FROM table3
WHERE name LIKE '%in%'
)
OR
)
name LIKE 'in%'
AND id <> '8'
Any suggestions if I am making the right things and what went wrong when its more than two characters

That's a completely ridiculous query! Use a join - that's what it's for!
SELECT tables.*
FROM tables JOIN table2 ON tables.table2_id = table2.id
JOIN table3 ON table2.table3_id = table3.id
WHERE (name LIKE '%in%' OR name LIKE 'in%' AND id <> 8

Related

Mysql select from two tables where first table field = second table field%

I have two tables.
table1 has a row id='12345'
table2 has a row where the id = that of table1 with added chars, e.g.,
table2.id = '12345-678qt'
table2 may have more than one id starting with '12345-' with different ending chars.
Yes, there is always a dash after table1's id that could be used in the query.
I need to get some data from both tables, say
SELECT table1.id, table1.field9,
table2.id, table2.fieldZ
FROM table1 and table2
WHERE (
table1.id=table2.id's characters before the dash
OR
table1.field1 = 'abcde'
)
AND table2.dataB='something'
ORDER BY table1.datefield DESC LIMIT 3;
Thank you.
The MySQL translation of:
"table1 and table2 WHERE" is table1 INNER JOIN table 2 ON
"table2.id's characters before the dash" is SUBSTRING_INDEX(table2.id, '-', 1)
The query should look like this:
SELECT table1.id, table1.field9,
table2.id, table2.fieldZ
FROM table1
INNER JOIN table2
ON (table1.id = SUBSTRING(table2.id, '-', 1) OR table1.field1 = 'abcde')
AND table2.dataB = 'something'
ORDER BY table1.datefield DESC
LIMIT 3;
This doesn't grant that your query will work if it's written like this. My fixes will remove the current errors inside your query. For more troubleshooting with a sql fiddle link, please provide tables and I'll be happy to help.
Check the official documentation about the JOIN operation and the SUBSTRING_INDEX function at the corresponding links.

Count dismatch between 2 rows from 2 different tables - MySQL

I have a database with 2 tables. table1 and table2.
Table1 contains a list of tests ( column 'name' ). And I want to count how many rows are missing in table2 ( this table has also a column 'name' ) according to the list of tests of table1.
So I just want to count the mismatch between table1.name and table2.name.
I tried several querys, but all didnt really work.
I tried to use the 'NOT IN' statement but it takes too much time. Like several minutes.
For example, the output should be :
COUNT(*) = 20
It means that 20 tests are missing ( or not done yet ) in table2.
I'm using MySQL, so I can't use EXCEPT or MINUS statement.
Thank you by advance.
Nordine
You can use not exists :
select count(*)
from table1 t1
where not exists (select 1 from table2 t2 where t2.name = t1.name);
If you have a duplicate name in table1 then you need count(distinct t1.name) instead.
Try the below query:
select count(case when bname is null then 1 end)
from
(
select a.name as aname, b.name as bname from
table1 a left join table2 b
on a.name=b.name)x
MINUS can be used in MySQL.
Ref:http://www.mysqltutorial.org/mysql-minus/
Try this:
SELECT name
FROM table1
MINUS
SELECT name
FROM table2

Inner Join SQL Syntax

I've never done an inner join SQL statement before, so I don't even know if this is the right thing to use, but here's my situation.
Table 1 Columns: id, course_id, unit, lesson
Table 2 Columns: id, course_id
Ultimately, I want to count the number of id's in each unit in Table 1 that are also in Table 2.
So, even though it doesn't work, maybe something like....
$sql = "SELECT table1.unit, COUNT( id ) as count, table2.id, FROM table1, table2, WHERE course_id=$im_course_id GROUP BY unit";
I'm sure the syntax of what I'm wanting to do is a complete fail. Any ideas on fixing it?
SELECT unit, COUNT( t1.id ) as count
FROM table1 as t1 inner JOIN table2 as t2
ON t1.id = t2.id
GROUP BY unit
hope this helps.
If I understand what you want (maybe you could post an example input and output?):
SELECT unit, COUNT( id ) as count
FROM table1 as t1 JOIN table2 as t2
ON t1.id = t2.id
GROUP BY unit
Okay, so there are a few things going on here. First off, commas as joins are deprecated so they may not even be supported (depending on what you are using). You should probably switch to explicitly writing inner join
Now, whenever you have any sort of join, you also need on. You need to tell sql how it should match these two tables up. The on should come right after the join, like this:
Select *
From table1 inner join table2
on table1.id = table2.id
and table1.name = table2.name
You can join on as many things as you need by using and. This means that if the primary key of one table is several columns, you can easily create a one-to-one match between tables.
Lastly, you may be having issues because of other general syntax errors in your query. A comma is used to separate different pieces of information. So in your query,
SELECT table1.unit, COUNT( id ) as count, table2.id, FROM ...
The comma at the end of the select shouldn't be there. Instead this should read
SELECT table1.unit, COUNT( id ) as count, table2.id FROM ...
This is subtle, but the sql query cannot run with the extra comma.
Another issue is with the COUNT( id ) that you have. Sql doesn't know which id to count since table1 and table2 both have ids. So, you should use either count(table1.id) or count(table2.id)

Select both ID columns when using UNION and GROUP BY

I'm desperate with this query. I have two tables table1 and table2, tables are identical but they have different data. I'm trying to remove duplicities by columns code and manufacturer. To do that I need in final result ID from table1 ID from table2 and also columns code and manufacturer
SELECT * FROM (
SELECT id,code,manufacturer FROM table1 WHERE manufacturer = 1
UNION SELECT id,code,manufacturer FROM table2 WHERE manufacturer = 1
) AS t GROUP BY code HAVING COUNT(*) > 1
But in result i got only values from table1. It's OK but I just need to get there id from table2 too. Please can anyone give me some tips how to do this ?
You have two basic problems:
Problem 1:
You are using UNION when you should be using UNION ALL, because UNION removes duplicates!
Problem 2:
This isn't the right way to go about the problem. You should be using a simple join, not a union.
Try this:
SELECT
t1.id as table1_id,
t2.id as table2_id,
t1.code,
t1.manufacturer
FROM table1 t1
JOIN table2 t2
ON t2.code = t1.code
AND t2.manufacturer = t1.manufacturer
WHERE manufacturer = 1 -- this WHERE clause is optional
Your use of the WHERE clause is a little odd - consider removing it to get all duplicates from all manufacturers.

CASE + IF MysQL query

Problem is as follows. I have a product that can be in one of three categories (defined by category_id). Each category table has category_id field related to category_id in product table. So I have 3 cases. I'm checking If my product.category_id is in table one. If yes, I take some values. If not I check in tables that are left. What can I write In the ELSE section? Can anyone correct my query ?
CASE
WHEN IF EXISTS(SELECT * FROM table1 WHERE category_id='category_id') THEN SELECT type_id FROM table1 WHERE category_id='category_id';
WHEN IF EXISTS(SELECT * FROM table2 WHERE category_id='category_id') THEN SELECT value_id FROM table2 WHERE category_id='category_id';
WHEN IF EXISTS(SELECT * FROM table3 WHERE category_id='category_id') THEN SELECT group_id FROM table3 WHERE category_id='category_id';
ELSE "dont know what here";
END;
In the else you would put whatever you want as default value, for example null.
I think that it would be much more efficient to make three left joins instead of several subqueries for each product in the result, and use coalesce to get the first existing value. Example:
select coalesce(t1.type_id, t2.value_id, t3.group_id)
from product p
left join table1 t1 on t1.category_id = p.category_id
left join table2 t2 on t2.category_id = p.category_id
left join table3 t3 on t3.category_id = p.category_id
example
SELECT CompanyName,
Fax,
CASE WHEN IF(Fax='', 'No Fax', 'Got Fax')='No Fax' THEN NULL
ELSE IF(Fax='', 'No Fax', 'Got Fax')
END AS Note
FROM Customers;
You can possibly include this...
SELECT "Unknown type" FROM table1;
You do not need to use ELSE if there is nothing left to do.
or something like this
CASE
WHEN IF EXISTS(SELECT * FROM table1 WHERE category_id='category_id') THEN SELECT type_id FROM table1 WHERE category_id='category_id';
WHEN IF EXISTS(SELECT * FROM table2 WHERE category_id='category_id') THEN SELECT value_id FROM table2 WHERE category_id='category_id';
ELSE SELECT group_id FROM table3 WHERE category_id='category_id';
In addition to Guffa's answer here is another approach - assuming #category_id is
SET #category_id = 'some_category_id_value'
then
SELECT t1.type_id
WHERE category_id = #category_id
UNION ALL
SELECT t2.value_id
WHERE category_id = #category_id
UNION ALL
SELECT t3.group_id
WHERE category_id = #category_id
should return what you ask for (and performance is not bad either).
If you have certain category_id in more then one table you will get multiple records (you can get out of that by limiting the number of results to 1; you might need to make it the whole union a subquery and order it, but not sure, consult the docs)
However, your question looks like you have a problem with a design of your tables
why do you keep three category tables and not one?
what is the relationship between type_id, value_id and group_id and why does it make sense to select them as if they were the same thing (what is the meaning/semantics of each table/column)?
how do you guarantee that you don't have entries in multiple tables that correspond to one product (and implement other business rules that you might have)?
These questions could have valid answers, but you should know them :)