2014-08-28 285 views
-4

我在这里阅读了很多答案,但直到现在没有任何东西可以帮助我。我正在开发一个门票系统,每张门票都有很多更新。SELECT DISTINCT返回比预期更多的行

我有大约2个表格:tb_tickettb_updates

我创建了一个SELECT子查询,它花了很长时间(大约25秒)获得大约1000行。现在我将其更改为INNER JOIN而不是子查询中的许多SELECT,它非常快(70毫秒),但是现在我获得了重复票据。我想知道如何才能得到最后一行(按时间排序)。

我现在的结果是:

... 
67355;69759;"COMPANY X";"2014-08-22 09:40:21";"OPEN";"John";1 
67355;69771;"COMPANY X";"2014-08-26 10:40:21";"UPDATE";"John";1 

的第一列是票ID,二是更新ID ...我想只能得到每票ID一排,但在这种情况下,DISTINCT不起作用。哪一行应该是?总是最新的,所以在这种情况下,2014-08-26 10:40:21

更新: 这是一个postgresql数据库。我没有分享我目前的查询,因为它只有葡萄牙语的名字,所以我认为它根本没有帮助。

SOLUTION: Used_By_Already了我的问题的最佳解决方案。

+3

什么是DBMS? – Dimt 2014-08-28 12:29:58

+3

如果您可以给我们您的SQL语句与 – Marco 2014-08-28 12:31:05

+0

一起使用,那么会很有光泽您的表的前缀为'tb_'。出于兴趣,您的存储过程是否为前缀'sp_'? – 2014-08-28 12:31:11

回答

3

没有你的表的详细内容的有猜字段名,但似乎tb_updates在tb_ticket(多对一关系)中有多条记录。

问题的一般解决方案 - 只获取“最新”记录 - 是在tb_updates上使用子查询(请参见下面的别名mx),然后将它加回到tb_updates,以便只有具有最新日期的记录被选中。

SELECT 
     t.* 
    , u.* 
FROM tb_ticket t 
     INNER JOIN tb_updates u 
        ON t.ticket_id = u.ticket_id 
     INNER JOIN (
        SELECT 
         ticket_id 
         , MAX(updated_at) max_updated 
        FROM tb_updates 
        GROUP BY 
         ticket_id 
      ) mx 
        ON u.ticket_id = mx.ticket_id 
         AND u.updated_at = mx.max_updated 
; 

如果您有支持ROW_NUMBER一个DBMS(),然后使用该函数可以是一个非常有效的替代方法,但是你有没有告知我们您正在使用的DBMS。


的方式: 这些行是不同的:

67355;69759;"COMPANY X";"2014-08-22 09:40:21";"OPEN";"John";1 
67355;69771;"COMPANY X";"2014-08-26 10:40:21";"UPDATE";"John";1 

69759是69771不同,这是足够的2行是DISTINCT 中有2个日期也差。

distinct是一个row operator这意味着在决定哪些行是唯一的时候,会考虑整行,而不仅仅是第一列。

+0

即使我提供的信息很差,也可以完全解决我的问题。不可思议!非常感谢,它非常完美!那就是我正在寻找的! – 2014-08-28 13:26:40

+0

不幸的是,你不明白的地方在于,它不仅仅是为了解决你的问题,而是要提出明确的问题和解决方案,以帮助像你(或我)这样的其他人在未来。一个好问题不会提供“不良信息”。 – Frazz 2014-08-28 15:07:41

0

U可以尝试像下面如果你updateid是标识列:

Select ticketed, max(updateid) from table 
group by ticketed 
0

为了得到你要结束你的查询与order by time desc然后使用TOP (1)在select语句选择仅在第一行的最后一行查询结果

例如:

select TOP (1) ..... 
     from ..... 
     where ..... 
     order by time desc 
1

Used_By_Already的解决方案将工作得很好。我不确定性能,但另一种解决方案是使用交叉应用,但仅限于少数几个DBMS。

SELECT * 
FROM tb_ticket ticket 
CROSS APPLY (
    SELECT top(1) * 
    FROM tb_updates details 
    ORDER BY updateTime desc 
    WHERE details.ticketID = ticket.ticketID 
    ) updates 
+0

事实上,如果updatedTime值有一条平行线,它可以防止获得超过1条记录。但是,@ Kiklion我可能会建议row_number()交叉应用之前,因为它是更广泛的可用。 – 2014-08-29 00:50:39

相关问题