Mysql - How to query 2 tables? - mysql

I've got a problem with a query with 2 tables
Table A
id (key), name
Table B
id, a_id (foreign key), language
In the first table you can find a lot of people and in the second languages they can speak. My problem now is, that I want to find all the people that can speak English and German (not one of them but both!) for example.
Do you have any idea to solve this problem?

this should work, assuming your language table looks something like this
https://www.dropbox.com/s/bgk0rjo8g86rfz5/Screenshot%202014-08-11%2022.20.55.png
SELECT a.*
FROM b
JOIN a ON a.id = b.user_id
WHERE b.language = 'German'
OR b.language = 'English'
GROUP BY b.user_id
HAVING COUNT(*) = 2;

Related

SQL - JOIN add additional requirement in another table

I'm looking for some guidance on the following. I have two SQL tables A and B.
Table A Contains a list of languages
language_id
language
1
English
2
French
3
Spanish
I would like select all languages, and do a check on Table B to see if it exists for a user in table B. A user can select multiple languages, and many users could opt for any give language. The Query will be for a specific userid.
Table B
language_id
userid
1
1
2
1
2
2
3
2
I am not sure how to add the condition "WHERE userid = 1", I am hoping it will provide the following result.
$stmt = "SELECT A.language_id, A.language, COUNT(B.userid) FROM A INNER JOIN B.language_id = A.language_id ORDER BY A.language";
So for userid 1 it would produce the following.
language_id
language
COUNT()
1
English
1
2
French
1
3
Spanish
0
I am just trying to check if the user has selected each language or not. Thank you in advance.
you can use below query for this.
select A.language_id, A.language, COALESCE(B.counter, 0)counter
FROM tableA A
LEFT OUTER JOIN (
SELECT language_id, COUNT(1)counter FROM tableB where userid=1 group by language_id
)B ON A.language_id = B.language_id

MYSQL Joining two tables with one identical column

I have two tables: table 1 = university and table 2 = school
I added university_id into the table 2 and I need to connect the two tables.
If university_name from table 1 and name from table 2 are identical, get the id from table 1 and replace it onto table 2 university_id
I am very new to sql so if you could explain that would be great. I have also tried the following with no avail!
select a.id,b.name from university as a
inner join school as b on a.university_name = b.name
UPDATE `school` SET `university_id` = a.id WHERE a.university_name = b.name
Something like
UPDATE school a
JOIN university b ON a.university_name = b.name
SET a.university_id = b.id
should work
I cannot run a test right now... Maybe it does give you a hint.
UPDATE `school` s SET `university_id` = (SELECT u.id FROM `university` u WHERE u.name=s.university_name)
You might need to JOIN the school-table within the SELECT statement.

SQL Genius need .. Complex MySQL query

I am trying to optimise my php by doing as much work on the MySQL server as possible. I have this sql query which is pulling data out of a leads table, but at the same time joining two tags tables to combine the result. I am looking to add a company which is linked through a relations table.
So the table that holds the relationship between the two is relations_value which simply states (I add example data)
parenttable (companies) | parentrecordid (10) | childtable (leads) | childrecordid (1)
the companies table has quite a few columns but the only two relevant are;
id (10) | companyname (my company name)
So this query currently grabs everything I need but I want to bring the companyname into the query:
SELECT leads.id,
GROUP_CONCAT(c.tag ORDER BY c.tag) AS tags,
leads.status,
leads.probability
FROM `gs_db_1002`.leads
LEFT JOIN ( SELECT *
FROM tags_module
WHERE tagid IN ( SELECT id
FROM tags
WHERE moduleid = 'leads' ) ) as b
ON leads.id = b.recordid
LEFT JOIN `gs_db_1002`.tags as c
ON b.tagid = c.id
GROUP BY leads.id,
leads.status,
leads.probability
I need to be able to go into the relations_values table and pull parenttable and parentrecordid by selecting childtable = leads and childrecordid = 1 and somehow join these so that I am able to get companyname as a column in the above query...
Is this possible?
I have created a sqlfiddle: sqlfiddle.com/#!2/023fa/2 So I am looking to add companies.companyname as column to the query.
I don't know what your primary keys and foreign keys are that link each table together.. if you could give a better understanding of what ID's are linked to eachother it would make this a lot easier... however i did something that does return the correct result... but since all of the ID's are = 1 then it could be incorrect.
SELECT
leads.id, GROUP_CONCAT(c.tag ORDER BY c.tag) AS tags,
leads.status, leads.probability, companyname
FROM leads
LEFT JOIN (
SELECT * FROM tags_module WHERE tagid IN (
SELECT id FROM tags WHERE moduleid = 'leads' )
) as b ON leads.id = b.recordid
LEFT JOIN tags as c ON b.tagid = c.id
LEFT JOIN relations_values rv on rv.id = b.recordid
LEFT JOIN companies c1 on c1.createdby = rv.parentrecordid
GROUP BY leads.id,leads.status, leads.probability

IF ELSE statement to join table sql

