I have a MySQL table which has three columns:
Name | Email | BDate
---------------------------------------------------------
John Doe | jdoe#company.com | June 1, 1980
Kelly Smith | | June 2, 1983
Richmond White | rwhite#company.com |
John Doe | |
Kelly Smith | ksmith#company.com |
Richmond White | | June 3, 1984
What I want to do is to delete duplicate name and merge the cell value. I want my table to look like this:
Name | Email | BDate
---------------------------------------------------------
John Doe | jdoe#company.com | June 1, 1980
Kelly Smith | ksmith#company.com | June 2, 1983
Richmond White | rwhite#company.com | June 3, 1984
How would my query look like to return my desire table?
Thanks in advance!
Query:
SQLFIDDLEExample
SELECT t1.Name,
MAX(t1.Email) Email,
MAX(t1.BDate) BDate
FROM Table1 t1
GROUP BY t1.Name
Result:
| NAME | EMAIL | BDATE |
------------------------------------------------------
| John Doe | jdoe#company.com | June 1, 1980 |
| Kelly Smith | ksmith#company.com | June 2, 1983 |
| Richmond White | rwhite#company.com | June 3, 1984 |
One option is to use the following query to create a new table and then delete the old table:
SELECT Name, GROUP_CONCAT(Email) AS Email, GROUP_CONCAT(BDate) AS DBate
FROM YourTable
GROUP BY Name
Related
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.
Given this sells table (in MySQL):
id | person | state | amount
1 | Ringo | CA | 3$
2 | Paul | CA | 10$
3 | John | MA | 2$
4 | Ringo | CA | 6%
5 | Ringo | MA | 12$
We like to create an SQL to get, for each person, what was his latest amount he sold in each state - something like that:
person | CA | MA
Ringo | 6$ | 12$
Paul | 10$| -
John | - | 2$
We also like this query to be dynamic enough, so if there will be a new record with a new state (e.g. TX), we will get it automatically.
6 | George | TX | 15$
Will result in:
person | CA | MA | TX
Ringo | 6$ | 12$ | -
Paul | 10$| - | -
John | - | 2$ | -
George| - | - | 15$
We tried Group by with this query:
select * from sells where id in(
select max(id) from sells
group by person, state
)
That seems to bring the right data for our needs, but we need help to do the extra leap to our wanted result
You may be able to get all the data you need with simpler SQL and format further in your application code to get the format that you want.
Table where for there is one row for each state a person has spent on:
id | person | state | amount
4 | Ringo | CA | 6$
5 | Ringo | MA | 12$
2 | Paul | CA | 10$
3 | John | MA | 2$
SQL query:
SELECT id, person, state, amount
FROM sells
GROUP BY person, state
HAVING id = MAX(id)
I've been trying to come up with an elegant way to do the following, let's say I have the following table:
+-----+---------+------------+--------------+------------+------------+--------+
| ID | EmpNum | Name | Title | StartDate | UpdateDate | IsCurr |
+-----+---------+------------+--------------+------------+------------+--------+
| 1 | 0000001 | John Smith | Engineer | 01/01/2017 | 01/02/2017 | N |
| 2 | 0000001 | John Smith | Sr. Engineer | 01/01/2017 | NULL | Y |
+-----+---------+------------+--------------+------------+------------+--------+
When the Title of the employee changes, I want to update the UpdateDate of the current employee record and change IsCurr to N, then insert the new record which will be the current one. For example if employee John Smith got promoted to Team Lead on 01/03/2017, then the resulting table would like this.
+-----+---------+------------+--------------+------------+------------+----
----+
| ID | EmpNum | Name | Title | StartDate | UpdateDate | IsCurr |
+-----+---------+------------+--------------+------------+------------+--------+
| 1 | 0000001 | John Smith | Engineer | 01/01/2017 | 01/02/2017 | N |
| 2 | 0000001 | John Smith | Sr. Engineer | 01/01/2017 | 01/03/2017 | N |
| 3 | 0000001 | John Smith | Team Lead | 01/01/2017 | NULL | Y |
+-----+---------+------------+--------------+------------+------------+--------+
From what I can tell MySQL does not have a MERGE function so I would need to this in 2 separate commands. As in UPDATE the most recent record and then insert the new row.
Is there a better way to do this in MySQL?
Thanks in advance.
You could try to arrange your desired query with INSERT INTO ... ON DUPLICATE KEY. But you need ID to be an index.
It is available since MySQL version 5.5.
INSERT INTO table (ID, EmpNum, Name, Title, StartDate, UpdateDate, IsCurr)
VALUES
(3, '0000001', 'John Smith', 'Team Lead', '01/01/2017', NULL, 'Y'),
(2, '0000001', 'John Smith', 'Sr. Engineer', '01/01/2017', '01/03/2017', 'N')
ON DUPLICATE KEY UPDATE isCurr='N', UpdateDate='01/03/2017';
I have a database with record_number(PRIMARY), owner_name, address in it.
I want to identify owner_name who own more than one property, and list each property owned by owner_name.
Something like:
record_number | owner_name | address
1 | Smith | 123 Main
7 | Smith | 1 Some Street
12 | Smith | 77 Dude Ln
19 | Jones | Some address
21 | Jones | Some Different address
47 | Jones | Yet another address
106 | Davis | You're getting the idea?
139 | Davis | All of these are different!
141 | Davis | They keep changing
158 | Davis | When will it end?
select record_number, owner_name, address
from your_table
where owner_name in
(
select owner_name
from your_table
group by owner_name
having count(*) > 1
)
order by owner_name, record_number
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`