简体   繁体   中英

MySql query with left join and Inner Join on the result

I have two tables in MySql one is users second is users transactions, transactions are related to user by user.id = transaction.user_id not all users have transaction, there is no limit of transaction per user all transactions have added_date field

What I need is a query that will give me list of all users with joined data about their last added transaction (one last transaction), or null's if they dont have any transaction

So what I think is

getting all users left join transactions on user.id = transaction.user_id inner join to get max transaction.added_date grouped by id

something like:

SELECT u.id, 
       u.name, 
       t.added_date
  FROM `user` u 
                LEFT JOIN `transaction` t 
                          ON u.id = t.user_id
               INNER JOIN (
                           SELECT id, 
                                  MAX(added_date) AS addedDate
                             FROM `transaction`
                         GROUP BY id
                           )gt
                          ON t.id = gt.id AND t.added_date = gt.addedDate

but it's giving me not what I expected, it leftjoins the transactions to users but i still have many transactions for same user in the result set

what am I doing wrong?

edit:

I simplified them a little but that should be enough so:

the user

CREATE TABLE `user` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(256) NOT NULL,
`email` varchar(128) NOT NULL,
`role_id` mediumint(8) unsigned NOT NULL,
`phone` varchar(128) NOT NULL, 
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

the transaction

    CREATE TABLE `transaction` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `user_id` int(10) unsigned DEFAULT NULL,  
  `added_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, 
  PRIMARY KEY (`id`),
  KEY `fk_transaction_user1_idx` (`user_id`),
  CONSTRAINT `transaction_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`)     ON DELETE CASCADE ON UPDATE CASCADE
  ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

I need a list of all users with their last transaction data, if the don't have then nulls

Please try this

SELECT u.id, 
       u.name, 
       t.added_date 
  FROM `users` u 
       LEFT JOIN `transaction` t 
                 ON u.id = t.user_id AND t.added_date = (
                                         SELECT MAX( added_date ) 
                                           FROM `transaction` t 
                                          WHERE t.user_id = u.id
                                         )

Thy this

  SELECT user.name, MAX(transaction.added_date) 
    FROM user 
              LEFT JOIN transaction 
                         ON user.id = transaction.user_id
GROUP BY user.name;

Here is SQL Fiddle

Also, try to avoid subqueries in favor of JOIN s, because the subqueries usually not good on perfomance

UPD. SQL Fiddle, with sorting ASC by date and NULLs last , using COALESCE
UPD2. Another SQL Fiddle with count

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM