【问题标题】:Avoiding same table joins避免相同的表连接
【发布时间】:2018-10-24 23:17:16
【问题描述】:

我有一个表,其中包含主要组合名称、年龄、地址,基于我们必须从 DUMMY_TEST 表中找到 id 的组合。

对于 DUMMY_TEST 表中的那个 id,必须获取应该与 DUMMY_ID_VALUE 表映射的所有名称、年龄、地址组合才能获得 Valuee 列结果。

需要下面给出的预期结果而不加入同一个表DUMMY_TEST 两次,因为它有数百万条实时记录会产生性能问题。

任何人都可以帮助创建一个性能良好的查询,而无需两次使用同一个表。

--table creation
CREATE TABLE DUMMY(NAME VARCHAR2(100),AGE VARCHAR2(100),ADDRESS VARCHAR2(100), ID VARCHAR2(100));
--data loading
INSERT INTO DUMMY VALUES('SAM','30','ITALY','100');
INSERT INTO DUMMY VALUES('RAGHU','20','VENICE','300');
INSERT INTO DUMMY VALUES('TOM','40','JAPAN','200');

CREATE TABLE DUMMY_TEST(NAME VARCHAR2(100),AGE VARCHAR2(100),ADDRESS VARCHAR2(100), ID VARCHAR2(100));
INSERT INTO DUMMY_TEST VALUES('SAM','30','ITALY','100');
INSERT INTO DUMMY_TEST VALUES('TOM','40','JAPAN','200');
INSERT INTO DUMMY_TEST VALUES('BROSNAN','20','INDIA','100');
INSERT INTO DUMMY_TEST VALUES('ARJUN','30','AMERICA','200');
INSERT INTO DUMMY_TEST VALUES('SAMUEL','40','BERLIN','100');
INSERT INTO DUMMY_TEST VALUES('RAM','60','GERMANY','200');

--table creation
CREATE TABLE DUMMY_ID_VALUE(ID VARCHAR2(100),VALUEE VARCHAR2(100));
--data loading
INSERT INTO DUMMY_ID_VALUE VALUES(100,'INCLUDED');
INSERT INTO DUMMY_ID_VALUE VALUES(200,'exclueded');
INSERT INTO DUMMY_ID_VALUE VALUES(300,'PARTIAL');

查询

SELECT DT.NAME,DT.AGE,DT.ADDRESS,DT.ID,DUMMY_ID_VALUE.VALUEE 
FROM DUMMY 
  LEFT OUTER JOIN DUMMY_TEST A
  ON DUMMY.NAME = A.NAME AND DUMMY.AGE = A.AGE AND DUMMY.ADDRESS = A.ADDRESS 
  LEFT OUTER JOIN DUMMY_TEST DT
  ON DT.ID = A.ID
  INNER JOIN DUMMY_ID_VALUE
  ON DUMMY_ID_VALUE.ID = DT.ID;

实际结果

NAME   AGE ADDRESS ID  VALUEE
---------------------------------
SAM        30  ITALY   100 INCLUDED
BROSNAN    20  INDIA   100 INCLUDED
SAMUEL 40  BERLIN  100 INCLUDED

预期结果:

NAME   AGE ADDRESS ID  VALUEE
---------------------------------
SAM        30  ITALY   100 INCLUDED
BROSNAN    20  INDIA   100 INCLUDED
SAMUEL 40  BERLIN  100 INCLUDED
RAGHU  20  VENICE  300 PARTIAL

【问题讨论】:

  • 您的示例为我返回 6 行,您真的只有 3 行吗?
  • id 不是主键
  • 是的...它会给出 6 个结果..sry 我错过了它
  • 你的数据和预期的结果对我来说毫无意义,你的解释无助于理解你真正想要什么。你应该改写这个,并显示更好的数据
  • 我需要一种方法来避免两次加入同一张表

标签: sql oracle outer-join


【解决方案1】:

所以,这里有两个问题,一个(避免双重加入)很容易解决:

select A.NAME, A.AGE, A.ADDRESS, A.ID, DUMMY_ID_VALUE.VALUEE 
FROM DUMMY
    left OUTER JOIN DUMMY_TEST A ON (DUMMY.NAME = A.NAME AND DUMMY.AGE = A.AGE AND DUMMY.ADDRESS = A.ADDRESS) or (DUMMY.ID = A.ID)
    INNER JOIN DUMMY_ID_VALUE on DUMMY_ID_VALUE.ID = A.ID

但我不确定它是否会提高性能。
另一个是你得到的结果不符合你的期望,假设你在查询中输入的逻辑你的结果应该是 6 行。

【讨论】:

  • 我们的场景就像对于一个组合的(name,age,address) ID,我们必须从 DUMMY_TEST 表中找到另一个可能组合的(nae,age,address)ID。有了这些组合 ID,我们必须从 DUUMMY_ID_VALUE 表中获取 valuee 数据。
  • 一个组合 sam 30 italy 同时在 DUMMY_TEST 中检查相同的组合,我们将得到 SAM 30 ITALY 100 然后基于 ID 100 我们还有其他组合,例如 --SAM 30 ITALY 100 BROSNAN 20印度 100 SAMUEL 40 BERLIN 100 现在对于那些组合,我们必须根据 ID 检查价值 100 它包括 SAM 30 意大利 100 包括 BROSNAN 20 印度 100 包括 SAMUEL 40 BERLIN 100 包括
  • 对不起,我不明白你的逻辑,尝试重写你的查询以产生正确的结果,然后我们可以尽量避免双重连接
【解决方案2】:

您的查询很好,除了joins。我会去:

SELECT DT.NAME, DT.AGE, DT.ADDRESS, DT.ID, DUMMY_ID_VALUE.VALUEE 
FROM DUMMY LEFT OUTER JOIN
     DUMMY_TEST A
     ON DUMMY.NAME = A.NAME AND DUMMY.AGE = A.AGE AND DUMMY.ADDRESS = A.ADDRESS LEFT OUTER JOIN
     DUMMY_TEST DT
     ON DT.ID = A.ID LEFT JOIN
     DUMMY_ID_VALUE
     ON DUMMY_ID_VALUE.ID = DT.ID;

最终的连接必须是LEFT JOIN。为了性能,您的查询很好。 DUMMY_TEST(NAME, AGE, ADDRESS) 上的索引将有助于您的表现。

【讨论】:

    猜你喜欢
    • 2023-03-16
    • 2018-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-10
    • 2014-05-08
    • 1970-01-01
    • 2013-04-28
    相关资源
    最近更新 更多