MySQL query with condition from 2 tables - mysql

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

Related

how to create a table like this by mysql

I have a table like this:
ID Payment year
A 10 1
A 15 2
A 12 3
B 11 2
B 15 4
C 25 1
C 17 3
I'm looking for a query that returns row for each ID for the its last year. The year column is ordered increasing for each ID.
I need a result like this:
ID Payment year
A 12 3
B 15 4
C 17 3
I have this query so far:
select ID, Payment, Year from payment_table
where year = (select max(year) from ?????????);
I don't know what shall I write instead of ????????
It would be appreciated If anybody gives me some idea.
Use subquery :
select t.*
from table t
where year = (select max(t1.year) from table t1 where t1.id = t.id);

Sql statement groupby with limiting condition

What am trying to do is to return all the records where the total count of truck owners is more than the specified limit
that is in the case below suppose the total limit is 3 i would like to fetch all the owners who have 3 or more trucks registered
so the query if the limit is 3 should only return metro trans as they have 3 or more trucks
This is my db structure
tbl_trucks
id owner_id .....
1 12
2 12
3 13
4 12
tbl_truck_owners
id owner
12 metro trans
13 mush elec
How do i add the limit to my sql statement
THis is what i have tried
SELECT
COUNT(tbl_trucks.owner_id), tbl_truck_owners.owner
FROM tbl_trucks
LEFT JOIN tbl_truck_owners ON tbl_trucks.owner_id = tbl_truck_owners.id
WHERE //stuck at adding the limit
GROUP BY owner_id"
How do i add the limit
Use HAVING statement:
SELECT COUNT(tbl_trucks.owner_id), tbl_truck_owners.owner
FROM tbl_trucks
LEFT JOIN tbl_truck_owners ON tbl_trucks.owner_id = tbl_truck_owners.id
GROUP BY owner_id
HAVING COUNT(tbl_trucks.owner_id) >= 3

Max & AVG MYSQL INNER JOIN for 2 tables

