Get most recent MySQL transaction only - mysql

I'm trying to export a set of user information from one WordPress database to import into another database. However I'm having trouble figuring out how to only export the most recent membership transaction for a user. The following query exports all transactions for each user, but I only want the transaction with the most recent "t.expires_at" value. I've tried various sub-queries etc based on other StackOverflow threads but can't quite figure it out.
SELECT DISTINCT
u.user_login AS user_login,
u.user_email AS user_email,
u.user_registered AS user_registered,
f.meta_value AS first_name,
l.meta_value AS last_name,
t.expires_at AS membership_enddate
FROM
wp_acfzia_users AS u
LEFT JOIN
wp_acfzia_usermeta AS f
ON u.ID = f.user_id AND f.meta_key = 'first_name'
LEFT JOIN
wp_acfzia_usermeta AS l
ON u.ID = l.user_id AND l.meta_key = 'last_name'
LEFT JOIN
wp_acfzia_mepr_transactions AS t
ON u.ID = t.user_id

Try this approach
SELECT DISTINCT
u.user_login AS user_login,
u.user_email AS user_email,
u.user_registered AS user_registered,
f.meta_value AS first_name,
l.meta_value AS last_name,
t.expires_at AS membership_enddate
FROM
wp_acfzia_users AS u
LEFT JOIN
wp_acfzia_usermeta AS f
ON u.ID = f.user_id AND f.meta_key = 'first_name'
LEFT JOIN
wp_acfzia_usermeta AS l
ON u.ID = l.user_id AND l.meta_key = 'last_name'
LEFT JOIN
wp_acfzia_mepr_transactions AS t
ON u.ID = t.user_id
WHERE exists (
select 1 from tbl where tbl.user_id = t.user_id
having max(tbl.expires_at) = t.expires_at
)
or MySQL 8+
select * from (
SELECT DISTINCT
u.user_login AS user_login,
u.user_email AS user_email,
u.user_registered AS user_registered,
f.meta_value AS first_name,
l.meta_value AS last_name,
t.expires_at AS membership_enddate,
row_number() over (order by t.expires_at partition by user_id) rn
FROM
wp_acfzia_users AS u
LEFT JOIN
wp_acfzia_usermeta AS f
ON u.ID = f.user_id AND f.meta_key = 'first_name'
LEFT JOIN
wp_acfzia_usermeta AS l
ON u.ID = l.user_id AND l.meta_key = 'last_name'
LEFT JOIN
wp_acfzia_mepr_transactions AS t
ON u.ID = t.user_id
)
Where rn = 1

Related

Select multipl query and every query got 2 JOIN

I want combine multiple query become 1:
SELECT b.fname FROM almanak as a
JOIN users as b on (b.userid = a.staf1)
SELECT c.fname FROM almanak as a
JOIN users as c on (c.userid = a.staf2)
SELECT d.fname FROM almanak as a
JOIN users as d on (d.userid = a.staf3)
SELECT e.fname FROM almanak as a
JOIN users as e on (e.userid = a.staf4)
SELECT f.fname FROM almanak as a
JOIN users as f on (f.userid = a.staf5)
i want make every field userid will select fname field at another table
Here is one way to do it:
SELECT
b.fname fname1,
c.fname fname2,
d.fname fname3,
e.fname fname4,
f.fname fname5
FROM almanak as a
INNER JOIN users as b ON b.userid = a.staf1
INNER JOIN users as c ON c.userid = a.staf2
INNER JOIN users as d ON d.userid = a.staf3
INNER JOIN users as e ON e.userid = a.staf4
INNER JOIN users as f ON f.userid = a.staf5
If there might be missing relations, you can turn the INNER JOINs to LEFT JOINs.
Alternatively, you can do conditional aggregation. Assuming that the primary key of the almanak table is id, that would look like:
SELECT
MAX(CASE WHEN u.userid = a.staf1 THEN u.fname END) fname1,
MAX(CASE WHEN u.userid = a.staf2 THEN u.fname END) fname2,
MAX(CASE WHEN u.userid = a.staf3 THEN u.fname END) fname3,
MAX(CASE WHEN u.userid = a.staf4 THEN u.fname END) fname4,
MAX(CASE WHEN u.userid = a.staf5 THEN u.fname END) fname5
FROM almanak as a
INNER JOIN users as u
ON u.userid IN (a.staf1, a.staf2, a.staf3, a.staf4, a.staf5)
GROUP BY a.id

SQL - How to Query from 3 tables (query in query?)?

I want to know how to complete this query correctly.
I wish to export a full list of votes from all ips used by an user.
My database have 3 tables storing the relatives data =>
votes = vote_site_id | vote_ip | vote_time
connexions_ip = adresse_ip | user_id | connexion_time
users = user_id | user_name | user_ip
So actually I have this query to have all connexions_ip from one user =>
SELECT c.adresse_ip, c.user_id, u.user_name
FROM connexions_ip c
LEFT JOIN users u ON u.user_id = c.user_id
WHERE u.user_id = '1'
And this query to have all votes from one user =>
SELECT v.vote_site_id, v.vote_ip, v.vote_time, u.user_name
FROM votes v
LEFT JOIN users u ON u.user_ip = v.vote_ip
WHERE user_id = '1'
I tried with subquery but I have this error "#1242 - Subquery returns more than 1 row"
SELECT v.vote_site_id, v.vote_ip, v.vote_time, u.user_name
FROM votes v
LEFT JOIN users u ON (
SELECT c.adresse_ip
FROM connexions_ip c
LEFT JOIN users u ON u.user_id = c.user_id
WHERE u.user_id = '1'
)
= v.vote_ip
WHERE user_id = '1'
Thanks for your help.
You can join all the table
SELECT c.adresse_ip, c.user_id, u.user_name
, v.vote_site_id, v.vote_ip, v.vote_time
FROM users u
LEFT JOIN connexions_ip c ON u.user_id = c.user_id
LEFT JOIN votes v ON u.user_ip = v.vote_ip
WHERE u.user_id = '1'
I choosed the table users as the base for FROM because is the only table with a condition.
try this:
select a.*,b.* from (SELECT c.adresse_ip, c.user_id, u.user_name
FROM connexions_ip c
LEFT JOIN users u ON u.user_id = c.user_id
WHERE u.user_id = '1')a left join (SELECT u.user_id,v.vote_site_id, v.vote_ip, v.vote_time, u.user_name
FROM votes v
LEFT JOIN users u ON u.user_ip = v.vote_ip
WHERE user_id = '1')b on a.user_id = b.user_id

