2009-07-29 57 views
3
SELECT (b.descr || ' - ' || c.descr) description 
    FROM tbl1 a LEFT JOIN tbl2 b ON a.ACCOUNT = b.ACCOUNT 
     LEFT JOIN tbl3 c ON a.product = c.product 
WHERE a.descr50 = ' ' ; 

table1只有7622行descr50 ='',但此选择返回7649行。你能帮我解决吗?在此先感谢获取额外的行 - 使用左连接连接3个表后

+0

得到的回答在 http://stackoverflow.com/questions/1198183/update-a-table-using-the-fields-of-the-other-two-table-please-help-me-in-this/1198197#1198197 – 2009-07-29 12:03:16

+1

你在用什么'RDBMS'? – Quassnoi 2009-07-29 13:00:34

+0

Prem,看起来你有*四个问题,包括这个问题,*你遇到的问题*。 (1):http://stackoverflow.com/questions/1204701/update-table-with-a-subquery-which-is-returning-more-than-one-row (2):http:// stackoverflow.com/questions/1199733/getting-extra-rows-after-joing-the-3-tables-using-left-join (3):http://stackoverflow.com/questions/1198183/update-a-这张桌子使用这个其他两个字段的表格请帮助我在这 (4):http://stackoverflow.com/questions/1204563/updating-row-with-子查询返回多行 – Liao 2009-07-30 08:06:49

回答

3

table1可能只有7622行,但如果tbl2具有多个具有相同ACCOUNT值的行,或者如果tbl3具有多个产品匹配的行,那么结果中会有更多行组。你有效地“乘”每个表。


编辑:OK,一个例子。

假设tbl1只有一行,并且“ACCOUNT”是1,“product”是2(我不知道表中有什么实际值,这并不重要)。

现在假设tbl2有2行,其中“ACCOUNT”为1.直接,您将在结果中至少获得2行,因为tbl1将匹配tbl2中的2行。现在

如果TBL3有2行,其中的“产品”为2,你会得到的结果行,因为各2个结果的上方将TBL3匹配2行。

所以希望你能看到为什么你得到的数据比你想象的要多。你选择做什么是另一回事,取决于tbl2和tbl3中是否有多个匹配的事实表明数据有问题。

+0

嗨麦吉尔,谢谢你的回答。我已通过创建示例表检查相同的查询,它工作正常。我将输出与实际表格进行了比较,发现27是额外的。我不知道如何。请帮助我。 – Prem 2009-07-29 12:01:19

+0

准确地+1我的答案,但你打我:) – 2009-07-29 12:02:28

+0

@Prem - 大概你的样品表没有相同的数据!如果每个tbl2和tbl3中只有一个匹配行,则查询*将会“工作正常”。 – 2009-07-29 12:11:30

4

当您将两个或多个表合并在一起时,您可以有效地为这些表应用JOIN条件中指定的过滤器的笛卡尔积。

当您使用过时的隐式JOIN语法时,这更为明显。

LEFT JOIN保证你得到没有行比最左边的表包含,即最左边的表中的每行至少返回一次。

如果筛选器不是一对一行映射,则仍然可以获取更多行。

你的情况:

SELECT (b.descr || ' - ' || c.descr) description 
FROM tbl1 a 
LEFT JOIN 
     tbl2 b 
ON  b.ACCOUNT = a.ACCOUNT 
LEFT JOIN 
     tbl3 c 
ON  c.product = a.product 
WHERE a.descr50 = ' ' 

要么acccountproduct不是bc独特。

对于这些行:

a.account 

1 
2 
3 

b.account b.description 

1   Account 1 
2   Account 2 - old 
2   Account 2 - new 

,该JOIN将返回以下:

a.account b.account b.description 

1   1   Account 1 
2   2   Account 2 - old 
2   2   Account 2 - new 
3   NULL  NULL 

,为您提供比任一表中包含多行。

只选择从任一表中的第一匹配的描述中,使用这样的:

SELECT (
     SELECT FIRST_VALUE(descr) OVER (ORDER BY descr) 
     FROM tbl2 b 
     WHERE b.account = a.account 
       AND rownum = 1 
     ) || ' - ' || 
     (
     SELECT FIRST_VALUE(descr) OVER (ORDER BY descr) 
     FROM tbl3 c 
     WHERE c.product= a.product 
       AND rownum = 1 
     ) description 
FROM tbl1 a 
WHERE a.descr50 = ' ' 

要进行更新,只是包裹查询分成内联视图:

UPDATE (
     SELECT (
       SELECT FIRST_VALUE(descr) OVER (ORDER BY descr) 
       FROM tbl2 b 
       WHERE b.account = a.account 
         AND rownum = 1 
       ) || ' - ' || 
       (
       SELECT FIRST_VALUE(descr) OVER (ORDER BY descr) 
       FROM tbl3 c 
       WHERE c.product= a.product 
         AND rownum = 1 
       ) description 
     FROM tbl1 a 
     WHERE a.descr50 = ' ' 
     ) 
SET  descr50 = description 
+0

感谢您的解释。我的requiremetn是通过从table2和table3中协调描述来填充名为description的table1字段。但1和2之间的通用领域是账户,1和3是产品。你能帮我解决吗? – Prem 2009-07-29 12:41:59

+0

我不能直接更新,我必须检查它,然后只有我可以更新。这是我使用select来获取值,但它更多的是table1中的值。但只有27. – Prem 2009-07-29 12:46:10

+0

@Prem:我更新了样本数据的帖子。鉴于'b'包含多个帐户'2'的描述,您希望帐户'2'具有哪个描述? – Quassnoi 2009-07-29 12:51:10

1

作为测试,以确定额外的行来自于,请尝试从连接的表中向您的SELECT语句添加更多字段并查看返回的数据。要解决此问题

一种选择是将你的连接表加入他们后:

SELECT (b.descr || ' - ' || c.descr) description 
    FROM tbl1 a 
    LEFT JOIN tbl2 b ON a.ACCOUNT = b.ACCOUNT 
    LEFT JOIN tbl3 c ON a.product = c.product 
    WHERE a.descr50 = ' ' 
    GROUP BY b.descr, c.descr 

另一种选择是将入组之前你TBL2和TBL3表:

SELECT (b.descr || ' - ' || c.descr) description 
    FROM tbl1 a 
    LEFT JOIN 
    (
     SELECT descr, ACCOUNT 
      FROM tbl2 
      GROUP BY descr, ACCOUNT 
    ) AS b 
     ON a.ACCOUNT = b.ACCOUNT 
    LEFT JOIN 
    (
     SELECT descr, product 
      FROM tbl3 
      GROUP BY descr, product 
    ) AS c 
     ON a.product = c.product 
    WHERE a.descr50 = ' ' 
+0

感谢您的解释。我的requiremetn是通过从table2和table3中协调描述来填充名为description的table1字段。但1和2之间的通用领域是账户,1和3是产品。你能帮我解决吗? – Prem 2009-07-29 12:44:44

+0

我不能直接更新,我必须检查它,然后只有我可以更新。这是我使用select来获取值,但它更多的是table1中的值。但只有27 – Prem 2009-07-29 12:46:46

+0

我发布的查询仍然返回27多行?如果是这样的话,那么对于给定的ACCOUNT,在tbl2中有多个descr的值,或者在给定的产品中有多个tbl3的值。你想如何处理?你需要选择一个值使用还是随机选择好吗? – 2009-07-29 14:08:22