Sql SELECT DISTINCT返回的行数超出预期

Sql SELECT DISTINCT返回的行数超出预期,sql,greatest-n-per-group,Sql,Greatest N Per Group,我在这里读了很多答案,但到目前为止,没有什么能帮助我。我正在开发一个票证系统,每个票证都有很多更新 我有大约两张表:tbu-ticket和tbu-updates 我创建了一个带有子查询的SELECT,在那里花了很长时间(大约25秒)才得到大约1000行。现在我将它改为内部连接而不是子查询中的许多选择s,它非常快(70毫秒),但现在我得到了重复的票证。我想知道如何才能只获得最后一行(按时间排序) 我目前的结果是: ... 67355;69759;"COMPANY X";"2014-08-22 09

我在这里读了很多答案,但到目前为止,没有什么能帮助我。我正在开发一个票证系统,每个票证都有很多更新

我有大约两张表:
tbu-ticket
tbu-updates

我创建了一个带有子查询的SELECT,在那里花了很长时间(大约25秒)才得到大约1000行。现在我将它改为
内部连接
而不是子查询中的许多
选择
s,它非常快(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数据库。我没有分享我当前的查询,因为它只有葡萄牙语的名字,所以我认为它不会有任何帮助

解决方案:
您使用的\U已经为我的问题提供了最好的解决方案。

如果您的updateid是identity列,您可以尝试以下方法:

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

要获取最后一行,您必须使用
orderbytime desc
结束查询,然后在select语句中使用
TOP(1)
仅选择查询结果中的第一行

例:


如果没有表的详细信息,就必须猜测字段名,但tb_更新似乎在tb_票证中有多条记录(多对一关系)

您的问题的一个通用解决方案——仅获取“最新”记录——是在tb_更新上使用子查询(请参见下面的别名mx),然后将其连接回tb_更新,以便仅选择具有最新日期的记录

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不同,这足以使这两行
DISTINCT
这两个日期也有差异


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

使用\u ready的解决方案就可以了。我不确定性能,但另一个解决方案是使用交叉应用,尽管这仅限于少数几个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

如果您能给我们您的SQL语句来处理您的表,您的表的前缀是“tb_389;”,那将是非常棒的。出于兴趣,您的存储过程是否前缀为“sp_”?没有表结构和需要修复的SQL副本。。。我们真的无法帮助您。
DISTINCT
始终适用于返回的所有列-任何行都不应具有所有相同的值-这就是
DISTINCT
所做的-其他什么都没有。您好,这是一个postgresql,我没有SP。即使我提供的信息很差,您也可以完全解决我的问题。太不可思议了!非常感谢,它工作得非常好!这正是我要找的!不幸的是,你不明白的是,SO在这里不仅仅是为了解决你的问题,而是为了提出明确的问题和解决方案,这些问题和解决方案可能会在将来帮助像你(或我)这样的人。一个好的问题不会提供“糟糕的信息”。事实上,如果updatedTime值上有一个平局,它可以防止获得超过1条记录。但是,@Kiklion我可能会建议交叉应用前使用row_number(),因为它的可用性更广。
SELECT *
FROM tb_ticket ticket
CROSS APPLY (
    SELECT top(1) *
    FROM tb_updates details
    ORDER BY updateTime desc
    WHERE details.ticketID = ticket.ticketID
    ) updates