SQL Select based on partial string match from another table - mysql

I have two tables like the ones below (examples):
Table 1:
Short
FirstName
TMS
Thomas
RBT
Robert
ALA
Angelica
CNA
Christina
Table 2:
ID
Surname
TMS123
Johnson
CNA342
Smith
TMS667
Cooper
RBT555
Lewis
So the Table 1 in this case connects an abbreviation with a name. In Table 2 I have a list of surnames and each of them has identifiers. I want to be able to get the first name of every person in Table 2 based on their identifier. So the output should be:
FirstName
Surname
Thomas
Johnson
Christina
Smith
Thomas
Cooper
Robert
Lewis

Most databases support a LEFT() string function, which you can use in a JOIN:
select t1.firstname, t2.surname
from table1 t1 join
table2 t2
on t1.short = left(t2.id, 3);
You can use substr()/substring() instead of left() if your database does not support left().

This (or something very similar) should work with most DBMS.
Select Table1.FirstName, Table2.Surname
From Table1 Inner Join Table2
On Left(Table2.ID, 3) = Table1.Short

Related

A SELECT statement to iterate over all rows of a subquery and for each row (“r”) return a value that is the result of a further query informed by “r”

In MySQL, is it possible in a SELECT statement to iterate over all rows of a subquery and for each row (“r”) return a value that is the result of a further query informed by “r”?
E.g. if I have a table of friend’s dates of birth, how can I get from another table of famous people’s dates of birth the most recent such famous person’s birthday that’s close to each friend’s date of birth?
http://www.sqlfiddle.com/#!9/a5d62f
I hope to generate a matching_birth_dates table with the following rows:
id
famous_name
friend_name
famous_dob
friend_dob
1
David Beckham
Sarah Holland
05/01/1980
07/02/1981
2
David Lynch
John Smith
02/05/1960
02/06/1959
3
David Beckham
Jane Doe
05/01/1980
02/04/1972
You can first find out the closest famous person in a subquery and then get the person and the famous in the outer query:
select friend.id, f.name, friend.name, f.dob, friend.dob
from (
select fa.id, fa.name, fa.dob, min(abs(datediff(fa.dob, fr.dob))) as diff
from famous_birth_dates fa
join friends_birth_dates fr on 1=1
group by fa.id, fa.name, fa.dob
) as f
join friends_birth_dates friend on f.diff = abs(datediff(f.dob, friend.dob))
order by friend.id
See db sqlfiddle

Is there a way to join tables in MS Access to get this output?

Say we have 2 tables:
Table A:
EmployeeName
Carter
Rick
Larry
Table B:
Case
Case1
Case2
Case3
Case4
Case5
Case6
Case7
Case8
Now I'd like an output like this:
EmployeeName Case
Carter Case1
Rick Case2
Larry Case3
Carter Case4
Rick Case5
Larry Case6
Carter Case7
Rick Case8
Can this be done in MS Access using SQL queries?
Yes, it can.
First, create two queries to add sequential numbers to the records:
SELECT
Employee.EmployeeName,
(Select Count(*)
From Employee As T
Where T.EmployeeName < Employee.EmployeeName) AS Id
FROM
Employee;
SELECT
Case.Case,
(Select Count(*)
From Case As T
Where T.Case < Case.Case) AS Id
FROM
Case;
Save these as qEmployee and qCase.
Then create the final query:
SELECT
qEmployee.EmployeeName,
qCase.Case
FROM
qCase,
qEmployee
WHERE
([qCase]![Id] Mod (Select Count(*) From Employee)) = [qEmployee]![Id];
Output:
If you don't want employee names to be sorted, another field to sort on must be present.

MySQL Multiple Select Ambiguous Results