How to use part of sql query in the same query?

I have this query to get information from two tables:
SELECT u.username, u.id,
SUM(t.result = 1) AS winnings,
SUM(t.result = 2) AS loses
FROM users u
LEFT JOIN tahminler t ON u.id = t.user_id
GROUP BY u.id
I want to get comments_no for each user from another table; something like this:
SELECT u.username, u.id,
SUM(t.result = 1) AS winnings,
SUM(t.result = 2) AS loses,
f1.comments_no
FROM users u
LEFT JOIN tahminler t ON u.id = t.user_id
INNER JOIN (select count(distinct match_static_id) as comments_no,user_id from comments where user_id = "here is my problem")
GROUP BY u.id
Is it possible to but the value of u.id in the where user_id = u.id.
Briefly How to get the comments_no for each user in my query.?
Use a GROUP BY in the sub query:-
SELECT u.username, u.id,
SUM(t.result = 1) AS winnings,
SUM(t.result = 2) AS loses,
f1.comments_no
FROM users u
LEFT JOIN tahminler t ON u.id = t.user_id
INNER JOIN (select user_id, count(distinct match_static_id) as comments_no from comments GROUP BY user_id) f1
ON u.id = f1.user_id
GROUP BY u.id

MySQL select where no matches in join

How would I do following in MySQL:
I have 3 tables:
user: id
communication: id, creation_date
user_communication: user_id, communication_id
Now I want to select all users that have had no communication since a given date.
Following is what I have now, but I'm stuck on how to get what I described above.
SELECT DISTINCT u.id FROM user u
LEFT JOIN user_communication uc ON uc.user_id = u.id
LEFT JOIN communication c ON c.id = uc.communication_id
WHERE c.creation_date < '2013-8-1';
The where condition is undoing the left join. The initial solution would be to move it to the on clause:
SELECT DISTINCT u.id FROM user u
LEFT JOIN user_communication uc ON uc.user_id = u.id
LEFT JOIN communication c ON c.id = uc.communication_id and c.creation_date < '2013-8-1';
But this doesn't do what you want. This retrieves all records. If you had a creation date field in the select clause, it would be NULL when there is record before that date.
For no communication since that date, you can do a "double" negative" query. Look for records that are since that date, and return the mismatches:
SELECT DISTINCT u.id
FROM user u LEFT JOIN
user_communication uc
ON uc.user_id = u.id LEFT JOIN
communication c
ON c.id = uc.communication_id and c.creation_date >= '2013-08-01'
WHERE c.creation_date is NULL;
EDIT:
I see. The problem is a little more subtle than my answer above. Each user has multiple communications, so none can be later. The following query tests this by grouping by u.id and then checking that there are no non-NULL values from the above join:
SELECT u.id
FROM user u LEFT JOIN
user_communication uc
ON uc.user_id = u.id LEFT JOIN
communication c
ON c.id = uc.communication_id and c.creation_date >= '2012-08-01'
group by u.id
having min(c.creation_date is null) = 1;
SELECT DISTINCT u.id FROM user u
LEFT JOIN user_communication uc ON uc.user_id = u.id
LEFT JOIN (SELECT * FROM communication WHERE creation_date < '2013-8-1') c
ON c.id = uc.communication_id
WHERE c.id is NULL;
After some research and help I have following query, which seems to work:
SELECT DISTINCT(u.id)
FROM user u
WHERE (SELECT coalesce(max(c.creation_date), '1900-01-01 00:00:00') last_creation_date
FROM user inneru
LEFT JOIN user_communication uc ON uc.user_id = inneru.id
LEFT JOIN communication c ON c.id = uc.communication_id
WHERE inneru.id = u.id) < '2012-08-01'
SQLFiddle: http://sqlfiddle.com/#!2/5dfad/10

msql wrong total and sum on result

We have three different following tables...
users
id,
username
password
email
user_clubs
id,
user_id,
club_name
sales
id,
club_id,
amount,
admin_fees,
dnt
And we want to get total sum of admin_fees as outstanding for user_id(for example 55), so we tried following...
SELECT u.id, count(c.id), SUM(s.admin_fees) as total_admin_fees
FROM users u
LEFT JOIN user_clubs c ON c.user_id = u.id
LEFT JOIN sales s ON s.club_id = c.id
WHERE u.id = 55
GROUP BY u.id;
But its returning value of first row, so balance is not correct, Please help to resolve.
Try this:
SELECT g.id, count(g.club_id), SUM(g.admin_fees) AS total_admin_fees
FROM (
SELECT u.id, c.id AS club_id, s.admin_fees
FROM users u
LEFT JOIN user_clubs c ON c.user_id = u.id
LEFT JOIN sales s ON s.club_id = c.id
WHERE u.id = 55
) AS g
GROUP BY g.id;