2012-04-19 213 views
6

所以我认为我已经看到了这个解决方案,但他们都是非常复杂的查询。我在oracle 11g中供参考。如何限制此LEFT JOIN返回的行数为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是兴田的本质左连接

+3

为什么这个标记为MySQL? – 2012-04-19 20:35:31

+2

尽管发布了很多答案,但如果不解释为什么只需要1行,就不可能知道你需要什么。你真的想每个assignment_group有一个随机的用户吗?做什么的? – winkbrace 2012-04-19 21:16:12

回答

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 
+0

可以发布基于abover查询的示例SQL语句吗?我知道你可以做一个子查询只是不确定的语法。 – BostonMacOSX 2012-04-19 20:47:52

+3

不容易在手机上点击... – 2012-04-19 20:53:46

-3

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

+1

只适用于SQL Server – 2012-04-19 20:38:36

+0

然后使用限制1。没什么大不了。 – ZERO 2012-04-19 21:03:45

+3

Oracle也不支持'LIMIT'子句。 – 2012-04-19 23:44:36

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 
+0

这不会限制我从表1的1行吗?我只需要连接表2中的1行,但每个表1中的所有行。 – BostonMacOSX 2012-04-19 20:53:00

+0

@BostonMacOSX已编辑我的回答 – 2012-04-19 20:56:11

+1

您不能在内联视图中引用'T1.ASSIGNMENT',因为'T1'被定义为更高级别的查询。您可以添加一个分析函数,该函数按“T2.ASSIGNMENT_GROUP”进行分区,然后在联接条件中包含排名(下面的示例)。或者你可以将'T2'的查询移动到'SELECT'列表中的标量子查询中,尽管这样效率可能会低很多。 – 2012-04-19 21:00:03

0

在MySQL中,你可以只GROUP通过分配和完成。 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 

如果你这样做,我会认真地怀疑你需要摆在首位的JOIN。

MySQL也可以帮助GROUP_CONCAT在需要列值的字符串连接的情况下(人们通常喜欢这样),但使用的是Oracle的staggeringly complex

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

+0

这个问题是关于Oracle的,所以你可以在不同的数据库中做的所有事情都不重要 – Forage 2017-10-16 12:33:47

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) 

这通过assignment_group划分在table2的数据,然后随意排列他们每assignment_group拉一个任意行。如果您关心返回哪一行(或者如果您想使行返回确定性),则可以将ORDER BY子句添加到分析函数中。

+0

请问你可以添加(也许在它自己的行上注释掉)订单的条款 – 2017-04-10 08:23:37

+1

@RuneJeppesen - 增加了一个'按顺序排列。 – 2017-04-20 18:43:33