MySQL Retrieving data from two tables using inner join syntax - mysql

My two tables are
Entry
event_id competitor_id place
101 101 1
101 102 2
101 201 3
101 301 4
102 201 2
103 201 3
second table lists prizes on offer for the events
Prize
event_id place money
101 1 120
101 2 60
101 3 30
102 1 10
102 2 5
102 3 2
103 1 100
103 2 60
103 3 40
From this I am looking to show all the information from the Entry table alongside the amount of money they won for their respected placing. If they failed to place in the money then a 0 will be displayed.
Any help would be appreciated.

try this:
SELECT a.Event_ID,
a.Competitor_ID,
a.Place,
COALESCE(b.money, 0) as `Money`
FROM entry a left join prize b
on (a.event_id = b.event_ID) AND
(a.place = b.Place)
hope this helps.
EVENT_ID COMPETITOR_ID PLACE MONEY
101 101 1 120
101 102 2 60
101 201 3 30
101 301 4 0 -- << this is what you're looking for
102 201 2 5
103 201 3 40

Try this:
select e.*, coalesce(p.money, 0) money from entry e
left join prize p
on e.event_id = p.event_id and e.place = p.place
You can play with the fiddle here.

SELECT * FROM Entry NATURAL LEFT JOIN Prize;
If you absolutely want 0 instead of NULL for the "money" when no prize was won (but how can you differentiate between a prize of 0 and no prize?):
SELECT Entry.*, COALESCE(money, 0) AS money FROM Entry NATURAL LEFT JOIN Prize;
See them both on sqlfiddle.

Related

Join two tables in MySQL, have just one row in the result set with few columns selected from second table

I am having a challenge to achieve the following
Have 2 tables namely Transaction Table and Transaction_Event_LOG_INFO table
Transaction Table Details
SL
TXN_ID
TXN_FOR
TXN_TYPE
1
111
Shopping
Debit
2
112
Rent
Debit
Transaction_Event_LOG_INFO table
SL
TXN_ID
EVT_ID
EVT_CODE
EVT_CREATED_DT
1
111
200
100
11-12-2020 12:00:00
1
111
201
101
11-12-2020 12:01:00
1
111
202
102
11-12-2020 12:02:00
1
111
203
103
11-12-2020 12:03:00
1
111
204
104
11-12-2020 12:04:00
1
112
205
100
11-12-2020 12:05:00
1
112
206
101
11-12-2020 12:06:00
1
112
207
102
11-12-2020 12:07:00
1
112
208
103
11-12-2020 12:08:00
1
112
209
104
11-12-2020 12:09:00
I need to join the above two tables based on TXN_ID (which is unique) and have just one row for every TXN ID and having all columns from 1st table and just the EVT_CREATED_DT from 2nd table like where EVT_CODE=100 and 104
like below
SL
TXN_ID
TXN_FOR
TXN_TYPE
EVT_CREATED_DT_FOR_100
EVT_CREATED_DT_104
1
111
Shopping
Debit
11-12-2020 12:00:00
11-12-2020 12:04:00
2
112
Rent
Debit
11-12-2020 12:05:00
11-12-2020 12:09:00
You can do cnoditional aggregation:
select t.*, te.evt_created_dt_100, te.evt_created_dt_104
from transaction t
inner join (
select txn_id
max(case when evt_code = 100 then evt_created_dt end) as evt_created_dt_100,
max(case when evt_code = 104 then evt_created_dt end) as evt_created_dt_104
from transaction_event_log_info
where evt_code in (100, 104)
group by txn_id
) te on te.txn_id = t.txn_id
In very recent versions of MySQL, this would be more efficiently phrased with a lateral join:
select t.*, te.*
from transaction t
cross join lateral (
select
max(case when te.evt_code = 100 then te.evt_created_dt end) as evt_created_dt_100,
max(case when te.evt_code = 104 then te.evt_created_dt end) as evt_created_dt_104
from transaction_event_log_info te
where te.evt_code in (100, 104) and te.txn_id = t.txn_id
) te
If you want to allow transactions that have none of the two events, you would change the inner join to a left join - and the cross join lateral (...) te to a left join lateral (...) te on true.

