SQL:一对多,只选一个

时间:2010-08-19 20:19:02

标签: sql mysql greatest-n-per-group

我正在编写一个小工具来管理注册协会的人员。

我有一张表USERS和一张表CARDS。每个用户可以拥有多张卡(因为卡过期)。

通过一个查询,我想提取所有用户信息以及仅针对最新卡的所有卡信息(字段:ISSUEDATE)。

这是一个非常基本的例子:

USERS表

IDUSER  NAME    SURNAME
------------------------
1       Robert  Hill

CARDS表

IDCARD  IDOWNER  ISSUEDATE   DESC 
----------------------------------------
1       1        2010-01-01  'CARD ONE'
2       1        2010-08-18  'CARD TWO'

基本上我想从我的查询中找回这些字段:

IDUSER  NAME     SURNAME  IDCARD  IDOWNER  ISSUEDATE   DESC
---------------------------------------------------------------
1       Robert   Hill     2       1        2010-08-18  'CARD TWO'

我试过,但我无法管理:(

编辑: 如果没有CARD链接到用户会发生什么? (一个用户已注册但该协会尚未给他/她任何卡)。有没有办法调整此查询以获取用户信息?我们的想法是为每个用户获取所有可能的信息。稍后通过JSON在广告ExtJS应用程序中使用此信息。

感谢您的回答。

3 个答案:

答案 0 :(得分:1)

带有NOT EXISTS查询的选项1:

select u.IDUSER, u.NAME, u.SURNAME,
       c.IDCARD, c.IDOWNER, c.ISSUEDATE, c.DESC
from USERS u
join CARDS c on u.IDUSER = c.IDOWNER
where not exists (select 1 from CARDS where IDOWDER = u.IDUSER and ISSUEDATE > c.ISSUEDATE)

选项2与LIMIT

select u.IDUSER, u.NAME, u.SURNAME,
       c.IDCARD, c.IDOWNER, c.ISSUEDATE, c.DESC
from USERS u
join CARDS c on u.IDUSER = c.IDOWNER
order by c.ISSUEDATE desc
LIMIT 1

答案 1 :(得分:1)

select u.IDUSER, u.NAME, u.SURNAME,
       c.IDCARD, c.IDOWNER, c.ISSUEDATE, c.DESC
from USERS u
join CARDS c on u.IDUSER = c.IDOWNER and c.IDCARD in (
     /* select biggest IDCARD numbers that has same IDOWNER thus eliminating multiple rows and remaining only 1 for each IDOWNER */
     select MAX(IDCARD) as IDCARD
     from USERS join CARDS on USERS.IDUSER = CARDS.IDOWNER
     group by CARDS.IDOWNER

)

答案 2 :(得分:1)

Altho LIMIT通常不包含在mysql子查询中,LIMIT 1是一个例外,所以 “只选一个”对于这种情况是完美的。

LEFT JOIN确保您的用户没有卡数据(卡数据为NULL,您可以使用ifnull(desc, 'No Card Issued')随意显示

和子查询确保仅选择用户的最新卡数据。

SELECT * 
  FROM users u 
       LEFT JOIN cards c 
         ON c.idcard = (SELECT idcard 
                          FROM cards c1 
                         WHERE c1.idowner = u.iduser 
                         ORDER BY issuedate DESC 
                         LIMIT 1)