MySQL: Count not existing values - mysql

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

Related

I wanted to know the command to check if all the values in one field of a table is present in another table under a different field name

I have 2 tables. I want to find out whether the values present in the first table is there in another table with a different field name.
Here is how it looks,
Table1
BillNo
43529179
43256787
35425676
25467778
24354758
45754748
Table2
BNo
113104808
25426577
268579679
2542135464
252525232
235263663
I have 137 records in table1 that needs to be checked against table2.
Instead of doing it one by one using the following command,
Select * from Table2 where BNo = '43529179';
This gives the result for just the mentioned value. Is there a way to check for all the values in a single query?
Thanks!
You can use a sub-select to compare against:
Select * from Table2 where BNo IN (SELECT BillNo FROM Table1);
That will "evalaute" to something like Select * from Table2 where BNo IN (113104808, 25426577, 268579679, 2542135464, 252525232, ...);
Join the tables, and check how many matching records there are:
select
count(*) as Matches
from
Table1 as t1
inner join Table2 as t2 on t2.BNo = t1.BillNo
You can also use a left join to pick out the records in table 1 that has no matching record in table 2:
select
t1.BillNo
from
Table1 as t1
left join Table2 as t2 on t2.BNo = t1.BillNo
where
t2.BNo is null

Select Pairs in MySQL

Have a table where certain rows come in couples which have a matching GUID. Just wondering how to SELECT all data from the table but ONLY if the rows exist as a couple with a matching GUID.
You can use a query like this:
SELECT *
FROM yourtable
WHERE GUID IN (SELECT GUID FROM yourtable GROUP BY GUID HAVING COUNT(*)=2)
The subquery will return all GUIDs that appears exactly twice, the outer query will return all rows associated to those GUIDs.
Please see fiddle here.
Try something like this:
SELECT t1.*
FROM
table t1
, table t2
WHERE
t1.guid = t2.guid
AND t1.id <> t2.id
;
table: your table name
id: some field that you know is different for both rows
Try
SELECT t.*
FROM Table1 t JOIN
(
SELECT guid
FROM Table1
GROUP BY guid
HAVING COUNT(*) = 2
) q ON t.guid = q.guid
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.

Sorting results based on key from different table

In table1 one of the fields is member_id.
In table2 one of the fields is member_username and the id field in this table is equal to the member_id field in table2.
The goal is to display all results from table1 in ascending alphabetical order based on member_username from table2.
Basically I need to resolve the member_id from table1 to a member_username from table2 and sort them alphabetically.
Any ideas?
You need to use a join from table1 to table2 to pick up the username, then sort on this field. You just need to be wary of a one-to-many relationship, i.e. if a member might have more than one entry in table2 with the same id you may get more rows than you expect.
select *
from table1
left join table2 on table2.id = table1.member_id
order by table2.member_username
If I didn't misunderstand your question, try joining both tables together and sort by member_username.
SELECT t1.*,
t2.member_username
FROM table1 AS t1
INNER JOIN table2 AS t2 ON t1.member_id = t2.id
ORDER BY t2.member_username ASC;
You can leave t2.member_username in the SELECT-part of the query, I just put it there for reference.

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