MySQL three table join with sum

I have three tables
Student
studenid stuname
101 john
102 aron
103 mary
104 lucy
Subject
studenid subjid subjname
101 1 maths
102 2 science
103 3 computer
104 4 english
Marks
subjid mark
1 50
2 40
3 55
4 60
1 40
2 55
3 60
I want output like this where studenid (sum of mark as total)
studenid stuname mark
101 john 90
102 aron 95
103 mary 115
104 lucy 60
Thank you in advance for yout help, i want output like this even join query or subquery which is best for timing
This just requires a straight left join across all tables, with an aggregation by student.
SELECT
st.studenid,
st.stuname,
COALESCE(SUM(m.mark), 0) AS mark
FROM Student st
LEFT JOIN Subject su
ON st.studenid = su.studenid
LEFT JOIN Marks m
ON su.subjid = m.subjid
GROUP BY
st.studenid,
st.stuname;
Demo
Note that if studenid be a primary key in the Student table, then strictly we would only need to aggregate by this column alone.

mysql subquery where value appears twice or more

I have two tables as below (MYSQL)
ENTRY table
Event_id | Horse_id | Place
101 101 1
101 102 2
101 201 3
101 301 4
102 201 2
103 201 3
201 101 1
301 301 2
401 102 7
HORSE table
Horse_id Name
101 Flash
102 Star
201 Boxer
301 Daisy
401 Snowy
I need to list the horse_id and name of horses that place (1, 2 or 3) two times or more.
best I can come up with which is not near it I know (need to do a subquery)
select horse_tbl.horse_id, horse_tbl.name
from horse_tbl
left join entry_tbl
on horse_tbl.horse_id = entry_tbl.horse_id
where place<4(
select count(horse_id)>1));
Any help would be greatly appreciated
Your query is on the right track, but instead of using a WHERE clause to check the place, you should be using GROUP BY along with conditional aggregation in the HAVING clause:
SELECT
h.horse_id,
h.name
FROM horse_tbl h
LEFT JOIN entry_tbl e
ON h.horse_id = e.horse_id
GROUP BY
h.horse_id,
h.name
HAVING SUM(CASE WHEN e.place IN (1, 2, 3) THEN 1 ELSE 0 END) >= 2
Output:
Demo here:
Rextester

Fetch Data from master table based on child table condition in sql server

Need to fetch data from master table based on child table condition.
Master Table:-
ID Name Address
1 abc xyz
2 abs txt
3 aui tre
4 pop top
5 the tre
6 pot tos
7 pog sop
8 pat top
9 bat cric
10 not kot
Child Table:-
chid shootid imagename IDFK
101 234 123ab.jpg 3
102 234 54abcab.jpg 3
103 235 123abc.jpg 3
104 236 12390acb.jpg Null
105 235 12332aab.jpg 8
106 234 123786ab.jpg 4
107 234 54789abcab.jpg 10
108 235 122343abc.jpg 10
109 235 122123acb.jpg 4
110 234 12123aab.jpg 9
111 234 1223ab.jpg Null
112 233 5432abcab.jpg Null
113 235 1239abc.jpg Null
114 236 1238acb.jpg 2
115 236 12356aab.jpg 2
116 236 1235ab.jpg 2
117 236 545abcab.jpg Null
118 237 1233abc.jpg 1
119 237 1223acb.jpg 1
120 237 1123aab.jpg 1
In Child table IDFK is the foreign key and ID in Master table is the primary key of that.
Now i want to show those name from master table that doesn't exist on child table filter on shootid like where childtable.Shootid=234. I tried but not find the desired output.Every time it just return's the same out for different shootid as well.
Please help me and show me the right query for that.
I don't know if I am understand you well or not but I think this is what you want,
Select * from [master] m
where m.ID not in (Select IDFK from detail where shootid=234)
I think this is what you are looking for.
Select distinct m.name from master m LEFT OUTER JOIN child c
ON m.id = c.id and
c.shootid=234
where
c.id is null

