JOIN data from 2 MySQL tables - mysql

I have a question about joining the data from 2 tables from a MySQL Database. First I will explain what I currently have and then what I want just to be as clear as possible.
I have 2 tables in the Database which look like this:
Table: Subscriptions
Columns:
ID int(11) PK AI
Klant ID int(11)
Mail ID int(11)
Status varchar(15)
Datum varchar(15)
ID Klant_ID Mail_ID Status Datum
123 6 6 90 21-03-2013
124 6 6 10 21-03-2013
125 6 5 90 21-03-2013
126 6 5 10 21-03-2013
127 6 1 90 20-03-2013
128 6 1 10 20-03-2013
129 6 2 10 21-03-2013
130 6 2 90 21-03-2013
131 6 4 90 21-03-2013
132 6 4 10 21-03-2013
And:
Table: Mail
Columns:
ID int(11) PK AI
Content longtext
Datum varchar(15)
Titel varchar(150)
ID Content Datum Titel
1 (alot of encoded html) 18-03-13 test
2 (alot of encoded html) 18-03-13 test2
4 (alot of encoded html) 18-03-13 alles weer testen
5 (alot of encoded html) 20-03-13 testje
6 (alot of encoded html) 21-03-13 Statusupdate week 6
I am using these 2 queries to select the data from the tables now:
SELECT ID, Titel FROM Mail
SELECT * FROM Subscriptions,
(SELECT MAX(ID) as ids, Mail_ID FROM Subscriptions
WHERE Klant_ID = '".$_GET["ID"]."' GROUP BY Mail_ID) table2
WHERE ID=table2.ids
I want to get a query using JOIN to be able to create this table using html:
I personaly haven't got much experience using JOIN since I first used it yesterday, I am able to make a simple JOIN query but I just don't know how to do this. If you have more questions ask them in the comments. If anyone could help me with this it would be great!

this is a simple Join between your tables
SELECT Mail_ID, Titel, Status, Subscriptions.Datum FROM Subscriptions
JOIN Mail ON (Subscription.Mail_ID=Mail.ID)
WHERE Klant_ID = '".$_GET["ID"]."' GROUP BY Mail_ID
the order of the rows is random by a join,
if you want to get the last data, your query is right.

Try:
select mail.id, mail.titel, subscriptions.status, subscriptions.datum
from mail join subscriptions on mail.id = subscriptions.mail_id

Tyvm #kolonel peteruk, #Kaii and #JaMaBing for your answers!
With your help I was able to merge my query with yours. I finally got it to work using this query:
SELECT Mail.ID, Mail.Titel, Subscriptions.ID, Subscriptions.Status, Subscriptions.Datum, Subscriptions.Mail_ID, Subscriptions.Mail_ID, Subscriptions.Klant_ID
FROM NAW.Subscriptions
JOIN NAW.Mail
ON Mail.ID = Subscriptions.Mail_ID,
(SELECT MAX(Subscriptions.ID) as ids, Mail_ID
FROM NAW.Subscriptions
WHERE Klant_ID =6
GROUP BY Mail_ID) table2
WHERE Subscriptions.ID=table2.ids

SELECT e.ID ,e.Titel,ea.Status,ea.Datum
FROM Mail e
LEFT JOIN Subscriptions ea
ON e.ID = ea.Mail_ID
WHERE ea.Klant_ID = '".$_GET["ID"]."'
GROUP BY Mail_ID)
ORDER BY e.ID ASC

Related

join to most recent right hand record, but place NULL when right table doesn't have data

i am trying to build a view/query that hops across multiple joins showing one result row per left hand record, with the right hand record being the most recently-created record for that object in the table.
the end goal is to provide data to a front end application, but i need to be able to tell if there is no data in the right hand table while still displaying the data from the left hand table.
i don't know if i've worded that well; i'm a little out of my depth. maybe code will illustrate better than english. here are some tables to illustrate:
left hand table bill
id description extId
1 Some descr... SB 123
2 Another de... SB 124
3 Third desc... SB 125
join table tally_bill
id billId tallyId
1 2 1
2 2 2
3 3 3
4 3 4
note that there is no entry for billId = 1
right hand table tally
id countYes countNo created
1 4 0 2022-09-26 13:11:48
2 5 8 2022-09-26 14:50:24
3 10 11 2022-09-26 11:20:01
4 4 3 2022-09-26 13:41:25
my desired result looks something like this:
billId description extId countYes countNo
1 Some descr... SB 123 null null
2 Another de... SB 124 5 8
3 Third desc... SB 125 4 3
i need countYes and countNo to be the values from the most recently-created record in tally.
the query i've gotten so far is:
SELECT
bill.id, bill.description, bill.extId,
tally.id, tally.countYes, tally.countNo
FROM
bill
LEFT JOIN tally_bill
ON tally_bill.billId = bill.id
LEFT JOIN tally
ON tally.id = tb.tallyId
AND (
SELECT
MAX(tally.id)
FROM
tally_bill tb
WHERE
tb.billId = bill.id);
but this produces something to the effect of:
billId description extId id countYes countNo
2 Another de... SB 124 2 5 8
3 Third desc... SB 125 4 4 3
as you see the record billId = 1 is missing. i have made a few variations on this query moving the subquery around, trying group bys and partitions, etc., to no avail. i'm at the limit of my SQL-fu, so i would appreciate any help or enlightenment, please :)
i'm using MySQL 8.0.30 but if there is a need to change versions i'm open to it.
select id
,description
,extId
,countYes
,countNo
from (
select b.id
,b.description
,b.extId
,t.countYes
,t.countNo
,row_number() over(partition by b.id order by t.id desc) as rn
from bill b left join tally_bill tb on tb.billId = b.id left join tally t on t.id = tb.tallyId
) t
where rn = 1
id
description
extId
countYes
countNo
1
Some descr
SB 123
null
null
2
Another de
SB 124
5
8
3
Third desc
SB 125
9
4
Fiddle

