CASE + IF MysQL query - mysql

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 :)

Related

MYSQL with multiple SUBQUERIES

Hi and thanks for reading.
SELECT DISTINCT (thisID and thisNAME) from table1 WHERE thisID IN
(SELECT id from table2 WHERE ... condtions)
OR
(SELECT id from table3 WHERE ... different condtions)
OR
(SELECT id from table99 WHERE ...even more conditions)
I need to perform a few SELECTS to provide a nu,ber of thisID's once I have these I need to select only thethisID and thisNAME from the table 1.
I must admit Im a little out of my depth with writing queries...but Im certain Im on the right lines? Any help please??
Your SQL is pretty close. You need to repeat the IN part and fix a few outher syntactic stuff:
SELECT DISTINCT thisID, thisNAME
from table1
WHERE thisID IN (SELECT id from table2 WHERE ... conditions) OR
thisID IN (SELECT id from table3 WHERE ... different conditions) OR
thisID IN (SELECT id from table99 WHERE ...even more conditions);

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)

MySQL: Count not existing values

I try to program a solution where I have multiple linked tables.
table1 contains rows with ids in field k_id
table2 contains rows where each row has a k_id assigned (as s_k_id) but any k_id may have multiple rows in table2. Any entry in table2 can only have one k_id
Now I want to have the count (and late probably a list) of k_ids which are not used in table2 as s_k_id.
I hope you can understand my question.
My solution would be this, but I assume it can be solved better?
SELECT count(k_id) AS `count` FROM tabel1 WHERE k_id NOT IN (SELECT s_k_id FROM table2)
How can I achieve this better? (Please include a short description what your SQL-Statement is doing)
Thank you!
You can try
SELECT COUNT(DISTINCT k_id) count
FROM table1 t1 LEFT JOIN table2 t2
ON t1.k_id = t2.s_k_id
WHERE t2.s_k_id IS NULL
or
SELECT COUNT(k_id) count
FROM table1 t
WHERE NOT EXISTS
(
SELECT *
FROM table2
WHERE s_k_id = t.k_id
)
Here is SQLFiddle demo

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.

MySQL subqueries weird behavior

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