Newest loan per user for all users - php

// Edit:
All work fine with:
SELECT u.*,
l.cod AS loans_cod,
l.step AS loans_step
FROM users AS u
LEFT JOIN loans AS l
ON u.id = l.users_id
WHERE l.step < 12
OR NOT EXISTS
(SELECT l.id
FROM loans
WHERE l.users_id = u.id
)
GROUP BY u.id
Now, I can select all user, and his last loan. Thanks, and I think my solution will help future users.

if you want the last loan, you could append something like this
ORDER BY l.date DESC GROUP BY u.id

SELECT u.*,
l.cod AS loans_cod,
l.step AS loans_step
FROM users AS u
LEFT JOIN loans AS l
ON u.id = l.users_id
WHERE u.id != :id
AND l.timestamp = (SELECT MAX(l.timestamp)
FROM loans AS l2
WHERE l2.users_id = l.users_id)
Where timestamp is a column on your table that indicates when the loan was created or otherwise gives you a time that you can compare to.

Try this:
SELECT u.*, l.cod AS loans_cod,
l.step AS loans_step
FROM users AS u inner join
(
select max(l.loan_id) as loan_id, l.users_id , l.cod, l.step
from loans l
group by
l.users_id,l.cod,l.step
) as l
ON u.id = l.users_id
WHERE u.id != :id
Note: Avoid doing select * it's a very bad practice. List all the columns you need only.

Related

how to subtract one query result to another query in mysql

this is my first query
SELECT DISTINCT(u.nickname) FROM user u
where u.id IN(SELECT `submission_user`.`user_id` from `submission_user`) AND
u.member_since >= '2015-07-01'
this is my second query
SELECT DISTINCT(u.nickname) FROM user u LEFT JOIN submission_user su ON su.user_id = u.id
LEFT JOIN submission s ON s.id = su.submission_id
WHERE s.date_time BETWEEN '2017-10-31' and '2018-07-31'
and this is my third query
SELECT DISTINCT(u.nickname) FROM user u LEFT JOIN submission_user su ON su.user_id = u.id
LEFT JOIN track_user tu ON tu.user_id = u.id
LEFT JOIN track ON track.id = tu.track_id
where track.uploaded_timestamp BETWEEN '2017-10-31' and '2018-07-31'
and after that, I am merging the second and third query result
$ids_reactivated = array_unique(array_merge($track_user, $submit_user));
so my question is that if I want to subtract query one result to merge result means with the (query 2 and 3)i.e in my case: $ids_reactivated
anyone have an idea how to do it ...
I already tried many ways and passed one day...
hope pepls help me thanks
thanks for your hint but i got my answer like this ...
SELECT DISTINCT(u.nickname) FROM user u
where u.id IN(SELECT `submission_user`.`user_id` from `submission_user`) AND
u.member_since >= '2015-07-01'
**and u.nickname not in ($query2)**
UNION
SELECT DISTINCT(u.nickname) FROM user u
where u.id IN(SELECT `submission_user`.`user_id` from `submission_user`) AND
u.member_since >= '2015-07-01'
**and u.nickname not in ($query3)**
Its simple You can make use of union for merging and not in for substraction
Following is the sample
SELECT DISTINCT(u.nickname) FROM user u LEFT JOIN submission_user su ON su.user_id = u.id LEFT JOIN submission s ON s.id = su.submission_id
WHERE s.date_time BETWEEN '2017-10-31' and '2018-07-31'
**and u.nickname not in ($query1)**
UNION
SELECT DISTINCT(u.nickname) FROM user u LEFT JOIN submission_user su ON su.user_id = u.id LEFT JOIN track_user tu ON tu.user_id = u.id LEFT JOIN track ON track.id = tu.track_id
where track.uploaded_timestamp BETWEEN '2017-10-31' and '2018-07-31'
**and u.nickname not in ($query1)**
change the $query1 with your query ,it should give the result

