如何将此LEFT JOIN返回的行数限制为一个?

时间:2012-04-19 20:29:06

标签: sql oracle join limit

所以我认为我已经看到了解决方案,但它们都是非常复杂的查询。我在oracle 11g中作为参考。

我所拥有的是一个简单的一对多联接,但是我不需要那么多。我只是希望左表(一个)只加入满足连接条件的任何1行...不是很多行。

我需要这样做,因为查询是汇总的,因此如果我执行正常的左连接,我会得到5行,我应该只得到1。

所以示例数据如下:

TABLE 1:
-------------
TICKET_ID      ASSIGNMENT
5              team1
6              team2

TABLE 2:
-------------
MANAGER_NAME   ASSIGNMENT_GROUP  USER
joe            team1             sally
joe            team1             stephen
joe            team1             louis
harry          team2             ted
harry          team2             thelma

我需要做的是在ASSIGNMENT = ASSIGNMENT_GROUP上加入这两个表,但只返回1行。

当我进行左连接时,我得到三行返回beaucse,这是hte left join的性质

6 个答案:

答案 0 :(得分:7)

如果oracle支持行号(分区依据),您可以创建一个子查询,选择行等于1的位置。

SELECT * FROM table1
LEFT JOIN
(SELECT *
FROM   (SELECT *,
           ROW_NUMBER()
             OVER(PARTITION BY assignmentgroup ORDER BY assignmentgroup) AS Seq
    FROM  table2) a
WHERE  Seq = 1) v
ON assignmet = v.assignmentgroup

答案 1 :(得分:5)

你可以这样做。

SELECT t1.ticket_id, 
       t1.assignment,
       t2.manager_name,
       t2.user
  FROM table1 t1
       LEFT OUTER JOIN (SELECT manager_name,
                               assignment_group,
                               user,
                               row_number() over (partition by assignment_group
                                                    --order by <<something>>
                                                 ) rnk
                          FROM table2) t2
                     ON (    t1.assignment = t2.assignment_group
                         AND t2.rnk = 1 )

这会将table2中的数据按assignment_group分区,然后对它们进行任意排名,以便每assignment_group个任意一行。如果您关心返回哪一行(或者如果您想使行返回确定性),则可以向分析函数添加ORDER BY子句。

答案 2 :(得分:1)

我认为您需要在GROUP BY字段上使用ASSIGNMENT_GROUP

http://www.w3schools.com/sql/sql_groupby.asp

答案 3 :(得分:1)

在Oracle中,如果您想要1个结果,可以使用ROWNUM语句获取查询的前N个值,例如:

SELECT *
FROM TABLEX
WHERE
ROWNUM = 1 --gets the first value of the result

此单个查询的问题是Oracle从不以相同的顺序返回数据。因此,您必须在使用rownum之前输入数据:

SELECT *
FROM
    (SELECT * FROM TABLEX ORDER BY COL1)
WHERE
ROWNUM = 1

对于您的情况,看起来您只需要1个结果,因此您的查询应如下所示:

SELECT *
FROM
    TABLE1 T1
    LEFT JOIN 
    (SELECT *
    FROM TABLE2 T2 WHERE T1.ASSIGNMENT = T2.ASSIGNMENT_GROUP
    AND
    ROWNUM = 1) T3 ON T1.ASSIGNMENT = T3.ASSIGNMENT_GROUP

答案 4 :(得分:1)

在MySQL中你可以只使用GROUP BY ASSIGNMENT来完成。 Oracle更严格,并且拒绝(以未定义的方式)选择要选择的三行中的哪些值。这意味着所有返回的列都需要成为GROUP BY的一部分或受到聚合函数(COUNT,MIN,MAX ...)的约束

您当然可以选择不关心并在返回的列上使用某些聚合函数。

select TICKET_ID, ASSIGNMENT, MAX(MANAGER_NAME), MAX(USER)
from T1
left join T2 on T1.ASSIGNMENT=T2.ASSIGNMENT_GROUP
group by TICKET_ID, ASSIGNMENT

如果你这样做,我会严重怀疑你首先需要加入。

如果你想要一个列的字符串串联(人们经常这样),MySQL也可以帮助GROUP_CONCAT,但是使用staggeringly complex的Oracle。

使用已建议的子查询是一个选项,look here作为示例。它还允许您在选择顶行之前对子查询进行排序。

答案 5 :(得分:-3)

你可以使用子查询 - 选择前1