การรวมด้านซ้ายของ Oracle และตำแหน่งข้อผิดพลาด


10
CREATE TABLE "ATABLE1"
  (
    "COLUMN1" VARCHAR2(20 BYTE),
    "COLUMN2" VARCHAR2(20 BYTE)
  );

CREATE TABLE "ATABLE2"
  (
    "COLUMN1" VARCHAR2(20 BYTE),
    "COLUMN2" VARCHAR2(20 BYTE)
  );

Insert into ATABLE1 (COLUMN1,COLUMN2) values ('A','1');
Insert into ATABLE1 (COLUMN1,COLUMN2) values ('B','2');

Insert into ATABLE2 (COLUMN1,COLUMN2) values ('A',null);
Insert into ATABLE2 (COLUMN1,COLUMN2) values ('A','1');
Insert into ATABLE2 (COLUMN1,COLUMN2) values ('A','2');

select ATABLE1.column1, count(ATABLE2.column1) 
    from ATABLE1 Left OUTER JOIN ATABLE2 on ATABLE1.column1 = atable2.column1
    GROUP BY ATABLE1.column1;

Result

COLUMN1              COUNT(ATABLE2.COLUMN1) 
-------------------- ---------------------- 
A                    3                      
B                    0    

ทำงานได้ตามที่คาดไว้ สิ่งนี้คือฉันต้องการให้ทุกแถวจาก ATABLE1 แสดงและใช้ข้อ จำกัด บางอย่าง

select ATABLE1.column1, count(ATABLE2.column1) 
    from ATABLE1 Left OUTER JOIN ATABLE2 on ATABLE1.column1 = atable2.column1
    where atable2.column2 = '1'
    GROUP BY ATABLE1.column1;


COLUMN1              COUNT(ATABLE2.COLUMN1) 
-------------------- ---------------------- 
A                    1                      

เหตุใดคอลัมน์ทั้งหมดจาก ATABLE1 จึงไม่แสดงแม้ว่าจะมีการเข้าร่วมด้านซ้าย ฉันจะทำให้มันปรากฏได้อย่างไร

ขอบคุณมากในล่วงหน้า.


+1 โดยเฉพาะอย่างยิ่งสำหรับความพยายามในการตั้งค่าวัตถุทดสอบ
แจ็คบอกว่าลอง topanswers.xyz

"ทำไมคอลัมน์ทั้งหมดจาก ATABLE1 ไม่แสดงถึงแม้จะมีการเข้าร่วมซ้าย" - คุณหมายถึงว่า 'ทุกแถว' หรือเปล่า?
แจ็คบอกว่าลอง topanswers.xyz

@ JackDouglas ใช่ว่าจะสมเหตุสมผลมากกว่านี้
แอรอน

คำตอบ:


7

เมื่อคุณเพิ่มตัวกรอง WHERE ไปยังตารางตัวเลือก / ตัวนอกคุณจะเปลี่ยนแบบสอบถามเป็น INNER JOIN คุณต้องเพิ่มเงื่อนไขลงในการเข้าร่วมหรือตารางที่ได้รับหรือ CTE

select ATABLE1.column1, count(ATABLE2.column1) 
    from ATABLE1 Left OUTER JOIN ATABLE2
         on ATABLE1.column1 = atable2.column1 AND atable2.column2 = '1'
    GROUP BY ATABLE1.column1;

3

เหตุใดคอลัมน์ทั้งหมดจาก ATABLE1 จึงไม่แสดงแม้ว่าจะมีการเข้าร่วมด้านซ้าย ฉันจะทำให้มันปรากฏได้อย่างไร

นั่นเป็นเพราะคุณกำลังบอกข้อความค้นหาของคุณให้นำ ATABLE.column1 กลับมาเท่านั้น หากคุณใช้คำสั่ง gbn หรือแจ็คเพียงระบุ ATABLE1. * (หรือระบุชื่อแต่ละข้อ) ในคำสั่ง SELECT ของคุณ:

select ATABLE1.*, count(ATABLE2.column1) 
from ATABLE1 Left OUTER JOIN ATABLE2
     on ATABLE1.column1 = atable2.column1 AND atable2.column2 = '1'
GROUP BY ATABLE1.column1;

1
น่าสนใจฉันหวังว่า OP จะไม่สับสนว่าจะแสดงรายการคอลัมน์ทั้งหมดอย่างไร ในทางกลับกันนั่นคือสิ่งที่พวกเขาถาม +1
Leigh Riffel

2

อีกทางเลือกหนึ่งในการเพิ่มเงื่อนไขในการเข้าร่วมคือการทดสอบnullในตัวกรอง:

select ATABLE1.column1, count(ATABLE2.column1) 
    from ATABLE1 Left OUTER JOIN ATABLE2 on ATABLE1.column1 = atable2.column1
    where atable2.column2 is null or atable2.column2 = '1'
    GROUP BY ATABLE1.column1;

ฉันชอบตัวแปรนี้ แต่คุณอาจพิจารณาว่าอ่านได้น้อยกว่า:

select ATABLE1.column1, count(ATABLE2.column1) 
    from ATABLE1 Left OUTER JOIN ATABLE2 on ATABLE1.column1 = atable2.column1
    where decode(atable2.column2,'1',1,null,1,0)=1
    GROUP BY ATABLE1.column1;

เหตุผลเดียวในการทำเช่นนี้คือถ้าด้วยเหตุผลบางอย่างคุณไม่สามารถใส่เงื่อนไขในตัวกรองได้ (ซึ่งบางครั้งเป็นกรณีในแบบสอบถามที่ซับซ้อนมากขึ้น)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.