count and group by first n(minimum) items in group - mysql

I've been through several of the "n from M" type solutions and not been able to get close to what I'm after though it's possible that the question has been asked before in some other format.
I've tried examples from this MySQL Group By with top N number of each kind and this http://www.xaprb.com/blog/2006/12/07/how-to-select-the-firstleastmax-row-per-group-in-sql/ none of which appear to apply to what I'm trying to do.
What I'm trying to do is determine the best teams in a running race, individual runners aren't a problem, gender, age categories can be taken care of. The rules for team prizes are based on membership of a club.
Clubs must have at least 3 runners to qualify for the team competition.
Only the first 3 runners from each club count towards the competition.
The team position is determined by the sum of the qualifying runners so runners from club A who finish 2nd 9th & 10th get 21pts, runners from club B who finish 4th, 5th & 6th get 15pts, etc.
I've a table with the following fields:
+---------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| runner_id | int(11) | YES | | NULL | |
| club_id | int(11) | YES | | NULL | |
| race_id | int(11) | YES | | NULL | |
| race_number | int(11) | YES | | NULL | |
| category | varchar(20) | YES | | NULL | |
| finish_time | int(11) | YES | | NULL | |
| race_position | int(11) | YES | | NULL | |
+---------------+-------------+------+-----+---------+----------------+
Only club_id and race_position are relevant to the query. runner_id, club_id and race_id are foreign keys and I need to be able to extract data (given_name, family_name, age, club_name, etc.) from those tables when creating the results.
This is typical data:
+----+-----------+---------+---------+-------------+-----------+-------------+---------------+
| id | runner_id | club_id | race_id | race_number | category | finish_time | race_position |
+----+-----------+---------+---------+-------------+-----------+-------------+---------------+
| 53 | 26 | 1 | 85 | 17 | Msenior | 1666 | 11 |
| 35 | 39 | 1 | 85 | 4 | Munder_18 | 1503 | 4 |
| 63 | 61 | 2 | 85 | 27 | Mvet_50 | 1610 | 9 |
| 42 | 46 | 2 | 85 | 11 | Lvet_40 | 1773 | 14 |
| 38 | 42 | 2 | 85 | 7 | Lunder_18 | 1793 | 17 |
| 56 | 36 | 9 | 85 | 20 | Msenior | 1561 | 6 |
| 44 | 48 | 9 | 85 | 13 | Msenior | 1667 | 12 |
| 64 | 62 | 9 | 85 | 28 | Msenior | 1660 | 10 |
| 49 | 52 | 9 | 85 | 18 | Msenior | 1432 | 1 |
| 47 | 51 | 10 | 85 | 16 | Msenior | 1779 | 15 |
| 61 | 59 | 11 | 85 | 25 | Mvet_50 | 1502 | 3 |
| 33 | 38 | 11 | 85 | 2 | Munder_18 | 1440 | 2 |
| 65 | 63 | 11 | 85 | 29 | Mvet_40 | 1566 | 8 |
| 54 | 54 | 12 | 85 | 19 | Msenior | 1785 | 16 |
| 58 | 56 | 12 | 85 | 23 | Msenior | 1546 | 5 |
| 37 | 41 | 12 | 85 | 6 | Munder_18 | 1668 | 13 |
| 45 | 49 | 14 | 85 | 14 | Mvet_50 | 1565 | 7 |
+----+-----------+---------+---------+-------------+-----------+-------------+---------------+
What I want to end up with is this:
+----+-----------+---------+---------+-------------+-----------+-------------+---------------+
| id | runner_id | club_id | race_id | race_number | category | finish_time | race_position |
+----+-----------+---------+---------+-------------+-----------+-------------+---------------+
| 33 | 38 | 11 | 85 | 2 | Munder_18 | 1440 | 2 |
| 61 | 59 | 11 | 85 | 25 | Mvet_50 | 1502 | 3 |
| 65 | 63 | 11 | 85 | 29 | Mvet_40 | 1566 | 8 |
| 49 | 52 | 9 | 85 | 18 | Msenior | 1432 | 1 |
| 56 | 36 | 9 | 85 | 20 | Msenior | 1561 | 6 |
| 64 | 62 | 9 | 85 | 28 | Msenior | 1660 | 10 |
| 58 | 56 | 12 | 85 | 23 | Msenior | 1546 | 5 |
| 37 | 41 | 12 | 85 | 6 | Munder_18 | 1668 | 13 |
| 54 | 54 | 12 | 85 | 19 | Msenior | 1785 | 16 |
| 63 | 61 | 2 | 85 | 27 | Mvet_50 | 1610 | 9 |
| 42 | 46 | 2 | 85 | 11 | Lvet_40 | 1773 | 14 |
| 38 | 42 | 2 | 85 | 7 | Lunder_18 | 1793 | 17 |
+----+-----------+---------+---------+-------------+-----------+-------------+---------------+
So even though runner_id of 52 won the race, he wasn't in the winning team.
I'm running all this under Codeigniter/Datamapper ORM but I can pass a full SQL query string down through this layer.
I hope all this makes sense.

MySQL lacks important features to get this solved (CTEs, window functions) but you can workaround them with some user defined variables and by paying the performance cost:
SELECT s1.id, s1.runner_id, s1.club_id, s1.race_id, s1.race_number, s1.category,
s1.finish_time, s1.race_position
FROM (
SELECT t1.*,
#club_rank := if(#prev_club = t1.club_id, #club_rank + 1, 1) club_rank,
#prev_club := t1.club_id
FROM t t1
CROSS JOIN (SELECT #prev_club := NULL, #club_rank := 1) init
ORDER BY t1.club_id, t1.race_position
) s1
JOIN (
SELECT club_id, count(*) teamSize, sum(race_position) teamPosition FROM t
GROUP BY club_id
) s2 ON s1.club_id = s2.club_id
WHERE club_rank <= 3 AND teamSize >= 3
ORDER BY teamPosition, race_position
Output:
| ID | RUNNER_ID | CLUB_ID | RACE_ID | RACE_NUMBER | CATEGORY | FINISH_TIME | RACE_POSITION |
|----|-----------|---------|---------|-------------|-----------|-------------|---------------|
| 33 | 38 | 11 | 85 | 2 | Munder_18 | 1440 | 2 |
| 61 | 59 | 11 | 85 | 25 | Mvet_50 | 1502 | 3 |
| 65 | 63 | 11 | 85 | 29 | Mvet_40 | 1566 | 8 |
| 49 | 52 | 9 | 85 | 18 | Msenior | 1432 | 1 |
| 56 | 36 | 9 | 85 | 20 | Msenior | 1561 | 6 |
| 64 | 62 | 9 | 85 | 28 | Msenior | 1660 | 10 |
| 58 | 56 | 12 | 85 | 23 | Msenior | 1546 | 5 |
| 37 | 41 | 12 | 85 | 6 | Munder_18 | 1668 | 13 |
| 54 | 54 | 12 | 85 | 19 | Msenior | 1785 | 16 |
| 63 | 61 | 2 | 85 | 27 | Mvet_50 | 1610 | 9 |
| 42 | 46 | 2 | 85 | 11 | Lvet_40 | 1773 | 14 |
| 38 | 42 | 2 | 85 | 7 | Lunder_18 | 1793 | 17 |
Fiddle here.

A bit late as I've been indisposed.
I came up with an inelegant solution. I added a club_total column to the table. I then loop over the table with one query for each club getting the first N runners with a query like:
select * from entries where race_id=? and club_id=? LIMIT ? order by race_position;
I then ignore those clubs with less than N finishers and sum the race positions of the other clubs and write this value back to the table.
Finally I run another query to extract only those rows with club totals:
select * from entries where club_total > 0 and race_id=? order by club_total, race_position;
Like I said, it's not elegant and it's certainly not quick (I've not timed it) but it's only going to get run a handful of times a year on one machine and the record set is a couple of hundred rows at a maximum. With a small data set it's not appreciably slower than a simple query with the data being displayed via AJAX. Getting the job done in this case is more important than speed. I wouldn't use this method for any situation where performance was an issue

Related

why can't join 2 tables with different num of rows on id?

I need to divide time from table A by table B to find relative completion time in % of a task.
The time column shows the time student needed to finish a task.
if the total time it took was 2 min, and the attempt time was 1 min, then the relative time is 50%
One table has 30 rows - it' s a derived table that shows total time,
another 59 rows - time it took for each step without summation,
common field is named st_id (step_id).
The first table A :
+-------+---------+
| st_id | time |
+-------+---------+
| 10 | 0:00:28 |
| 11 | 0:01:51 |
| 12 | 0:10:09 |
| 13 | 0:03:44 |
| 14 | 0:16:44 |
| 15 | 0:19:12 |
| 16 | 0:03:43 |
| 17 | 0:07:56 |
| 18 | 0:06:19 |
| 19 | 0:31:14 |
| 20 | 0:11:50 |
| 81 | 0:14:12 |
| 82 | 0:18:59 |
| 83 | 0:30:24 |
| 84 | 0:11:50 |
| 85 | 0:40:35 |
| 86 | 1:28:57 |
| 87 | 0:24:10 |
| 88 | 0:51:53 |
| 100 | 0:05:31 |
| 101 | 0:13:41 |
| 103 | 0:11:50 |
| 104 | 0:22:18 |
| 105 | 0:35:18 |
| 106 | 0:55:02 |
| 107 | 0:42:02 |
| 108 | 0:08:52 |
| 109 | 1:07:07 |
| 110 | 0:11:50 |
| 111 | 0:11:55 |
+-------+---------+
another table has 59 rows - table B:
+------------+---------+---------------+
| student_id | st_id | time |
+------------+---------+---------------+
| 59 | 10 | 0:00:28 |
| 59 | 11 | 0:01:11 |
| 59 | 12 | 0:06:09 |
| 59 | 13 | 0:02:24 |
| 59 | 14 | 0:00:05 |
| 59 | 14 | 0:00:04 |
| 59 | 14 | 0:00:20 |
| 59 | 14 | 0:00:23 |
| 59 | 14 | 0:09:42 |
| 59 | 14 | 0:00:10 |
| 59 | 15 | 0:11:44 |
| 59 | 15 | 0:00:08 |
| 59 | 16 | 0:02:23 |
| 59 | 17 | 0:04:53 |
| 59 | 17 | 0:00:23 |
| 59 | 18 | 0:00:07 |
| 59 | 18 | 0:03:19 |
| 59 | 18 | 0:00:53 |
| 59 | 19 | 0:00:07 |
| 59 | 19 | 0:00:29 |
| 59 | 19 | 0:00:10 |
| 59 | 19 | 0:00:06 |
| 59 | 19 | 0:00:04 |
| 59 | 19 | 0:00:07 |
| 59 | 19 | 0:00:24 |
| 59 | 19 | 0:00:08 |
| 59 | 19 | 0:00:08 |
| 59 | 19 | 0:02:11 |
| 59 | 19 | 0:00:10 |
| 59 | 19 | 0:15:50 |
| 59 | 20 | 0:07:10 |
| 59 | 81 | 0:08:52 |
| 59 | 82 | 0:11:31 |
| 59 | 82 | 0:00:08 |
| 59 | 83 | 0:00:04 |
| 59 | 83 | 0:00:08 |
| 59 | 83 | 0:00:51 |
| 59 | 83 | 0:00:15 |
| 59 | 83 | 0:17:46 |
| 59 | 84 | 0:07:10 |
| 59 | 85 | 0:24:35 |
| 59 | 86 | 0:53:14 |
| 59 | 86 | 0:00:23 |
| 59 | 87 | 0:07:10 |
| 59 | 87 | 0:07:40 |
| 59 | 88 | 0:31:13 |
| 59 | 100 | 0:03:31 |
| 59 | 101 | 0:08:21 |
| 59 | 103 | 0:07:10 |
| 59 | 104 | 0:13:38 |
| 59 | 105 | 0:21:18 |
| 59 | 106 | 0:33:02 |
| 59 | 107 | 0:07:10 |
| 59 | 107 | 0:18:12 |
| 59 | 108 | 0:05:32 |
| 59 | 109 | 0:40:27 |
| 59 | 110 | 0:07:10 |
| 59 | 111 | 0:07:15 |
+------------+---------+---------------+
I tried to inner join by step_id, but it gives me the error:
"derived table has diff num of rows"
But i m only trying to join those that exist in both tables? that's how inner join works?
I have both tables inside with clause, they pull attempt time data for student_id = 59:
with step_helper(st_id, t) as (
select step_id, sec_to_time(sum(t)) as total_time from (select step_id,
case when (submission_time - attempt_time) > 3600 then sec_to_time((select * from s1))
else sec_to_time((submission_time - attempt_time)) end as t
from step_student where student_id = 59)k
group by step_id),
time_attempt(st_id, t) as (
select student.student_id, step.step_id,
case when (submission_time - attempt_time) > 3600 then sec_to_time((select * from s1))
else sec_to_time((submission_time - attempt_time)) end as Время_попытки
from step_student inner join student on student.student_id = step_student.student_id
inner join step on step.step_id = step_student.step_id where student.student_id = 59)
this inner joining the 2 tables above does not work:
SELECT *FROM time_attempt INNER JOIN step_helper ON time_attempt.st_id = step_helper.st_id
In definition of view, derived table or common table expression,
SELECT list and column names list have different column counts
The problem is here time_attempt(st_id, t) as (. The columns in SELECT sub-query for time_attempt are 3 however you only list 2. As per MySQL documentation
The number of names in the list must be the same as the number of columns in the result set.
Therefore, your option is either listing all three columns from the result set time_attempt(st_id, t, ttt) as ( or don't list them at all time_attempt as (.
Update:
Here is an update fiddle to prove a point that it's not about row differences that return the error.

Is there a way to grab associated data from three different tables and display them?

I have four tables, three of which I need data from, as well as a fourth that stores how this data is associated. When running my query, I'm getting the wrong output and it seems like I'm not linking things up correctly, but I'm unsure as to how to do so. How do I link my joins to get the output I'm looking for?
So far, I've used
SELECT c.class, p.name, s.specialization
FROM players_classes pc
JOIN players p ON p.player_id=pc.player_id
JOIN classes c ON c.class_id=pc.class_id
JOIN specialization s ON s.spec_id=pc.spec_id
which references
CREATE TABLE players(
player_id INT UNSIGNED auto_increment PRIMARY KEY,
name VARCHAR(20)
)...;
CREATE TABLE classes(
class_id INT UNSIGNED auto_increment PRIMARY KEY,
class VARCHAR(20)
)...;
CREATE TABLE specializations(
spec_id INT UNSIGNED auto_increment PRIMARY KEY,
class_id INT UNSIGNED,
specialization VARCHAR(20)
)...;
but I'd like to be using this table in some way to display the information correctly linked, I'm just unsure how to do so:
CREATE TABLE players_classes(
pc_id INT UNSIGNED auto_increment PRIMARY KEY,
FOREIGN KEY(class_id) REFERENCES classes(class_id),
FOREIGN KEY(player_id) REFERENCES players(player_id),
FOREIGN KEY(spec_id) REFERENCES specializations(spec_id)
)...;
I'm expecting to be able to grab a player's name as well as their associated class and specialization, actual results are showing the values associated with 1/1/1 for each id, and so on and so forth.
edit: the data from players_classes is as follows
pc_id | class_id | player_id | spec_id |
1 3 1 8
2 12 2 35
3 2 3 6
etc.
therefore the expected result from this is
class | name | spec
paladin seranul holypa
hunter contherious marksmanship
priest unicorns holypr
I am instead getting
class | name | spec
warlock Affliction Affliction
warlock Grireaver Demonology
warlock Affliction Demonology
and so on throughout the table, listing combinations that do not exist within my players_classes table
specializations table
+---------+----------+----------------+
| spec_id | class_id | specialization |
+---------+----------+----------------+
| 1 | 1 | Affliction |
| 2 | 1 | Destruction |
| 3 | 1 | Demonology |
| 4 | 2 | Shadow |
| 5 | 2 | Discipline |
| 6 | 2 | HolyPr |
| 7 | 3 | Retribution |
| 8 | 3 | HolyPa |
| 9 | 3 | ProtectionPa |
| 10 | 4 | ProtectionWa |
| 11 | 4 | Arms |
| 12 | 4 | Fury |
| 13 | 5 | FrostMa |
| 14 | 5 | Fire |
| 15 | 5 | Arcane |
| 16 | 6 | vengeance |
| 17 | 6 | havoc |
| 18 | 7 | guardian |
| 19 | 7 | balance |
| 20 | 7 | feral |
| 21 | 7 | restorationDr |
| 22 | 8 | elemental |
| 23 | 8 | enhance |
| 24 | 8 | restorationSh |
| 25 | 9 | frostDk |
| 26 | 9 | blood |
| 27 | 9 | unholy |
| 28 | 10 | outlaw |
| 29 | 10 | assassin |
| 30 | 10 | subtlety |
| 31 | 11 | brewmaster |
| 32 | 11 | windwalker |
| 33 | 11 | mistweaver |
| 34 | 12 | BeastMaster |
| 35 | 12 | marksmanship |
| 36 | 12 | Survival |
+---------+----------+----------------+
classes table
+----------+-------------+
| class_id | class |
+----------+-------------+
| 1 | warlock |
| 2 | priest |
| 3 | paladin |
| 4 | warrior |
| 5 | mage |
| 6 | demonhunter |
| 7 | druid |
| 8 | shaman |
| 9 | deathknight |
| 10 | rogue |
| 11 | monk |
| 12 | hunter |
+----------+-------------+
players table
+-----------+--------------+
| player_id | name |
+-----------+--------------+
| 1 | Seranul |
| 2 | Contherious |
| 3 | Unicorns |
| 4 | Remereili |
| 5 | Affliction |
| 6 | Meowing |
| 7 | Brobot |
| 8 | Bagelsbbq |
| 9 | Rafusen |
| 10 | Taiboku |
| 11 | Yikes |
| 12 | Thunderblaze |
| 13 | Muo |
| 14 | Intz |
| 15 | Trunks |
| 16 | Kalphyte |
| 17 | Eyeoftheshoe |
| 18 | Amuhnet |
| 19 | Synkka |
| 20 | Affliction |
| 21 | Kts |
| 22 | Shadowdreams |
| 23 | Zahel |
| 24 | Azrama |
| 25 | Seranul |
| 26 | Momspaghetti |
| 27 | Ohki |
| 28 | Rafusen |
| 29 | Cindyy |
| 30 | Grireaver |
| 31 | Intz |
| 32 | lazy |
| 33 | missworld |
| 34 | Affliction |
| 35 | Amuhnet |
| 36 | eyeoftheshoe |
| 37 | sanctus |
| 38 | nozshelen |
| 39 | Contherious |
| 40 | messer |
| 41 | catathor |
| 42 | demonblaze |
| 43 | wrillett |
| 44 | raagnnar |
| 45 | xizi |
| 46 | nemesix |
| 47 | zeroskill |
| 48 | chikfillidan |
| 49 | tentenlol |
| 50 | unicorns |
| 51 | bubuhtide |
| 52 | ohki |
| 53 | azrama |
+-----------+--------------+
players_classes table
+-------+----------+-----------+---------+
| pc_id | class_id | player_id | spec_id |
+-------+----------+-----------+---------+
| 1 | 3 | 1 | 8 |
| 2 | 12 | 2 | 35 |
| 3 | 2 | 3 | 6 |
| 4 | 11 | 4 | 31 |
| 5 | 1 | 5 | 1 |
| 6 | 12 | 6 | 34 |
| 7 | 2 | 7 | 6 |
| 8 | 11 | 8 | 31 |
| 9 | 2 | 9 | 6 |
| 10 | 7 | 10 | 21 |
| 11 | 4 | 11 | 11 |
| 12 | 8 | 12 | 22 |
| 13 | 4 | 13 | 12 |
| 14 | 5 | 14 | 13 |
| 15 | 3 | 15 | 7 |
| 16 | 11 | 16 | 33 |
| 17 | 8 | 17 | 22 |
| 18 | 2 | 18 | 6 |
| 19 | 8 | 19 | 23 |
| 20 | 11 | 20 | 33 |
| 21 | 5 | 21 | 13 |
| 22 | 6 | 22 | 17 |
| 23 | 10 | 23 | 29 |
| 24 | 8 | 24 | 22 |
| 25 | 11 | 25 | 31 |
| 26 | 11 | 26 | 32 |
| 27 | 4 | 27 | 11 |
| 28 | 5 | 28 | 13 |
| 29 | 7 | 29 | 19 |
| 30 | 1 | 30 | 3 |
| 31 | 9 | 31 | 25 |
| 32 | 3 | 32 | 8 |
| 33 | 9 | 33 | 25 |
| 34 | 1 | 34 | 3 |
| 35 | 2 | 35 | 6 |
| 36 | 4 | 36 | 11 |
| 37 | 5 | 37 | 13 |
| 38 | 5 | 38 | 13 |
| 39 | 9 | 39 | 25 |
| 40 | 6 | 40 | 17 |
| 41 | 10 | 41 | 28 |
| 42 | 2 | 42 | 6 |
| 43 | 8 | 43 | 24 |
+-------+----------+-----------+---------+
You need to use the relationship table in your query:
SELECT c.class, p.name, s.specialization
FROM players_classes pc
JOIN players p ON p.player_id = pc.player_id
JOIN classes c ON c.class_id = pc.class_id
JOIN specializations s ON s.spec_id = pc.spec_id
DEMO
You shouldn't even have class_id and spec_id in the other tables, since these are many-to-many relationships, and those columns can only be used for one-to-one relationships.

MySQL Query to track transaction from 5 tables

I have 3 tables in my db, the scenario is inventory is entered into the database with reference to invoice no/po number, then users request for inventory and admin assign the items from specific invoices_items/po_items.
I need query to get when an invoice number is entered into the database and what quantity of items is this invoice has. then when when admin issue items from this issue. in other words i have to tracked inventory transactions with reference to invoice/po number.
I have following structure of tables,
table - po_reference
+----------------+-------------------------+--------------------+--------+---------------------+
| po_refrence_id | po_reference_name | requested_quantity | cost | created_on |
+----------------+-------------------------+--------------------+--------+---------------------+
| 6 | Dell Computer 000001256 | 14 | 15000 | 2015-02-18 10:36:33 |
| 11 | Dell Computer 000001257 | 50 | 150000 | 2015-02-18 10:38:33 |
+----------------+-------------------------+--------------------+--------+---------------------+
table - po_reference_details
+-------------------------+----------------+--------------------+-------------------+----------------------+-----------------------+
| po_reference_details_id | po_refrence_id | quantity_requested | quantity_received | quantity_outstanding | remarks |
+-------------------------+----------------+--------------------+-------------------+----------------------+-----------------------+
| 6 | 6 | 20 | 14 | 6 | 6 items are short.... |
| 8 | 11 | 60 | 50 | 10 | 10 items are short... |
+-------------------------+----------------+--------------------+-------------------+----------------------+-----------------------+
table - stock
+----------+----------+---------------------+------------+---------------------+------------+-----------+---------+--------------+---------+-------------+----------------+------------------+
| stock_id | quantity | created_on | created_by | updated_on | updated_by | module_id | item_id | main_unit_id | unit_id | category_id | po_refrence_id | startup_quantity |
+----------+----------+---------------------+------------+---------------------+------------+-----------+---------+--------------+---------+-------------+----------------+------------------+
| 290 | 35 | 2015-02-18 02:15:00 | NULL | NULL | NULL | 1 | 286 | 94 | 24 | 47 | 6 | 50 |
| 291 | 110 | 2015-02-18 00:00:00 | NULL | 2015-02-18 00:00:00 | NULL | 2 | 286 | 94 | 24 | 47 | 6 | 10 |
+----------+----------+---------------------+------------+---------------------+------------+-----------+---------+--------------+---------+-------------+----------------+------------------+
and request_stock_bridge
+--------------------------+------------+----------------+------------------+---------------------+--------------------------------------------------------------------+-----------------+--------------+
| stock_requests_bridge_id | request_id | po_refrence_id | quantity_on_hand | issued_date | remarks | issued_quantity | main_unit_id |
+--------------------------+------------+----------------+------------------+---------------------+--------------------------------------------------------------------+-----------------+--------------+
| 8 | 78 | 6 | 44 | 2015-02-18 06:49:34 | items are short , giving you 2 less, request after a week again... | 6 | 94 |
| 9 | 79 | 6 | 42 | 2015-02-18 08:18:56 | test | 2 | 94 |
| 10 | 80 | 6 | 35 | 2015-02-18 08:56:39 | 2 shorts.... | 7 | 94 |
+--------------------------+------------+----------------+------------------+---------------------+--------------------------------------------------------------------+-----------------+--------------+
and finally table - request
+------------+---------------+--------------------+---------------------+-----------------+--------+---------------+-----------+---------+
| request_id | department_id | quantity_requested | requested_date | quantity_issued | status | employee_name | module_id | item_id |
+------------+---------------+--------------------+---------------------+-----------------+--------+---------------+-----------+---------+
| 76 | 54 | 8 | 2015-02-18 00:00:00 | 0 | 0 | MTaqi | 2 | 279 |
| 77 | 54 | 7 | 2015-02-18 00:00:00 | 0 | 0 | MTaqi | 2 | 279 |
| 78 | 54 | 8 | 2015-02-18 00:00:00 | 0 | 1 | MTaqi | 2 | 286 |
| 79 | 54 | 2 | 2015-02-18 00:00:00 | 0 | 1 | MTaqi | 2 | 286 |
| 80 | 54 | 9 | 2015-02-18 00:00:00 | 0 | 1 | MTaqi | 2 | 286 |
+------------+---------------+--------------------+---------------------+-----------------+--------+---------------+-----------+---------+
i have write this query but doesn't work,
SELECT s.created_on, po.po_reference_name, s.startup_quantity, su.issued_date, su.issued_quantity, su.quantity_on_hand, su.remarks,po.po_refrence_id
FROM stock s, po_reference po, request r, stock_requests_bridge su
WHERE po.po_refrence_id = s.po_refrence_id
AND su.po_refrence_id = s.po_refrence_id
AND s.item_id = 286
GROUP by po.po_refrence_id
it returns this,
+---------------------+-------------------------+------------------+---------------------+-----------------+------------------+--------------------------------------------------------------------+----------------+
| created_on | po_reference_name | startup_quantity | issued_date | issued_quantity | quantity_on_hand | remarks | po_refrence_id |
+---------------------+-------------------------+------------------+---------------------+-----------------+------------------+--------------------------------------------------------------------+----------------+
| 2015-02-18 02:15:00 | Dell Computer 000001256 | 50 | 2015-02-18 06:49:34 | 6 | 44 | items are short , giving you 2 less, request after a week again... | 6 |
+---------------------+-------------------------+------------------+---------------------+-----------------+------------------+--------------------------------------------------------------------+----------------+

mysql: If a value appears more than once, get values from the others similar rows and create new columns

Here is an example of my table patients:
id | case_id | patient_id | syndrome | age |
------------------------------------------------------
1 | 23 | 24 | stable | 45 |
2 | 24 | 25 | stable | 64 |
3 | 25 | 24 | coronary | 46 |
4 | 26 | 27 | stable | 73 |
5 | 27 | 24 | stable | 48 |
6 | 28 | 25 | coronary | 67 |
7 | 29 | 40 | coronary | 68 |
If patient_id appears more than once, i only want to show the first row and add extra columns to this row containing the values of the others similar patient_ids.
For example
id | case_id | patient_id | syndrome | age | syndrome2 | age2 | syndrome3 | age3
--------------------------------------------------------------------------------------------
1 | 23 | 24 | stable | 45 | coronary | 46 | stable | 48
2 | 24 | 25 | stable | 64 | coronary | 67 | |
7 | 29 | 40 | coronary | 68 |
Is this feasible using mysql code?
Currently, I have this code:
SELECT *, count(patients.patient_id) as PatientsNo FROM patients
GROUP BY patient_id
HAVING COUNT(patient_id) > 1
Any suggestions please?
Thank you in advance,
Zinon

comparing the same table over two rows in MySQL

So this is what i have
Table : Bill
+------+------------+-----------------+---------------------+
| id | patient_id | bill_number | confirmed_date |
+------+------------+-----------------+---------------------+
| 14 | 32 | 4657 | 2012-07-06 04:11:05 |
| 15 | 33 | 4567 | 2012-07-07 05:11:05 |
| 16 | 34 | 4568 | 2012-07-08 06:11:05 |
| 17 | 35 | 7445 | 2012-08-08 07:11:05 |
+------+------------+-----------------+---------------------+
Table: Claim
+------+---------+------------+-------+--------------+---------------------+
| id | bill_id | patient_id | level | claim_format | confirmed_date |
+------+---------+------------+-------+--------------+---------------------+
| 10 | 14 | 32 | 1 | 1500 | 2012-08-10 10:57:17 |
| 11 | 14 | 32 | 1 | UB04 | 2012-08-10 11:01:42 |
| 12 | 15 | 33 | 1 | 1500 | 2012-09-10 13:57:17 |
| 13 | 15 | 33 | 1 | UB04 | 2012-09-10 12:01:42 |
| 14 | 16 | 34 | 1 | 1500 | 2012-10-10 12:57:17 |
| 15 | 16 | 34 | 1 | UB04 | 2012-10-10 13:01:42 |
| 16 | 17 | 35 | 1 | 1500 | 0012-11-10 15:57:17 |
| 17 | 17 | 35 | 1 | UB04 | 2012-11-10 14:01:42 |
+------+---------+------------+-------+--------------+---------------------+
I want to update the confirmed_date column of bill table with the confirmed_date of claim table after comparing the greater of the two dates for each bill_id(bill_id and patient_id in claims are foreign keys to id and patient_id in bill)
Did i make myself clear enough?
UPDATE Bill b
SET b.confirmed_date = ( SELECT MAX(confirmed_date) FROM Claim c WHERE b.id = c.bill_id)