2017-02-22 51 views
0
在数据库中写上从每个用户(用户名)最近的日子(review_date)最近的日子

我想实现的注释(标题)选择一行

My code is : 

select tb1.*, tb2.* from 
(select username, via_mobile as pc, max(review_date) as pcdate from tripadvisor where username != "" and via_mobile='false' group by username) tb1 
join 
(select username, via_mobile as mobile, max(review_date) as mobile from tripadvisor whereusername != "" and via_mobile='true' group by username) tb2 
on tb1.username = tb2.username; 

的问题是我无法在正确的日期得到正确的评价。 例如:

username; review_date; title 
Alan; 2012-12-18 ;"If..." 

但它应该显示Alan; 2012-12-18; "Nice hotel"

你能不能帮我修复代码。

+0

参见http://meta.stackoverflow.com/questions/333952/why-should-i-provide-an-mcve-for-what -see-a-very-simple-sql-query – Strawberry

+0

'NiceHôtel'...荒谬的 – Strawberry

回答

1

你的问题有点不清楚,但如果我理解正确,你正在寻找具有最高日期的每个完整行,选择明确/用户名分组?这应该给你的是:

SELECT 
    username, 
    review_date, 
    title 
FROM 
    tripadvisor AS ta 
    INNER JOIN (
    SELECT 
     username, 
     max(review_date) AS review_date 
    FROM 
     tripadvisor 
    GROUP BY 
     username 
) AS max_table 
    ON ta.username = max_table.username 
     AND ta.review_date = max_table.review_date; 
WHERE 
    username != '' 
    -- any extra where clauses go here 

参见:How can I SELECT rows with MAX(Column value), DISTINCT by another column in SQL?

+1

如果有两行或多行具有相同的最近'review_date'给定''用户名',这个查询将为该用户名返回两行或多行。这可能是一个边缘案例。我们可能期望'(username,review_date)'是唯一的。但我们没有看到任何保证。此外,原始查询似乎将行限制为那些具有via_mobile ='true'或via_mobile ='false'的行,不包括例如具有via_mobile ='未知'的行。但是,除了这两个小问题外,该查询还说明了返回“最新行”的规范方法。+10 – spencer7593

+1

诚然,如果我说实话,我对电脑/手机的区别很不清楚,它看起来像是一种不正常的标准化;除非OP正在尝试获取移动设备的最近日期,以及同一行中PC的最近日期......我只是为OP的结果表编写了一个查询,但是您的答案更符合OP的写作方式查询。 +1 –

+1

是的,规范是不精确的;有几种方法可以解释它,在什么情况下应该返回哪些行。我的意见是要指出一些具体的边缘案例。我不打算批评这个答案中的查询。这个查询是一个很好的演示,并且比我的答案中的查询清晰得多。如果SO会让我的话,我会再加上+10。 – spencer7593

1

如果目标是返回最近的评论标题为“手机”和“PC”,我会做这样的事情:

SELECT q.username 
    , MAX(q.pc_date)  AS pc_date 
    , MAX(p.title)  AS pc_title 
    , MAX(q.mobile_date) AS mobile_date 
    , MAX(r.title)  AS mobile_title 
    FROM (SELECT t.username 
       , MAX(IF(t.via_mobile='false',t.review_date,NULL) AS pc_date 
       , MAX(IF(t.via_mobile='true',t.review_date,NULL) AS mobile_date 
      FROM tripadvisor t 
      WHERE t.username <> '' 
      AND t.via_mobile IN ('true','false') 
      GROUP 
      BY t.username 
     ) q 
    LEFT 
    JOIN tripadvisor p 
    ON p.username = q.username 
    AND p.review_date = q.pc_date 
    AND p.via_mobile = 'false' 
    LEFT 
    JOIN tripadvisor r 
    ON r.username = q.username 
    AND r.review_date = q.mobile_date 
    AND r.via_mobile = 'true' 
GROUP 
    BY q.username 

如果用户只有“移动”评论并且没有“pc”评论,该查询将返回一行,但“pc”列的值为NULL。同样,查询将为只有“pc”评论的用户返回“移动”列的NULL值。

可以很容易地将查询更改为仅返回具有“移动”和“pc”评价的用户的行,使其更接近使用INNER JOIN的原始行。


如果目标是简单的,只是仅返回最近的评价......

SELECT r.username 
    , r.review_date 
    , MAX(r.title)  AS title 
    , MAX(r.via_mobile) AS via_mobile 
    FROM (SELECT t.username 
       , MAX(t.review_date) AS max_review_date 
      FROM tripadvisor t 
      WHERE t.username <> '' 
      AND t.via_mobile IN ('true','false') 
      GROUP 
      BY t.username 
     ) q 
    JOIN tripadvisor r 
    ON r.username = q.username 
    AND r.review_date = q.max_review_date 
    AND r.via_mobile IN ('true','false') 
GROUP 
    BY r.username 
    , r.review_date 

此查询的结果有些不确定时username具有相同的(最近的多行)review_date。这保证将返回一行,但titlevia_mobile可能不在同一行。

0

您的问题可以表示为存在测试:显示检查日期与该用户的最新检查日期相匹配的行。

存在性与EXISTS测试在相关子查询:

SELECT * FROM tripadvisor as T 
where exists ( 
    select 1 from tripadvisor 
    where username = T.username 
    group by username 
    having MAX(review_date) = T.review_date 
);