EXISTS query optimization on mysql query

I have a big data problem with MySQL.
I have:
a users table with 59033 rows, and
a user_notes table with 8753 rows.
But when I search which users have user note in some dates.
My query like this :
SELECT u.*, rep.name as rep_name FROM users as u
LEFT JOIN users as rep on rep.id = u.add_user
LEFT JOIN authorization on authorization.id = u.authorization
LEFT JOIN user_situation_list on user_situation_list.user_situation_id = u.user_situation
WHERE
EXISTS(
select * from user_notes
where user_notes.note_user_id = u.id AND user_notes.create_date
BETWEEN "2017-10-20" AND "2017-10-22"
)
ORDER BY u.lp_modify_date DESC, u.id DESC
Turn it around -- find the ids first; deal with the joins later.
SELECT u.*,
( SELECT rep.name
FROM users AS rep
WHERE rep.id = u.add_user ) AS rep_name
FROM (
SELECT DISTINCT note_user_id
FROM user_notes
WHERE create_date >= "2017-10-20"
AND create_date < "2017-10-20" + INTERVAL 3 DAY
) AS un
JOIN users AS u ON u.id = un.note_user_id
ORDER BY lp_modify_date DESC, id DESC
Notes
No GROUP BY needed;
2 tables seem to be unused; I removed them;
I changed the date range;
User notes needs INDEX(create_date, note_user_id);
Notice how I turned a LEFT JOIN into a subquery in the SELECT list.
If there can be multiple rep_names, then the original query is "wrong" in that the GROUP BY will pick a random name. My Answer can be 'fixed' by changing rep.name to one of these:
MAX(rep.name) -- deliver only one; arbitrarily the max
GROUP_CONCAT(rep.name) -- deliver a commalist of names
Rewriting your query to use a JOIN rather than an EXISTS check in the where should speed it up. If you then group the results by the user.id it should give you the same result:
SELECT u.*, rep.name as rep_name FROM users as u
LEFT JOIN users as rep on rep.id = u.add_user
LEFT JOIN authorization on authorization.id = u.authorization
LEFT JOIN user_situation_list on user_situation_list.user_situation_id = u.user_situation
JOIN user_notes AS un
ON un.note_user_id
AND un.create_date BETWEEN "2017-10-20" AND "2017-10-22"
GROUP BY u.id
ORDER BY u.lp_modify_date DESC, u.id DESC

How to perform inner join in mysql

I have to write a query such that ,I need to get events whose start date is of 30 min from now.
My conditions are:
1) get the event from events table
2)Join created by of events with id in users table.
3)Comments from comment table with user ser id
But the problem here is if there is no comment for event then the event it self is not coming.If any comment is present it is coming.I dont want this.If comment is not there just fetch it as empty but not hide the total event .Can anyone please help me,.Thanks.
select u.email ,group_members.user_id,users.first_name,u.first_name
as host_name,events.name,events.start_date,comments.comments,c.first_name as
comment_user,comments.id from events
inner join users as u on u.id = events.created_by
inner join comments on events.id = comments.event_id
inner join group_members on events.group_id = group_members.group_id
inner join users as c on comments.from_user = c.id
inner join users on group_members.user_id = users.id
where events.start_date between date_add(now(),interval 1 minute) and date_add(
now(),interval 30 minute)
and group_members.user_status = 2
and events.status = 2
You need a left join to the comments table. I would put that table last in the from clause.
select u.email, gm.user_id, gu.first_name, u.first_name as host_name,
e.name, e.start_date, c.comments, uc.first_name as comment_user,
c.id
from events e inner join
users u
on u.id = e.created_by inner join
group_members gm
on e.events.group_id = gm.group_id inner join
users gu
on gm.user_id = gu.id left join
comments c
on e.id = c.event_id left join
users uc
on c.from_user = uc.id
where e.start_date between date_add(now(),interval 1 minute) and date_add(now(),interval 30 minute) and
gm.user_status = 2 and
e.status = 2;
Once you use a left join on comments, you also need a left join for the from user. I replaced all table names with aliases -- this makes it easier to track which table is used for which purpose.
Use the INNER JOIN Keyword and select the two columns by putting them with keyword ON.
SELECT EMP.EMP_ID, EMP.EMP_NAME, DEPT.DEPT_NAME FROM EMP
INNER JOIN DEPT ON DEPT.DEPT_ID = EMP.DEPT_ID;