MySQL query with condition from 2 tables

I'm new to programming and MySQL and I think this is simple but not for me. So, I have two tables, Tickets and Ticket_user, and I need to get all the fields from the Table Ticket where user_id =15 and ticket_id >8.
Table 1 : Ticket
id name ...... other fields
7 Tickte1
8 Tickte2
9 ticket3
10 ticket4
11 Tickte5
Table 2 : Ticket_users
id ticket_id User_id
1 7 15
2 8 16
3 9 15
4 10 15
5 11 8
Result:
ticket_id name ...... other fields
9 Tickte3
10 ticket4
How can I achieve this?
Both queries will work.
The second is faster if you have to handle a lot of data
First uses IN clause
SELECT
id, name
FROM
Ticket
WHERE
id IN (SELECT
ticket_id
FROM
Ticket_users
WHERE
User_id = 15 AND ticket_id > 7);
second uses INNER JOIN
SELECT
id, name
FROM
Ticket t
INNER JOIN
(SELECT
ticket_id
FROM
Ticket_users
WHERE
User_id = 15 AND ticket_id > 7) ut ON t.id = ut.ticket_id;
You need to look into JOIN CLAUSE.
What your looking for is something like this
SELECT t.*
FROM Ticket t LEFT JOIN Ticket_users tu ON t.id = tu.ticket_id
WHERE tu.user_id = 15 AND t.id > 8

Multiple join with self join in MySQL and split rows in columns by a row value

I have three tables "Users" , "Subjects" and "Marks" like
Users Table
id name
1 A
2 B
3 C
4 D
5 E
6 A
7 B
Subjects Table
id name
1 Chemistry
2 Physics
3 English
4 Maths
5 History
Marks Table
u_id is the foreign key of Users (id) and s_id is foreign key of Subjects(id)
id u_id s_id marks
1 1 1 60
2 1 2 70
3 1 3 80
4 2 2 80
5 2 3 44
6 3 1 50
7 5 4 50
8 4 5 50
9 5 4 100
10 2 5 100
and I wish for the result to be like
id Name Chemistry Physics English
1 A 60 70 80
2 B NULL 80 44
3 3 50 NULL NULL
Using Join
So far I have only been able to get
name name marks
A English 80
A Physics 70
A Chemistry 60
B English 44
B Physics 80
C Chemistry 50
Using the following query
SELECT u.name, s.name , m.marks
FROM Users as u
RIGHT JOIN Marks as m ON m.u_id = u.id
LEFT JOIN Subjects as s ON m.s_id = s.id
WHERE s.name = "English"
OR s.name = "Physics"
OR s.name = "Chemistry"
ORDER BY u.name; "
Well, after reading the answers, I wanted to post my own one:
SELECT
u.id
, u.name
, MAX(IF(s.id = 1, COALESCE(m.mark), 0)) as 'Chem'
, MAX(IF(s.id = 2, COALESCE(m.mark), 0)) as 'Phys'
, MAX(IF(s.id = 3, COALESCE(m.mark), 0)) as 'Eng'
FROM marks m
INNER JOIN subjects s
ON s.id = m.subjects_id
INNER JOIN users u
ON u.id = m.users_id
GROUP BY u.id
You can check that makes all you want in SqlFiddle: http://sqlfiddle.com/#!9/f567b/1
The important part is the grouping of all the elements according to the user id, and the way of writing the results from rows in a table to columns in another table. As written in #TheShalit answer, the way of achieving that is just assigning the value as a column. Problem is that when grouping by user, you'll have a lot of values there from where you have to select the important one (the one that is not 0 neither NULL, XD). COALESCE function makes sure that you always return a integer, just in case a NULL is given.
It's also important to notice that you'll have to build the SQL with the names of the subjects and the ids from database, as SQL can't retrieve the name of the elements to write them directly as names of the columns. That's why I wrote 'Chem', 'Phys' and 'Eng' instead of the right names. In fact, would be easier if you just wrote the id of the subject instead of a name, just to retrieve the elements later when you'll fetch the rows.
Take into account that is VERY IMPORTANT that you'll table will have the right indexes there. Make sure you have an UNIQUE id on the table marks with users and subjects to avoid having more than one value there stored
Use select like this(with joins and group by student):
MAX(If(subjects.name="Chemistry",marks.marks,'')) Chemistry,
MAX(If(subjects.name="Physics",marks.marks,'')) Physics,
.....
You will need to do something like:
SELECT u.NAME AS NAME,
m_e.marks AS english,
m_p.marks AS physics,
m_c.marks AS chemistry
FROM users AS u
JOIN marks AS m_e ON m_e.u_id = u.id
JOIN marks AS m_p ON m_p.u_id = u.id
JOIN marks AS m_c ON m_c.u_id = u.id
WHERE m_e.s_id = 3 AND m_c.s_id = 1 AND m_p.s_id = 2
You are getting 3 different values from a single table but different rows so you need to join the marks table with itself to be able to get the values from 3 different records into 1 result row
I used the values that you defined as primary id's for your 3 subjects in your question in the where clause to make sure you are getting the correct result for each subject

