Displaying the content of two mysql tables together - mysql

Trying to figure out how to display the content of two mysql tables when one table has multiple matching rows, eg. so that the tables below display the results:
London - Harry Smith, Oliver Jones, Jack Taylor
Manchester - Charlie Williams, Jacob Brown
Table One Table two
+-----------------------------+ +----------------------------------+
| id | branchid | store | | branchid | firstname | employee |
+-----------------------------+ +----------------------------------+
| 1 | 1 | London | | 1 | Harry | Smith |
| 2 | 2 | Manchester | | 1 | Oliver | Jones |
+-----------------------------+ | 1 | Jack | Taylor |
| 2 | Charlie | Williams |
| 2 | Jacob | Brown |
+----------------------------------+
Many thanks.

GROUP_CONCAT will do the job, although we first need to CONCAT as well to put firstname and lastname together:
SELECT b.store, GROUP_CONCAT(CONCAT(e.firstname, ' ', e.employee)) AS Employees
FROM TableOne b INNER JOIN TableTwo e on b.branch = e.branchid
GROUP BY b.store;
SqlFiddle here
Result:
Store Employees
London Harry Smith,Jack Taylor,Oliver Jones
Manchester Jacob Brown,Charlie Williams`

Related

How can I return each record associated with State and City while returning State and City name only once? (MySql)

I'm not really sure how to ask this and I've been search-engining for awhile and haven't come up with anything useful.
Say I have the following three tables People, Cities and States:
PeopleID | Name | Age | CityIDFK
--------------------------------------------
1 | John | 24 | 20
2 | Jim | 28 | 21
3 | Joan | 49 | 10
4 | Mike | 37 | 10
5 | Bruce | 26 | 2
6 | Peter | 22 | 20
7 | Oprah | 27 | 3
7 | Jake | 21 | 1
CityIDPK | City | StateIDFK
---------------------------------------
1 | Seattle | 1
2 | Gotham | 2
3 | Oakland | 4
10 | Boise | 5
20 | Austin | 6
21 | Tyler | 6
StateIDPK | StateName
----------------------------
1 | Washington
2 | New York
3 | Oregon
4 | California
5 | Idaho
6 | Texas
How can I achieve the following output:
StateName | City | Name
---------------------------------------
California | Oakland | Oprah
Idaho | Boise | Mike
| | Joan
New York | Gotham | Bruce
Washington | Seattle | Jake
Texas | Austin | John
| | Peter
| Tyler | Jim
I'm not sure if the above output is possible or not, I would probably just do something like this:
SELECT StateName, City, Name FROM People
INNER JOIN Cities
ON Cities.CityIDPK = People.CityIDFK
INNER JOIN States
ON States.StateIDPK = Cities.StateIDFK
But that would return the StateName and City for every person, instead of just once.
StateName | City | Name
---------------------------------------
California | Oakland | Oprah
Idaho | Boise | Mike
Idaho | Boise | Joan
New York | Gotham | Bruce
Washington | Seattle | Jake
Texas | Austin | John
Texas | Austin | Peter
Texas | Tyler | Jim
If the output I want to achieve is possible, would someone show me an example of how to write the query, or point me in the right direction?
I agree with Tim, this should be handled in your presentation layer.
But you can do it if you're using MySQL 8 by taking advantage of window functions. We can use row_number() to determine the first row per state and per city, then use a case to only display the name for the first row.
SELECT
case row_number() over states_w
when 1 then states.name
else '' end as StateName,
case row_number() over cities_w
when 1 then cities.name
else '' end as CityName,
people.name as Name
FROM People
INNER JOIN Cities ON Cities.id = People.City_id
INNER JOIN States ON States.id = Cities.state_id
window states_w as (partition by states.id),
cities_w as (partition by cities.id);
If you're using MySQL before 8... upgrade. If you can't upgrade, it can be emulated.

How do I do a distinct join on a mysql db using conditions

I have two tables I am trying to match. I want to have the referredbyname in sourcelist match the name column to targetjoin when the record is in the same groupname
I would like to join these two tables with one-one match. Contacts in targetjoin have multiple recordtypes with the same name. I want to do some type of distinct join based on a hierarchy set up of record type name
For example: If a record is matched with the two recordtypes for the same name the RecordType: TypeA will be matched only, and so forth.
sourcelist :
ID GroupName Name ReferredbyName
1 A John Smith Sally Bosh
2 A Craig Miller Sally Smith
3 A Fulton Fork Spoon Knife
4 B Joe Sample George Test
targetjoin :
ID GroupName Name RecordType
101 A Sally Bosh TypeA
102 A Sally Bosh TypeB
103 A Sally Smith TypeC
104 A Sally Smith TypeD
105 B George Test TypeF
My Result:
| id | groupname | name | referredbyname | id | groupname | name | recordtype |
|----|-----------|--------------|----------------|-----|-----------|-------------|------------|
| 2 | A | Craig Miller | Sally Smith | 103 | A | Sally Smith | TypeC |
| 1 | A | John Smith | Sally Bosh | 102 | A | Sally Bosh | TypeB |
| 1 | A | John Smith | Sally Bosh | 101 | A | Sally Bosh | TypeA |
| 2 | A | Craig Miller | Sally Smith | 104 | A | Sally Smith | TypeD |
| 4 | B | Joe Sample | George Test | 105 | B | George Test | TypeF |
This result gives me all the of possible matches one-many join with duplicate ID
I would like to have desired result like this:
| id | groupname | name | referredbyname | id | groupname | name | recordtype |
|----|-----------|--------------|----------------|-----|-----------|-------------|------------|
| 2 | A | Craig Miller | Sally Smith | 103 | A | Sally Smith | TypeC |
| 1 | A | John Smith | Sally Bosh | 101 | A | Sally Bosh | TypeA |
| 4 | B | Joe Sample | George Test | 105 | B | George Test | TypeF |
This is what I have gotten so far
select a.*, b.*
from sourcelist a
join targetjoin b
on a.groupname=b.groupname
and
case
when b.recordtype in ('TypeA') and a.referredbyname=b.name then 1
when b.recordtype in ('TypeB') and a.referredbyname=b.name then 2
when b.recordtype in ('TypeC') and a.referredbyname=b.name then 3
when b.recordtype in ('TypeD') and a.referredbyname=b.name then 4
when b.recordtype in ('TypeE') and a.referredbyname=b.name then 5
when b.recordtype in ('TypeF') and a.referredbyname=b.name then 6
else 0
end in (1,2,3,4,5,6)
order by a.groupname
Schema: http://sqlfiddle.com/#!9/eb97f
Thanks for any help!
SELECT x.*
FROM targetjoin x
JOIN
( SELECT name
, MIN(recordtype) recordtype
FROM targetjoin
GROUP
BY name
) y
ON y.name = x.name
AND y.recordtype = x.recordtype;
The last part of this problem has been left as an exercise for the reader.

Query that display father, son in one column

I use MySQL,
In my database, I have this table :
+-----------------------------+
| ID NAME ID_FATHER |
+-----------------------------+
| 1 Mylodi 0 |
| 2 Jack 0 |
| 3 Linda 1 |
| 4 Mark 2 |
| 5 Simon 4 |
| 6 Sacha 1 |
| 7 Edward 1 |
+-----------------------------+
By this query I retrieve each name with his father :
select f.name as father, s.name as son from family s, family f where s.id_father = f.id
Result
+------------+---------+
| father | son |
+------------+---------+
| mylodi | linda |
| Jack | mark |
| mark | simon |
| mylodi | sacha |
| mylodi | edward |
+------------+---------+
But, my question How can I get this result, but in one column like this :
+--------+
| colum |
+--------+
| Mylodi |
| linda |
| sacha |
| edward |
| jack |
| mark |
| simon |
+--------+
that mean I want to display the name of the Father and of below each name of father names of his son. Thanks.
EDIT
this is my db structure
How about something like this:
SELECT name FROM (
SELECT id, name, id sort1, id_father sort2 FROM family WHERE id_father = 0
UNION
SELECT id, name, id_father, 1 sort2 FROM family WHERE id_father <> 0
) AS v
ORDER BY sort1, sort2
Here's an updated fiddle.
This is not so straightforward. It assumes that there are no loops in the data (a is b's father and b is a's father)
Not sure what database you are using, but Oracle has Hierarchical queries that are meant for problems like this using the "connect by" keyword.

SQL Query reg.ex. matching

i have a little problem figuring out what request (MySQL) would suit this requirements:
Table1
+++++++++++++++++
id| name
+++++++++++++++++
1 | John Smith
2 | Eric Smith
3 | Martha Smith
4 | Smith
5 | Ronald Smith Donald
6 | Marc Fisher
Table2
+++++++++++++++++++++++
regex | value1 | value2
+++++++++++++++++++++++
Smith | Mister | 356
Fisher| Sir | 24
To select result values as
Result Set
+++++++++++++++++++++++++++++++++++++++++++++++++++
id| name | regex | value1 | value2
+++++++++++++++++++++++++++++++++++++++++++++++++++
1 | John Smith | Mister | 356
2 | Eric Smith | Mister | 356
3 | Martha Smith | Mister | 356
4 | Smith | Mister | 356
5 | Ronald Smith Donald | Mister | 356
6 | Marc Fisher | Sir | 24
Thanks in advance.
You could use MySQL's regexp:
select *
from Table1 t1
join Table2 t2
on t1.name regexp t2.regex
Funny things will occur if a name matches more than one regex in Table2.

Join only for specific rows where value matches a variable

I have multiple MySQL tables containing varying numbers of columns. After joining three of the tables, I have a resulting table that's structured as follows:
+------------+------------+-----------+-------+------+
| student_id | first_name | last_name | class | rank |
+------------+------------+-----------+-------+------+
| 1 | John | Doe | 2012 | 1 |
+------------+------------+-----------+-------+------+
| 2 | Suzy | Public | 2013 | 12 |
+------------+------------+-----------+-------+------+
| 3 | Mike | Smith | 2014 | 50 |
+------------+------------+-----------+-------+------+
I also have two additional tables that aren't involved in the initial join:
interest
+-------------+------------+-----------------------+----------------+
| interest_id | student_id | employer_interest | interest_level |
+-------------+------------+-----------------------+----------------+
| 1 | 1 | Wayne Enterprises | High |
+-------------+------------+-----------------------+----------------+
| 2 | 1 | Gotham National Bank | Medium |
+-------------+------------+-----------------------+----------------+
| 3 | 2 | Wayne Enterprises | Low |
+-------------+------------+-----------------------+----------------+
| 4 | 3 | Gotham National Bank | High |
+-------------+------------+-----------------------+----------------+
offers
+----------+------------+-----------------------+
| offer_id | student_id | employer_offer |
+----------+------------+-----------------------+
| 1 | 1 | Wayne Enterprises |
+----------+------------+-----------------------+
| 2 | 1 | Gotham National Bank |
+----------+------------+-----------------------+
| 3 | 2 | Wayne Enterprises |
+----------+------------+-----------------------+
The interest and offers table won't necessarily contain a record for every student_id but at the same time contain multiple records that reference a single student_id.
For each of the latter two tables, I'd like to:
Select all rows where the employer_interest or employer_offer value is equal to $var (a variable I've set in PHP)
Join these rows to the original table
For example, if $var is set to Wayne Enterprises, I'd like the resulting table to be:
+------------+------------+-----------+-------+------+-------------------+----------------+-------------------+
| student_id | first_name | last_name | class | rank | employer_interest | interest_level | employer_offer |
+------------+------------+-----------+-------+------+-------------------+----------------+-------------------+
| 1 | John | Doe | 2012 | 1 | Wayne Enterprises | High | Wayne Enterprises |
+------------+------------+-----------+-------+------+-------------------+----------------+-------------------+
| 2 | Suzy | Public | 2013 | 12 | Wayne Enterprises | Low | Wayne Enterprises |
+------------+------------+-----------+-------+------+-------------------+----------------+-------------------+
| 3 | Mike | Smith | 2014 | 50 | NULL | NULL | NULL |
+------------+------------+-----------+-------+------+-------------------+----------------+-------------------+
Is what I'm trying to do possible using just a MySQL query? If so, how do I do it?
it sounds like you just need a LEFT JOIN to the other tables since it appears you want to see all students from the first set regardless of any job offer/interest.
If so... ensure both the "Interest" and "Offers" tables have an index where the student ID is either a single element index, or first in that of a compound index.
select STRAIGHT_JOIN
ORS.Student_ID,
ORS.First_Name,
ORS.Last_Name,
ORS.Class,
ORS.Rank,
JI.Employer_Interest,
JI.Interest,
OFR.Employer_Offer
from
OriginalResultSet ORS
LEFT JOIN Interest JI
ON ORS.Student_ID = JI.Student_ID
AND JI.Employer_Interest = YourPHPVariable
LEFT JOIN Offers OFR
on JI.Student_ID = OFR.Student_ID
AND JI.Employer_Interest = OFR.Employer_Offer
To prevent "NULL" results in the employer interest, interest and offer, you can wrap them in a Coalesce() call such as (for all three columns on left join)
COALESCE( JI.Employer_Interest, " " ) Employer_Interest
Your query should be something like this:
select
s.student_id, s.first_name, s.last_name, s.class, s.rank,
i.employer_interest, i.interest_level,
o.employer_offer
from students s
left join interest i
on i.student_id = s.student_id
and i.employer_interest = 'Wayne Enterprises'
left join offers o
on o.student_id = s.student_id
and o.employer_offer = 'Wayne Enterprises'