Using phpMyAdmin 5.1.44 to experiment with DML commands.
I've been following tutorials on-line.
SELECT book.b_isbn, publisher.p_name FROM 'book', 'publisher' WHERE book.b_title='DSA'
Table 1
book
b_id(PK) b_isbn b_title p_id(FK)
-----------------------------------------
1 12345 DSA 1
2 23456 SD 1
3 34567 CSP 2
Table 2
publisher
p_id(PK) p_name
--------------------
1 Fred
2 John
Expected Results
b_isbn p_name
---------------------
12345 Fred
Actual Results
b_isbn p_name
----------------------
12345 Fred
34567 John
Any ideas?
You need to tell MySQL how to join the tables together (without which it just matches every book to every publisher) - use any one of:
add AND publisher.p_id = book.p_id to your WHERE clause;
tell MySQL to join ON that condition / USING that column;
... FROM book JOIN publisher ON publisher.p_id = book.p_id WHERE ...
or
... FROM book JOIN publisher USING (p_id) WHERE ...
use a NATURAL JOIN to have MySQL guess that's what you want based on the column names.
... FROM book NATURAL JOIN publisher WHERE ...
I think you need to put the fk to the pk key in the where statement
SELECT
*
FROM
book, publisher
WHERE
book.p_id=publisher.p_id
AND book.b_title='DSA'
Or even better use JOINs:
SELECT
*
FROM
book
JOIN publisher
ON book.p_id=publisher.p_id
WHERE
book.b_title='DSA'
Or if you are not sure if there is a corresponding value then use a left join. Like this:
SELECT
*
FROM
book
LEFT JOIN publisher
ON book.p_id=publisher.p_id
WHERE
book.b_title='DSA'

find out count of comma based value in MySql

I have two tables.
Table Emp
id name
1 Ajay
2 Amol
3 Sanjay
4 Vijay
Table Sports
Sport_name Played by
Cricket ^2^,^3^,^4^
Football ^1^,^3^
Vollyball ^4^,^1^
Now I want to write a query which will give me output like
name No_of_sports_played
Ajay 2
Amol 1
Sanjay 2
Vijay 2
So what will be Mysql query for this?
I agree with the above answers/comments that you are not using a database for what a database is for, but here is how you could calculate your table from your current structure in case you have no control over that:
SELECT Emp.name, IF(Played_by IS NULL,0,COUNT(*)) as Num_Sports
FROM Emp
LEFT JOIN Sports
ON Sports.Played_by RLIKE CONCAT('[[:<:]]',Emp.id,'[[:>:]]')
GROUP BY Emp.name;
See it in action here.
UPDATE: added the IF(Played_by IS NULL,0,COUNT(*)) instead of COUNT(*). This means that if an employee doesn't play anything they'll have a 0 as their Num_Sports. See it here (I also added in those ^ characters and it still works.
What it does is joins the Emp table to the Sports table if it can find the Emp.id in the corresponding Played_by column.
For example, if we wanted to see what sports Ajay played (id=1), we could do:
SELECT *
FROM Emp, Sports
WHERE Sports.Played_by LIKE '%1%'
AND Emp.id=1;
The query I gave as my solution is basically the query above, with a GROUP BY Emp.name to perform it for each employee.
The one modification is the use of RLIKE instead of LIKE.
I use RLIKE '[[:<:]]employeeid[[:>:]]' instead of LIKE '%employeeid%. The [[:<:]] symbols just mean "make sure the employeeid you match is a whole word".
This prevents (e.g.) Emp.id 1 matching the 1 in the Played_by of 3,4,11,2.
You do not want to store your relationships in a column like that. Create this table:
CREATE TABLE player_sports (player_id INTEGER NOT NULL, sport_id INTEGER NOT NULL, PRIMARY KEY(player_id, sport_id));
This assumes you have an id column in your sports table. So now a player will have one record in player_sports for each sport they play.
Your final query will be:
SELECT p.name, COUNT(ps.player_id)
FROM players p, player_sports ps
WHERE ps.player_id = p.id
GROUP BY p.name;

MySQL selecting distinct names from two columns

I have two columns of coaches names:
coach1
JOHN
JACOB
MARY
coach2
JOHN
JACOB
HENRY
I would like to select all DISTINCT values between the two columns.
So that my SELECT statement will read,
JOHN
JACOB
MARY
HENRY
with no duplicates. Any suggestions as to the most efficient way to do this?
SELECT COACH1 AS NAME FROM TABLE
UNION
SELECT COACH2 AS NAME FROM TABLE
Is a way to do. I'm not saying it's the "most" efficient to do, though :) Shouldn't be too bad. UNION by default will select only distinct values.