Sql show top 10 requested products of every group

I have the following data stored in my database.
I want to know what the 10 most searched parts are for every car.
Below I made an example of the data that is stored in the database.
One table contains the names of the cars with the car id.One table contains the requests with one or more request id('s) for every car.One table contains the request id with the name of the requested part.
Table cars
audi (7)
bmw (12)
Table request
7 (100)
7 (234)
7 (367)
7 (562)
7 (729)
7 (765)
7 (881)
Table request_parts
100 (achterband)
234 (voorband)
367 (motor)
562 (accu)
729 (achterband)
765 (kopeling)
881 (koeling)
What the query should return is something like this, as in the example 'achterband' was found twice
audi achterband 2
audi voorband 1
audi motor 1
audi accu 1
audi kopeling 1
The query that I currently have counts how often the part 'motor' has been requested for every car. however I can't find out how to do this not just for one product but for all of them at the same time. right now its not important to have the name of the car as the id is already shown.
SELECT COUNT(*), requests.sibben_brand_id, request_parts.name
FROM request_parts
JOIN requests ON requests.id = request_parts.request_id
WHERE requests.sibben_brand_id IS NOT NULL
AND request_parts.name LIKE 'motor'
GROUP BY requests.sibben_brand_id
ORDER BY COUNT(*) DESC `
Does any one has a idea how i could get the correct data?
try with this:
SELECT COUNT(*), requests.sibben_brand_id, request_parts.name
FROM request_parts
JOIN requests ON requests.id = request_parts.request_id
WHERE requests.sibben_brand_id IS NOT NULL
GROUP BY requests.sibben_brand_id,request_parts.name
ORDER BY COUNT(*) DESC `
with
cars table as (id,name)
request table as (id,car_id,request_id)
request_parts table as (id,request_id,part_name)`
the following query returns top 10 records
select top 10 c.name, rqp.part_name,count(*) as repetition
from request as r, request_parts as rqp, cars as c
where rqp.request_id = r.request_id AND r.car_id = c.Id
group by rqp.part_name,c.name
order by repetition desc`

SUM 2 Field from 2 different tables

I have a mysql query like this :
SELECT SUM(bills.Amount) AS AmountExpense, SUM(assets.Amount) as AmountIncome
FROM bills, assets where bills.UserId = 11 and assets.UserId =11
Sample Bills table
id payee description UserId Amount
1 john advance 11 15.0
2 dave request 2 13.0
3 er request 11 12.0
Sample assets table
id payee description UserId Amount
1 john advance 11 40.2
2 dave request 2 13.0
3 ww request 11 14.00
I have a problem with AmountExpense, the record SUM record multiple time. I have successed with Amount Income. Any suggestions?
You have most likely more than one row per user on one or both of those tables. You'll need to join them after performing the aggregation. Also, please don't use old style non ANSI implicit joins:
SELECT AmountExpense, AmountIncome
FROM ( SELECT UserId,
SUM(Amount) AS AmountExpense
FROM bills
GROUP BY UserId) AS b
LEFT JOIN ( SELECT UserId,
SUM(Amount) AmountIncome
FROM assets
GROUP BY UserId) AS a
ON b.UserId = a.UserId
WHERE b.UserId = 11
If you have the possibility that users can be in either table, but not the other, then you want the equivalent of a full outer join. MySQL doesn't support that syntax, but it does support this:
select userid, sum(amountexpense) as amountexpense, sum(amountincome) as amountincome
from (select userid, amount as amountexpense, null as amountincome
from bills
union all
select userid, null, amount as amountincome
from assets
) ba
group by userid;