MySQL: Select rows where `project_id` equals any `project` with specific `user_id`

This can't be too hard, but I don't know what the term is I'm looking for. I'm sure you guys can help me out. :)
I have a table tasks with rows that have a column project_id. Each project_id refers to (the id of) a row in the projects table. Each project belongs to a certain user which is why it has a column user_id.
I now want to select all tasks from this table where the project_id equals any project of a certain user.
Or put more simply:
Each TASK belongs to a PROJECT which belongs to a USER.
I want to create a SELECT-statement to receive all TASKS that belong to a specific USER. The only link between each TASK and a USER is through the PROJECT.
How do I accomplish this?
Thank you very much for your help! :)
JOIN the tables:
SELECT
t.*
FROM tasks t
INNER JOIN projects p ON t.project_id = p.project_id
INNER JOIN users u ON p.user_id = u.user_id
WHERE u.user_id = #AcertianUserId
SELECT
tasks.*
FROM
users
INNER JOIN
projects ON users.id = projects.user_id
INNER JOIN
tasks ON projects.id = tasks.project_id
WHERE
users.id = 1
SQL Fiddle
select t.*
from tasks t
join projects p on p.id = t.project_id
join users u on u.id = p.user_id
where u.id = 17
Try :
SELECT t.*
FROM user u, projet p, task t
WHERE u.id = p.user_id
AND p.id = t.project_id
AND u.id = your_id
Or (same result) :
SELECT t.*
FROM user u
INNER JOIN projet p ON u.id = p.user_id
INNER JOIN task t ON p.id = t.project_id
WHERE u.id = your_id

MySQL Query Multiple LEFT Joins problem

I am trying to get the required result from the following query but it doesnt seem to work...
SELECT DISTINCT
u.user_name as user_name,
u.total_points as total_points,
u.user_id as user_id,
COUNT(a.id) as user_total_articles_published,
COUNT(r.id) as user_total_replies_published,
COUNT(v.id) as user_total_votes_done
FROM users as u
LEFT JOIN articles as a ON u.user_id=a.user_id
LEFT JOIN replies as r ON u.user_id=r.user_id
LEFT JOIN votes as v ON u.user_id=v.user_id
GROUP BY u.user_id
ORDER BY u.total_points DESC
LIMIT 10
If i remove the last 2 LEFT jOINS the query will work... whats wrong with the other 2? Do i have to use another method for this to work?
thanks
I think by 'not working' you mean that the query returns too many records? That is because of the combination of joins. You return each reply for each article record, so the numbers are multiplied. You can solve this by using DISTINCT in the COUNT. That way, you count the unique id's, so you count each article only once:
COUNT(distinct a.id) as user_total_articles_published,
COUNT(distinct r.id) as user_total_replies_published,
COUNT(distinct v.id) as user_total_votes_done
[edit]
A possibly faster solution, eliminating the need for DISTINCT and GROUP BY:
SELECT
u.user_name as user_name,
u.total_points as total_points,
u.user_id as user_id,
(SELECT COUNT(a.id) FROM articles a
WHERE a.user_id = u.user_id) as user_total_articles_published,
(SELECT COUNT(r.id) FROM replies r
WHERE r.user_id = u.user_id) as user_total_replies_published,
(SELECT COUNT(v.id) FROM votes v
WHERE v.user_id = u.user_id) as user_total_votes_done
FROM users as u
ORDER BY u.total_points DESC
LIMIT 10

Categories