I'm new to sql and do not understand what this join statement is doing. Does this statement ON people.state_code=states.state_abbrev mean that people.state_code and states.state_abbrev are now one?
SELECT people.first_name,
people.state_code, states.division
FROM people
JOIN states ON people.state_code=states.state_abbrev;
It will take the columns first_name and state_code from the table people and the column division from the table states and put them together in a join table where the entries in the state_code and state_abbrev columns match. The join table is produced only for display in response to this query; the underlying tables with the data entries are not amended.
In this case the '=' means equal (like values are equal) and is part of the join condition based on which data is retrieved by the select statement. You are 'linking' the two tables based on a condition so you can retrieve related data...
Relational data base - there are relations between tables and between data.
For example:
table_1
PERSON_ID FIRST_NAME LAST_NAME ADDRESS_ID
1 |John |Doe |2
table_2
ADRESS_ID STREET
1 | 5th Avenue
2 | 1st Street
SELECT FIRST_NAME, STREET
FROM table_1 t1
JOIN table_2 t2 ON t1.ADDRESS_ID = t2.ADDRESS_ID;
will return
John, 1st Street
Does this statement ON people.state_code=states.state_abbrev mean that people.state_code and states.state_abbrev are now one?
Answer: NO. people.state_code and states.state_abbrev should be the same value on the respective tables.
Let me give you an example taken from https://www.mysqltutorial.org/mysql-join/
Suppose you have below tables:
CREATE TABLE members (
member_id INT AUTO_INCREMENT,
members_name VARCHAR(100),
PRIMARY KEY (member_id)
);
CREATE TABLE committees (
committee_id INT AUTO_INCREMENT,
committees_name VARCHAR(100),
PRIMARY KEY (committee_id)
);
Some data examples:
+-----------+--------+
| member_id | members_name |
+-----------+--------+
| 1 | John |
| 2 | Jane |
| 3 | Mary |
| 4 | David |
| 5 | Amelia |
+-----------+--------+
+--------------+--------+
| committee_id | committees_name |
+--------------+--------+
| 1 | John |
| 2 | Mary |
| 3 | Amelia |
| 4 | Joe |
+--------------+--------+
To do the INNER JOIN we can use members_name and committees_name not the id because they are auto_increment and the data are not related.
So the query would be:
SELECT
m.member_id,
m.members_name AS member,
c.committee_id,
c.committees_name AS committee
FROM members m
INNER JOIN committees c ON c.name = m.name;
Giving below result:
+-----------+--------+--------------+-----------+
| member_id | member | committee_id | committee |
+-----------+--------+--------------+-----------+
| 1 | John | 1 | John |
| 3 | Mary | 2 | Mary |
| 5 | Amelia | 3 | Amelia |
+-----------+--------+--------------+-----------+
Conclusion: The values of the columns are equaly the same
Related
I am trying to get values matching the value from the second column. For example, I want to know who is the sender for Bill Gates by only using IDs.
I have two tables,
*users* table
| user_ID | Full_name |
| -------- | -------------- |
| 1 | Steve Jobs |
| 2 | Bill Gates |
| 3 | Elon Musk |
*relationships* table (with both column foreign keys)
| user_sender | user_receiver |
| ------------ | -------------- |
| 1 | 2 |
| 3 | 1 |
| 3 | 2 |
I want to select based on "user_receiver" column the matching values in the column "user_sender"
For example, I want to know who is user_sender for 2
OUTPUT:
| | |
| ------------ | -------------- |
| 1 | 2 |
| 3 | 2 |
You need to join the tables and select the rows you want
you have access to all columns of both tables by addressing them with their alias
SELECT u.user_ID , u.Full_name,r.user_receiver
FROM users u JOIN
relationships r ON u.user_ID = r.user_sender
WHERE r.user_receiver = 2
If you want to look based on the name, then join the relationships to users.
SELECT
rel.user_sender
, rel.user_receiver
-- , sender.Full_name AS sender_name
-- , receiver.Full_name AS receiver_name
FROM relationships AS rel
JOIN users AS sender ON sender.user_ID = rel.user_sender
JOIN users As receiver ON receiver.user_ID = rel.user_receiver
WHERE receiver.Full_name = 'Bill Gates'
If you already know the user_receiver number, and you only want the ID's
SELECT *
FROM relationships
WHERE user_receiver = 2
We have a situation that I have been able to recreate with the following simple example. I have the following two sample tables:
CREATE TABLE contact_info
(
id INT UNSIGNED AUTO_INCREMENT,
priContactId INT,
secContactId INT,
blahBlah VARCHAR(32),
PRIMARY KEY(id)
);
and
CREATE TABLE name_lookup
(
id INT UNSIGNED AUTO_INCREMENT,
contactID INT,
contactName VARCHAR(32),
PRIMARY KEY(id)
);
I populate them as follows:
INSERT INTO contact_info(priContactId, secContactId, blahBlah) VALUES(1, 3, "Team A"), (4, 2, "Team B");
INSERT INTO name_lookup(contactID, contactName) VALUES(1, "John Doe"), (2, "Mary Smith"), (3, "Jose Garcia"), (4, "Larry Brown");
Obviously, the contents of the tables are as follows:
+----+--------------+--------------+----------+
| id | priContactId | secContactId | blahBlah |
+----+--------------+--------------+----------+
| 1 | 1 | 3 | Team A |
| 2 | 4 | 2 | Team B |
+----+--------------+--------------+----------+
+----+-----------+-------------+
| id | contactID | contactName |
+----+-----------+-------------+
| 1 | 1 | John Doe |
| 2 | 2 | Mary Smith |
| 3 | 3 | Jose Garcia |
| 4 | 4 | Larry Brown |
+----+-----------+-------------+
We would like to perform a JOIN operation so that we get output like this:
+-------------+-------------+--------+
| John Doe | Jose Garcia | Team A |
+-------------+-------------+--------+
| Larry Brown | Mary Smith | Team B |
+-------------+-------------+--------+
The join constraints for both the priContactId and secContactId columns are the same and I am having tough time figuring out what the JOIN query should look like.
FYI, we are using MySQL version 5.6.49.
Two separate columns needs 2 separate table copies join.
SELECT t1.contactName name1, t2.contactName name1, t3.blahBlah team
FROM name_lookup t1
JOIN name_lookup t2
JOIN contact_info t3 ON t1.contactID = t3.priContactId
AND t2.contactID = t3.secContactId
This would normally be handled with two joins. You don't have not null constraints on the two contacts, so I would suggest outer joins:
select nl_pri.contactName as PrimaryName, nl_sec.contactName as SecondaryName,
ci.blahblah
from contact_info ci left join
name_lookup nl_pri
on ci.priContactId = nl_pri.contactId left join
name_lookup nl_sec
on c.secContactId = nl_sec.contactId;
Notes:
The left join keeps all contacts, even those that don't have both primary and secondary.
Table aliases make the query easier to write and read. The table aliases should be meaningful.
You should define the foreign key relationships, so it is clear that the contact ids refer to the name_lookup table.
This is branch detail table which have the branch name and the employee id work on that branch.
CREATE TABLE Branch_detail
(`nid` int,`branch` varchar(15), `emp_with_department` varchar(15));
INSERT INTO Branch_detail
(`nid`,`branch`, `emp_with_department`)
VALUES
(1,'Mumbai', '1,2,4'),
(2,'Banglore', '4,5');
| nid | branch | emp_with_department |
|-----|----------|---------------------|
| 1 | Mumbai | 1,2,4 |
| 2 | Banglore | 4,5 |
This is employee detail table with their respective designations.
CREATE TABLE Emp
(`id` int, `name` varchar(10), `Designations ` varchar(10));
INSERT INTO Emp
(`id`, `name`,`Designations `)
VALUES
(1,'Rantesh', 'Executive'),
(2,'Keith', 'Art'),
(3,'Nikhil', 'Executive'),
(4,'Gauresh', 'Art'),
(5,'Sumit', 'Executive');
| id | name | Designations |
|----|---------|--------------|
| 1 | Rantesh | Executive |
| 2 | Keith | Art |
| 3 | Nikhil | Executive |
| 4 | Gauresh | Art |
| 5 | Sumit | Executive |
This query i tried to get atleast which id is Executive or Art employee
SELECT a.nid,
GROUP_CONCAT(b.Designations ORDER BY b.id) Designations_Name
FROM Branch_detail a INNER JOIN Emp b
ON FIND_IN_SET(b.id, a.emp_with_department) > 0
GROUP BY a.nid
| nid | Designations_Name|
|-----|-------------------|
| 1 | Executive,Art,Art |
| 2 | Art,Executive |
Output should be:
count of Executives for nid=1,
count of Art for nid=1,
count of executives for nid=2,
count of Art for nid=1
OR
| nid | count(Designations_Name)|
|-----|--------------------------|
| 1 | 1,2,2 |
| 2 | 1,1 |
I want the Output like there on n location, how many executive and art employee is present in count ?
this is sqlfiddle where the demo is present
http://sqlfiddle.com/#!9/27aa51/1
Although you should implement Normalization.
But still, here is a query which will work for you, utilizing Nested Queries:
select inner_nest.nid, GROUP_CONCAT(designations_count)
FROM (SELECT a.nid, b.Designations, COUNT(DISTINCT b.id) as designations_count
FROM Branch_detail a
INNER JOIN Emp b ON FIND_IN_SET(b.id, a.emp_with_department) > 0
WHERE 1 = 1
GROUP BY a.nid, b.Designations ) AS inner_nest
GROUP BY inner_nest.nid
It gets Count for Art first, then Executives (as alphabetically Art comes first)
I have a basic multi-school management system that I am working on for fun in order to learn querying from a MySQL database.
I am doing a number of joins from tables such as students, schools,student_grade, grade_school etc. I now want to get a list of all subjects the student has been assigned. Since there are multiple possible rows, I have a student_subject table to hold the student_id and then the subject_id values.
The following query gets me the student's name, and their grade:
SELECT a.id,a.firstnames,a.surname,d.gradename
FROM students a
LEFT JOIN student_grade b ON a.id=b.studentid
LEFT JOIN grade_school c ON c.id=b.gradeid
LEFT JOIN grades d ON c.gradeid=d.id
WHERE a.schoolid=? AND b.gradeid=? ORDER by a.surname ASC
This results in each row returned to be the student's name and their grade, like this:
ID | Firstname | Surname | Grade
1 | John | Doe | 4
5 | Sarah | Marshall | 7
How can I get all the subjects the student is assigned and put them all in a column "subject_ids" to get a result as follows:
ID | Firstname | Surname | Grade | Subjects
1 | John | Doe | 4 | 5,54,2,56
5 | Sarah | Marshall | 7 | 2,4,12,17
My table structures are as follows:
Table `students`
id | firstnames | surname | schoolid
Table `student_grade`
id | studentid | gradeid
Table `grade_school`
id | gradeid| schoolid
Table `grades`
id | gradename|
Table `student_subject`
id | studentid| subjectid
4 | 1 | 5
5 | 1 | 54
6 | 1 | 2
7 | 1 | 56
8 | 5 | 2
9 | 5 | 4
10 | 5 | 12
11 | 5 | 17
Try this:
SELECT a.id,a.firstnames,a.surname,d.gradename, GROUP_CONCAT(s.subjectid)
FROM students a
LEFT JOIN student_grade b ON a.id=b.studentid
LEFT JOIN grade_school c ON c.id=b.gradeid
LEFT JOIN grades d ON c.gradeid=d.id
LEFT JOIN student_subject s ON s.studentid=a.id
WHERE a.schoolid=? AND b.gradeid=? ORDER by a.surname ASC
also check this or this
The GROUP_CONCAT() function will do what you want here.
This question is a dup of Can I concatenate multiple MySQL rows into one field?
I have a database that has two columns in a table called jos_facileforms_subrecords. I want to report on: record, value
Record contains a set of unique record values, and values contains the values I want to turn into columns. i.e.:
RECORD | NAME | VALUE
1 | firstname | Frank
1 | lastname | Smith
1 | email | fsmith#email.com
2 | firstname | Sally
2 | lastname | Jones
2 | email | sjones#email.com
3 | firstname | Peter
3 | lastname | Baker
3 | email | pbaker#gmail.com
I want to turn this into a row per record set. i.e.
FIRST NAME | LAST NAME | EMAIL
Frank | Smith | fsmith#email.com
Sally | Jones | sjones#email.com
Peter | Baker | pbaker#email.com
What you are looking for is a PIVOT query. Other DBMS's have functions for this, unfortunately MySQL does not, so you have to do it manually. There are several ways to accomplish this. Here's one that will work for your situation:
select
f.`record` as `record`,
f.`value` as `first name`,
l.`value` as `last name`,
e.`value` as `email`
from
jos_facileforms_subrecords f
inner join jos_facileforms_subrecords l on f.record = l.record
inner join jos_facileforms_subrecords e on f.record = e.record
where
f.name = 'firstname'
and l.name = 'lastname'
and e.name = 'email'
group by f.`record`
See it working in this fiddle.