简体   繁体   English

带有左联接和内部联接的MySQL查询

[英]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 我在MySql中有两个表,一个是用户,第二个是用户事务,事务通过user.id = transaction.user_id与用户相关。并非所有用户都有事务,每个用户没有事务限制,所有事务都有add_date字段

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 我需要的是一个查询,该查询将向我提供所有用户的列表,这些用户具有有关其最后添加的事务(最后一个事务)的合并数据,如果没有任何事务,则为null

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 让所有用户离开,并在user.id = transaction.user_id内部联接上加入事务,以获取最大的transaction.added_date按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 我需要所有用户的列表及其最近的交易数据,如果没有,则为null

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 这是SQL小提琴

Also, try to avoid subqueries in favor of JOIN s, because the subqueries usually not good on perfomance 另外,请尽量避免使用JOIN 子查询因为子查询通常在性能方面不佳

UPD. UPD。 SQL Fiddle, with sorting ASC by date and NULLs last , using COALESCE SQL Fiddle,使用日期和空值对ASC进行排序,最后使用COALESCE
UPD2. UPD2。 Another SQL Fiddle with count 另一个带有计数的SQL提琴

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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