I have one supertype table where I have to pick 1 subtype table from 2 subtypes a,b. A subtype cannot go with the other one so for me to query I have to check whether if the supertype id is contained on one of the subtypes. I have been doing experiment queries but cannot get it right.
This is what somehow I thought of:
SELECT * from supertypetable INNER JOIN
IF (a.id = given.id) then a ON a.id = supertypetable.id
ELSE b ON b.id = supertetable.id
job Table
________________________________
|job_id| blach2x....
________________________________
| 1 |
| 2 |
| 3 |
________________________________
partime Table
________________________________
|job_id| blach2x....
________________________________
| 2 |
| 3 |
________________________________
fulltime Table
________________________________
|job_id| blach2x....
________________________________
| 1 |
| |
________________________________
I want to join tables that satisfy my given id
This looks a lot like a polymorphic join in rails/activerecord. The way it's implemented there, the 'supertype' table has two fields: subtype_id and subtype_type. The subtype_type table has a string that can be easily turned into the name of the right subtype table; subtype_id has the id of the row in that table. Structuring your tables like this might help.
The next question you have to ask is what exactly are you expecting to see in the results? If you want to see the supertype table plus ALL of the subtype tables, you're probably going to have to join them one at a time, then union them all together. In other words, first join against just one of the subtype tables, then against the next one, etc. If this isn't what you're going for, maybe you could clarify your question further.
If a.id can never equal b.id you could do joing on both tables and then do a UNION and only the table where the id matched would return results:
SELECT * from supertypetable
INNER JOIN
a ON a.id = supertypetable.id
UNION
SELECT * from supertypetable
INNER JOIN
b ON b.id = supertypetable.id
If a.id can equal b.id, then this would not work. But it's an idea
EDITTING PER COMMENTS:
This approach only works if the structures of a and b are identical.
So one simple suggestion might be just:
SELECT * FROM job
left join parttime on parttime.job_id = job.job_id
left join fulltime on fulltime.job_id = job.job_id
where job.job_id = #job_id
And then let your application figure out which of the two joined tables doesn't have NULL data and display that.
If you don't mind inconsistent datasets and just always want the correct returned set regardless (although you're still going to need some kind of application logic since as you said, the structures of parttime and fulltime are different, so how are you going to display/utilize their data conditionally without some kind of inspection? And if you're going to do that inspection, you might as well do it up front, figure out for your given job_id what the subtype is, and then just pick the appropriate query to run there.)
Sorry! Digression!
A stored procedure can do this logic for you (removed all the joins, just an example):
CREATE PROCEDURE getSubTypeDATA (#job_id int)
BEGIN
IF (SELECT EXISTS(SELECT 1 FROM parttime WHERE job_id = #job_id)) = 1
BEGIN
SELECT * from parttime
END
ELSE
BEGIN
SELECT * from fulltime
END
END
Alternatively, if you want a consistent dataset (ideal for application logic), why not put the common columns between fulltime and parttime into a UNION statement, and create hard-coded NULLs for the columns they don't share. For example, if fullTime looked like
EmployeeID, DepartmentID, Salary
and partTime looked like
EmployeeID, DepartmentID, HourlyRate
you could do
SELECT job.*, employeeid, departmentid, salary, null as hourlyrate FROM job inner join fulltime on fulltime.job_id = job.job_id
where job.job_id = ?
union
SELECT job.*, employeeid, departmentid, null as salary, hourlyrate FROM job inner join parttime on parttime.job_id = job.job_id
where job.job_id = ?
If there are hundred different columns, this might be unwieldy. Also, in case this didn't make it obvious, having subtypes with completely different structures but using the same foreign key is a very good clue that you're breaking third normal form.

How do I link tables with id from a list stored as XML in a column

Hopefully the question explains it well. I have a DB for a Library. Since they can be used many times, and contains more data than just a name, I have a table for Authors. Then there's a table for Books. I have no problem linking Authors to Books via a column called Author_id.
What I'm trying to do is have a column called Author_IDs that contains a list of id's, since a book can have multiple IDs. In the Author_IDs column I have:
<id>3478</id>
<id>6456</id>
Using the ExtractValue function in MySQL I can link the table with one or the other id using:
WHERE Author.id = ExtractValue(Book.Author_IDs,"/id[2]") // to get the second ID.
My question is, I want to be able to automatically display all of the authors of a book, but don't know how to link to it more than once, without looping. How can I get the results to show me all of the authors?
(Or is there a better way to accomplish this?)
Firstly, I have to vote against your storage method. Storing data as xml inside a mysql column should be avoided if possible. If you use a normal approach you will find this problem to be much easier.
Create a table:
book_authors
book_id author_id
------- ---------
1 1
1 2
1 3
2 2
2 4
Then to get all of the authors associated with a certain book it's a simple query.
Select
b.book_id,
b.book_name,
GROUP_CONCAT(a.author_name) AS 'authors'
FROM
book_authors ba LEFT JOIN
books b ON ba.book_id = b.book_id LEFT JOIN
authors a ON ba.author_id = a.author_id
GROUP BY
ba.book_id
Not sure I understand completely. Could something like this do the trick?
select a.* from tblBooks b
left join tblAuthors a on (b.authors = concat('%', a.id, '%')
where b = 'book id';
I would have done it like this
Structure
tblBooks
--------
book_id
book_name
tblAuthors
----------
author_id
author_name
tblBooksToAuthors
-----------------
id
book_id
author_id
Query
select a.*
from tblAuthors a
left join tblBooksToAuthors b2a on (b2a.author_id = a.author_id)
where b2a.book_id = {your book id};