So I have a table where each row may or may not be merged via a merge_id.
Its easy to jump in and grab all merged rows, where the merge_id column is not null. The thing is I want to output the merged rows together in one container on the client side.
I there any way for sql to return a collection for merged collections ?
Do I sort in ascending order of the merge ID and trust that its sequential ?
EDIT
________________________________________________
|id | firstname | lastName | merge_id |
|------------------------------------------------|
| 1 | jane | Doe | 1 |
-------------------------------------------------|
|------------------------------------------------|
| 2 | John | Doe | 1 |
-------------------------------------------------|
|------------------------------------------------|
| 3 | max | payne | 2 |
-------------------------------------------------|
|------------------------------------------------|
| 4 | sub | zero | 3 |
--------------------------------------------------
So I want to query in such a way that I know that jane and max belong to different mergers.
How about
SELECT firstname, lastname, merge_id
FROM table t
ORDER BY t.merge_id
That would give you a record per person, and the merge_id will be ascending:
1 | Jane Doe
1 | John Doe
2 | max payne
3 | sub zero
Otherwise, you can use GROUP_CONCAT:
SELECT merge_id , GROUP_CONCAT(CONCAT(firstname, ' ', lastname))
FROM table t
GROUP BY t.merge_id
ORDER BY t.merge_id
Which will give one record per merge_id:
1 | Jane Doe, John Doe
2 | max payne
3 | sub zero
Related
The title is a bit messy, but here's an example
suppose we have table:
| name | room |
=================
| John | 4 |
| John | 6 |
| John | 9 |
| Smith | 4 |
| Smith | 6 |
| Brian | 4 |
| Brian | 6 |
| Brian | 9 |
I want to select John and Brian because they both have exactly rooms 4, 6 and 9, but not Smith, since he doesn't have the room 9. (If we had another person who ONLY has room 4 and 6, then it'd select that other person as well as Smith).
I know I need to do some kind of correlated query, but I'm not sure how to actually get it to do something like
for a check for b
If you want groups of names that share the exact same rooms, I would recommend group_concat():
select rooms, group_concat(name) as names
from (select name, group_concat(room order by room) as rooms
from t
group by name
) n
group by rooms;
If you want only combinations with more than one name, then add having count(*) > 1 to the outer select.
results table:
result_event | name | position
-------------+---------------+------------
1 | Jason Smith | 1
1 | David Johnson | 2
1 | Randy White | 3
1 | Billy Hansen | 4
2 | Wally Mann | 1
2 | Jason Smith | 2
2 | Billy Hansen | 3
2 | David Johnson | 4
2 | Randy White | 5
I have a table with race results as above. I want to sort the riders by their combined placement in the two races. (eg 1st plus 2nd = 3, 2nd plus 4th = 6, etc.) Racer "Wally Mann" did not race the first race so even though he won the second race, he should be scored behind all others.
Desired Result:
Name | Race1 | Race2
--------------+--------+-------
Jason Smith | 1 | 2
David Johnson | 2 | 4
Billy Hansen | 4 | 3
Randy White | 3 | 5
Wally Mann | NULL | 1
Current query:
SELECT name,
CASE(WHEN result_event=1 then position else 0 END) Race1,
CASE(WHEN result_event=2 then position else 0 END) Race2,
SUM(position) eventscore
FROM results
GROUP BY name
ORDER BY eventscore DESC
In my current query, "Wally Mann" is first in the list because (Null + 1) < (1+2). What can I do to make the (Null + 1) result sort AFTER all the racers who have two results?
Change your ORDER BY to sort by number of records DESC and THEN BY eventscore
ORDER BY count(*) DESC, eventscore ASC
select name from results
group by name
order count(*) desc, sum(position);
I have a table filled with first and last names. I have two other columns that I am trying to update. These two columns has the number of people that have the same first names and same last names. For example,
first last samef samel
John Smith 1 2
John Adams 1 1
Mary Kate 0 0
Kate Adams 2 1
Kate Smith 2 2
Kate Smith 2 2
Alice Mirth 0 0
So far I can only come up with these two queries, but of course they are not correct. They return the total count for each name when I need the total count - 1. Plus, the results are shown on separate tables.
I was wondering if I should use a stored procedure where I use variables to store the count for samef and samel. And then insert it into the names table, but I don't know the correct syntax for this.
SELECT first, last,
( SELECT COUNT(*) FROM names WHERE first = table1.first) AS samef
FROM names AS table1
SELECT first, last,
( SELECT COUNT(*) FROM names WHERE last = table2.last) AS samel
FROM names AS table2
I am new to mySQL so please provide explanations.
Just like Strawberry mentioned, do not store information that can be derived. Databases are great at storing data optimally. SQL is great at extracting table and derived/calculated data. Try this:
select `first`, `last`,
(select count(*)-1 from test where `first` = t.`first`) as samef,
(select count(*)-1 from test where `last` = t.`last`) as samef
from test t;
Example: http://sqlfiddle.com/#!9/9c673f/1
Result:
| first | last | samef | samef |
|-------|-------|-------|-------|
| john | smith | 1 | 2 |
| john | adams | 1 | 1 |
| mary | kate | 0 | 0 |
| kate | adams | 2 | 1 |
| kate | smith | 2 | 2 |
| kate | smith | 2 | 2 |
| alice | mirth | 0 | 0 |
I have a MySQL table called employee that looks like this:
ID | User | Phone_No | Phone_No_Count
1 | Fred | 9999 | 1
2 | John | 8888 | 2
3 | Pablo | 123 | 1
4 | John | | 0
5 | John | 8888 | 2
6 | Pablo | | 0
7 | John | 456 | 1
Phone_No_Count is a count of the Phone_No column, if there is no Phone_No then Phone_No_Count is set to zero.
I want to backfill the missing Phone_No entries using Phone_No entries which have the highest Phone_No_Count.
e.g. User John has 2 Phone_No's (8888 and 456) so I just want to use 8888 as it has the highest Phone_No_Count (2)
The backfilled data in employee would then look like this:
ID | User | Phone_No | Phone_No_Count
1 | Fred | 9999 | 1
2 | John | 8888 | 2
3 | Pablo | 123 | 1
4 | John | 8888 | 0
5 | John | 8888 | 2
6 | Pablo | 123 | 0
7 | John | 456 | 1
I can then update the Phone_No_Count separately, which I know how to do anyway.
All the examples I've seen online are for backfilling multiple tables or if it's just one table they don't have the required logic for this.
Can somebody please help as this has been frying my brain all day!!
One way to go about this kind of update you can use user defined variables in your query and store the phone for the user which has the maximum of phone count (i.e a correlated subquery) then join this data with your table and do update
update Table1 t1a
inner join(
select t1.id,
t1.`User`,
#p:= case
when t1.Phone_No is null then #c
else t1.Phone_No END Phone_No,
#c:=(select Phone_No from Table1 where t1.`User`=`User` order by `Phone_No_Count` DESC limit 1 ) max_phone
from Table1 t1,(select #p:=0,#c:=0) t
order by t1.`User`,t1.`Phone_No_Count` DESC
) t2 on(t1a.id=t2.id)
set t1a.Phone_No = t2.Phone_No
Fiddle Demo
The trick is to get the phone number for the highest count. Unfortunately, MySQL doesn't let you have subqueries on the same query being updated, but you can do this with a trick. This allows you to use update/join syntax:
update employee e join
(select e.user,
substring_index(group_concat(phone_no order by phone_no_count desc
), ',', 1) as new_phone_no
from employee e
group by e.user
) toupdate
on e.user = toupdate.user
set e.phone_no = toupdate.new_phone_no
where e.phone_no is null;
I have two tables:
Parent Information
Child Information
both are structured (almost) the same with a few nuances.
The table structures are as follows:
Parent
ID | First | Last | DOB | Address
-------------------------------------------------
1 | John | Doe | 1980-01-01 | 123 street
Dependents
ParentID | Type | First | Last | DOB
--------------------------------------------------
1 | Spouse | Jane | Doe | 1981-02-01
1 | Child | Mike | Doe | 1999-08-01
1 | Child | Zoe | Doe | 2002-04-01
I want to build a query (ideally single call with joins which returns the following:
Table Results
First | Last | Type | DOB | Address
----------------------------------------------------------------
John | Doe | Parent | 1980-01-01 | 123 Street
Jane | Doe | Spouse | 1981-02-01 | 123 Street
Mike | Doe | Child | 1999-08-01 | 123 street
Zoe | Doe | Child | 2002-04-01 | 123 Street
I suppose I could build the originally subquery with a LEFT JOIN on the dependents table (not all parents have dependents) then run a primary query which filters that table, however - when i do this, the query takes over a full minute to produce. (my tables change hundreds of times a day so keeping an index of the tables is not really an option as I'd have to rebuild constantly).
UPDATE
The more I think about it even the left join would not work necessarily because the parent information and first set of dependent information would reside on the same row from the subquery (and in turn make it 'impossible' for the primary query to filter the single row into multiple).
Any ideas?
SELECT t.First, t.Last, t.Type, t.DOB, t.Address
FROM (SELECT ID, First, Last, 'Parent' as Type, DOB, Address, 1 as SortKey
FROM Parent
UNION ALL
SELECT p.ID, d.First, d.Last, d.Type, d.DOB, p.Address,
CASE WHEN d.Type = 'Spouse' THEN 2 ELSE 3 END as SortKey
FROM Dependents d
INNER JOIN Parent p
ON d.ParentID = p.ID) t
ORDER BY t.ID, t.SortKey