Query to display the only the most recent message of each thread

Environment PHP 5.3.5 phpMyAdmin 3.3.9
Here's an link of the issue in sqlfiddle
Trying to create a query which filters through a user's message activity. The activity will display the most recent threads based upon message recently added. So I have to consider if the user is the recipient or sender.
I have a query structured but I am having great difficulty on grouping the threads. When I group the threads, the order of the most recent activity is lost.
Here is the query and results which captures the correct order of the last 10 messages but there are duplicate thread_ids. I want to only display the most recent thread based upon the message sent date.
SQL query:
SELECT m.date_sent, m.thread_id, m.message_id, m.sender_id,
upub2.firstname as sender_name, mr.recipient_id,
upub1.firstname as recipient_name
FROM message AS m
JOIN message_recipient AS mr ON mr.message_id = m.message_id
JOIN user_public_info AS upub1 ON upub1.user_public_info_id = mr.recipient_id
join user_public_info AS upub2 ON upub2.user_public_info_id = m.sender_id
WHERE ((m.senderDelete IS NULL OR m.senderDelete = 0) AND m.sender_id = 2 ) OR
((mr.is_delete IS NULL OR mr.is_delete = 0 ) AND mr.recipient_id = 2)
ORDER BY m.message_id;
Results:
date_sent thread_id message_id sender_id sender_name recipient_id recipient_name
2013-10-09 14:31:50 106 113 1 John 2 Mark
2013-10-09 14:30:50 107 112 2 Mark 1 John
2013-10-09 14:30:31 106 111 2 Mark 1 John
2013-10-09 09:49:58 112 110 1 John 2 Mark
2013-10-09 09:20:24 108 106 1 John 2 Mark
2013-10-07 15:46:15 107 105 1 John 2 Mark
2013-10-07 14:40:25 103 104 1 John 2 Mark
2013-10-07 14:39:37 103 103 1 John 2 Mark
2013-10-07 14:36:34 107 102 2 Mark 1 John
2013-10-07 14:36:07 106 101 2 Mark 1 John
2013-10-07 14:35:29 105 100 2 Mark 1 John
2013-10-07 12:32:50 104 99 2 Mark 1 John
2013-10-07 12:15:43 104 98 2 Mark 1 John
2013-10-07 11:46:36 104 97 2 Mark 1 John
2013-10-07 11:43:32 104 96 1 John 2 Mark
2013-10-07 11:43:17 104 95 1 John 2 Mark
2013-10-07 11:27:14 103 94 1 John 2 Mark
What I want is this:
date_sent thread_id message_id sender_id sender_name recipient_id recipient_name
2013-10-09 14:31:50 106 113 1 John 2 Mark
2013-10-09 14:30:50 107 112 2 Mark 1 John
2013-10-09 09:49:58 112 110 1 John 2 Mark
2013-10-09 09:20:24 108 106 1 John 2 Mark
2013-10-07 14:40:25 103 104 1 John 2 Mark
2013-10-07 14:35:29 105 100 2 Mark 1 John
2013-10-07 12:32:50 104 99 2 Mark 1 John
Can this be done in one single query or should I create another query based upon the results of the first query?
Thank you for anyone that can help me solve this query....
Your various data sets, queries, and results do not appear to correspod with one another so it's a little difficult to follow, but I suspect you're after something along these lines...
SELECT m.message_id m_id
, m.sender_id s_id
, m.thread_id t_id
, m.subject
, m.message
, m.date_sent
, s.firstname sender
, r.firstname recipient
FROM message m
JOIN message_recipient n
ON n.message_id = m.message_id
JOIN user_public_info s
ON s.user_public_info_id = m.sender_id
JOIN user_public_info r
ON r.user_public_info_id = n.recipient_id
JOIN (SELECT thread_id, MAX(max_message_id) max_message_id FROM message GROUP BY thread_id)x
ON x.thread_id = m.thread_id AND x.max_message_id = m.message_id;