I have 2 tables (example):
users:
ID company_ID
1 7
2 6
3 7
activity_rewards:
user_ID points activity_type_ID
1 1 7
1 2 7
1 1 7
1 1 8
2 1 7
2 1 7
2 2 8
2 1 7
3 2 7
3 1 7
3 2 8
3 1 8
(There are also tables for company and activity_types, but they shouldn't be relevant here)
I need a MYSQL query that will sum the total points for each user WHERE all users have a certain company_ID and for a certain activity_type_ID AND it will return the MAX and the AVG of the sum of all the users points
I have for example:
SELECT SUM(activity_rewards.points) AS totalpoints,
MAX(activity_rewards.points) AS maxpoints,
AVG(activity_rewards.points) AS avgpoints
FROM activity_rewards
INNER JOIN users
ON activity_rewards.user_ID = users.ID
WHERE ( (users.company_ID = "7") && (activity_rewards.activity_type_ID LIKE '8') )
In the example query only 3 results are involved. They are:
user_ID points activity_type_ID
1 1 8
3 2 8
3 1 8
I want to get:
user 1 has 1 point
user 3 has 3 points
Max is 3 average is 2
instead I'm getting Max is 2 and average is 1.33
The results are in line with your query, but your query is not in line with your requirements.
Your query calculates the max and the average of points across the relevant records. But you seem to want the max and the average of the points summed by user id.
This means that you need to calculate the sum of points per user in a subquery and then calculate the max and average in the outer query.
SELECT SUM(sumpoints) as totalpoints, max(sumpoints) as maxpoints, avg(sumpoints) as avgpoints
FROM
(SELECT users.ID, SUM(activity_rewards.points) AS sumpoints
FROM activity_rewards
INNER JOIN users ON activity_rewards.user_ID = users.ID
WHERE users.company_ID = 7 and activity_rewards.activity_type_ID = 8
GROUP BY users.ID) t
Do it like this:
SELECT MAX(sum_points) max, AVG(sum_points) avg, SUM(sum_points) sum_all FROM (SELECT SUM(t2.points) sum_points FROM users t1 JOIN activity_rewards t2 ON (t1.ID = t2.user_ID) WHERE ( (t1.company_ID = "7") AND (t2.activity_type_ID = '8') ) GROUP by t1.ID) as summation

Sum values in mysql table where userid is identical

I have read the different answers here on SO, but I am stuck on this question. Please help.
I have this mysql view named "activeuser":
userid COUNT(*) ACRONYM
1 23 admin
2 2 doe
3 4 tompa
12 4 Marre
13 1 Mia
1 2 admin
3 1 tompa
12 1 Marre
13 1 Mia
2 1 doe
3 1 tompa
12 1 Marre
How can I sum the COUNT column so that I get the following wanted result?
userid COUNT(*) ACRONYM
1 25 admin
2 3 doe
3 6 tompa
12 6 Marre
13 1 Mia
EDITED:
I used this query to create the view:
CREATE VIEW activeuser AS
(SELECT boats_comments.userid, COUNT(boats_comments.userid), boats_user.acronym, boats_user.email
FROM boats_comments
INNER JOIN boats_user
ON boats_comments.userid = boats_user.id
GROUP BY boats_comments.userid
ORDER BY COUNT(boats_comments.userid) DESC)
UNION ALL
(SELECT boats_answers.userid, COUNT(boats_answers.userid), boats_user.acronym, boats_user.email
FROM boats_answers
INNER JOIN boats_user
ON boats_answers.userid = boats_user.id
GROUP BY boats_answers.userid
ORDER BY COUNT(boats_answers.userid) DESC)
UNION ALL
(SELECT boats_questions.userid, COUNT(boats_questions.userid), boats_user.acronym, boats_user.email
FROM boats_questions
INNER JOIN boats_user
ON boats_questions.userid = boats_user.id
GROUP BY boats_questions.userid
ORDER BY COUNT(boats_questions.userid) DESC)
My goal is to see which users are the most active by checking the number of comments, questions and answers... but I got stuck...
As the results in your view has duplicates I guess the underlying code for the view is grouping on something it maybe shouldn't be grouping on.
You can get the results you want by applying SUM to it:
select userid, sum("whatever column2 is named") as "Count", Acronym
from activeuser group by userid, Acronym;
select userid, count(*) from activeuser group by userid;

MySQL select values from Multiple Tables dependent on latest value in one

I have the following three tables to look after support tickets in a small web application, but I need some help getting the data I need.
Table 1 (ticket):
user_ID site_ID support_ID timestamp priority title
12 25 3 2014-09-26 14:09:25 0 A Test Row
12 26 4 2014-09-27 09:41:18 0 A 2nd Test Row
Table 2 (ticket_reply):
reply_ID support_ID user_ID support_reply reply_timestamp
3 3 12 some really boring text 2014-09-26 14:09:25
4 3 25 some really boring reply 2014-09-26 15:35:18
5 4 12 some really boring text 2014-09-27 09:41:18
Table 3 (ticket_status):
ticket_status_ID support_ID status_ID status_timestamp
3 3 40 2014-09-26 14:09:25
4 3 41 2014-09-26 15:35:18
5 4 40 2014-09-27 09:41:18
The 1st table holds the key ticket information, the 2nd, any replies made to the corresponding ticket, and the third tracks the change in status (statuses are held in another table, but don't need anything from there).
What I need to do is get the number of tickets where the latest status is == 40, and if this is greater than 0, get the latest reply along with the data from the first table.
I've tried multiple ways of doing this, but I am stuck. Don't really want to paste them here as they will likely confuse people, and I doubt they are even close.
This one was rather tricky, however here is a working solution for you.
This query will get the most recent support_reply value for all tickets where the most recent status_ID is 40.
SELECT
ticket_status_ID,
support_ID,
status_ID,
status_timestamp,
reply_ID,
support_reply,
reply_timestamp,
`timestamp` ticket_timestamp,
`priority` ticket_priority,
title
FROM (
SELECT * FROM (
SELECT * FROM (
SELECT
ticket_status.ticket_status_ID,
ticket_status.support_ID,
ticket_status.status_ID,
ticket_status.status_timestamp,
ts1.reply_ID,
ts1.user_ID,
ts1.support_reply,
ts1.reply_timestamp
FROM
ticket_status
INNER JOIN (SELECT * FROM ticket_reply ORDER BY reply_timestamp DESC) ts1 ON ts1.support_ID = ticket_status.support_ID
GROUP BY support_ID, status_ID
ORDER BY status_timestamp DESC
) ts2
GROUP BY ts2.support_ID
) ts3
INNER JOIN (SELECT support_ID as `ticket_support_ID`, site_ID, `timestamp`, priority, title FROM ticket) ts4 ON ts4.ticket_support_ID = ts3.support_ID
WHERE ts3.status_ID = 40
) ts5
From the example given, it looks that all timestamp are equivalent, so a query like this should be enough:
SELECT
ticket.*,
ticket_reply.*
FROM
(SELECT support_ID, MAX(status_timestamp) as max_timestamp
FROM ticket_status
GROUP BY support_ID) m
INNER JOIN ticket
ON m.support_ID=ticket.support_ID
AND m.max_timestamp=ticket.`timestamp`
INNER JOIN ticket_reply
ON m.support_ID=ticket_reply.support_ID
AND m.max_timestamp=ticket_reply.reply_timestamp
INNER JOIN ticket_status
ON m.support_ID=ticket_status.support_ID
AND m.max_timestamp=ticket_status.status_timestamp
WHERE
status_ID=40;
but depending on the logic of your application, it might happen that the last row in a table has a timestamp of 2014-09-27 09:41:18 and the last in another has for example 2014-09-27 09:41:19.
In this case, you should use a query like this one:
SELECT
ticket.*,
ticket_reply.*
FROM
(SELECT support_ID, MAX(status_timestamp) AS max_status_timestamp
FROM ticket_status
GROUP BY support_ID) m_status
INNER JOIN
(SELECT support_ID, MAX(reply_timestamp) AS max_reply_timestamp
FROM ticket_reply
GROUP BY support_ID) m_reply
ON m_status.support_ID=m_reply.support_ID
INNER JOIN
(SELECT support_ID, MAX(`timestamp`) AS max_ticket_timestamp
FROM ticket
GROUP BY support_ID) m_ticket
ON m_status.support_ID=m_ticket.support_ID
INNER JOIN ticket_status
ON ticket_status.support_ID=m_status.support_ID
AND ticket_status.status_timestamp=m_status.max_status_timestamp
INNER JOIN ticket_reply
ON ticket_reply.support_ID=m_reply.support_ID
AND ticket_reply.reply_timestamp=m_reply.max_reply_timestamp
INNER JOIN ticket
ON ticket.support_ID=m_ticket.support_ID
AND ticket.`timestamp`=m_ticket.max_ticket_timestamp
WHERE
ticket_status.status_ID=40;
Please see fiddle here.
You can try this one:
SELECT t.*, tr.support_reply, ts.status_timestamp
FROM ticket_status as ts
left join ticket_reply as tr on(ts.support_ID=tr.support_ID)
left join ticket as t on(t.support_ID=tr.support_ID)
where status_ID=40
order by status_timestamp desc
limit 1;