【问题标题】:LEFT JOIN with two tablesLEFT JOIN 与两个表
【发布时间】:2018-09-19 09:38:45
【问题描述】:

我有 3 个表,并想根据他们的地区从“销售”中选择所有带有客户 ID 的记录。

create table t_sales (
   id                   SERIAL               not null,
   parent               INT4                 null,
   client1              TEXT                 null,
   client2              TEXT                 null,
   constraint PK_T_SALES primary key (id)
);
create table t_client (
   id                   SERIAL               not null,
   name                 TEXT                 null,
   district             INT4                 null,
   constraint PK_T_CLIENT primary key (id)
);
create table t_sale_district (
   id                   SERIAL               not null,
   sale_id              INT4                 null,
   district_id          INT4                 null,
   constraint PK_T_SALE_DISTRICT primary key (id)
);
INSERT INTO t_client (id,name,district) VALUES(1,'JOHN',1);
INSERT INTO t_client (id,name,district) VALUES(2,'JOHN',2);
INSERT INTO t_client (id,name,district) VALUES(3,'john',1);
INSERT INTO t_client (id,name,district) VALUES(4,'john',2);
INSERT INTO t_client (id,name,district) VALUES(5,'MAX',1);
INSERT INTO t_client (id,name,district) VALUES(6,'MAX',2);
INSERT INTO t_client (id,name,district) VALUES(7,'max',1);
INSERT INTO t_client (id,name,district) VALUES(8,'max',2);

INSERT INTO t_sales (id,parent,client1,client2) VALUES (1,1,'JOHN','john');
INSERT INTO t_sales (id,parent,client1,client2) VALUES (2,1,'JOHN','MAX');

INSERT INTO t_sale_district (id,sale_id,district_id) VALUES (1,1,1);
INSERT INTO t_sale_district (id,sale_id,district_id) VALUES(2,1,5);

INSERT INTO t_sales (id,parent,client1,client2) VALUES (3,1,'JOHN',NULL);
INSERT INTO t_sale_district (id,sale_id,district_id) VALUES (3,2,2);

这个查询选择我想要的但没有空值:

SELECT s.id,s.client1 as c1,c1.district as d1,s.client2 as c2,c2.district as d2
FROM public.t_sales s
    JOIN t_client c1 ON c1.name=s.client1 
    JOIN t_client c2 ON c2.name=s.client2
    JOIN t_sale_district sd1 ON sd1.district_id = c1.district 
    JOIN t_sale_district sd2 ON sd2.district_id = c2.district 
    WHERE sd1.sale_id=s.id AND sd2.sale_id=s.id

1;"JOHN";1;"john";1
2;"JOHN";2;"MAX";2

但我想添加空值:

  1;"JOHN";1;"john";1
    2;"JOHN";2;"MAX";2
    3;"JOHN";2;NULL;NULL

是否可以在销售中使用空值进行此类查询?

PS 我知道 LEFT JOIN:

SELECT s.id,s.client1 as c1,c1.district as d1,s.client2 as c2,c2.district as d2
FROM public.t_sales s
LEFT JOIN t_client c1 ON c1.name=s.client1 
LEFT JOIN t_client c2 ON c2.name=s.client2
LEFT JOIN t_sale_district sd1 ON sd1.district_id = c1.district AND sd1.sale_id=s.id
LEFT JOIN t_sale_district sd2 ON sd2.district_id = c2.district AND sd2.sale_id=s.id

输出:

1;"JOHN";2;"john";1
1;"JOHN";1;"john";1
2;"JOHN";1;"MAX";2
2;"JOHN";2;"MAX";2
2;"JOHN";1;"MAX";1
2;"JOHN";2;"MAX";1
1;"JOHN";2;"john";2
1;"JOHN";1;"john";2
3;"JOHN";2;"";
3;"JOHN";1;"";

PS2。我只找到了一种解决方案(thanx Zaynul Abadin Tuhin):

select ids,t1.* from    
(
    select s.id as ids,c1.district as d1, c2.district as d2,c1.id as c1,c2.id as c2,s.client1,s.client2 from  t_sales s    
     left join t_client c1 on s.client1=c1.name
     left join t_client c2 on s.client2=c2.name
 )
    as t1 
    left join    t_sale_district d1 on d1.sale_id=t1.ids 
    left join    t_sale_district d2 on d2.sale_id=t1.ids 
where
    (t1.d2 IS NULL OR t1.d2=d2.district_id )
    and (t1.d1 IS NULL OR t1.d1=d1.district_id)

输出:

1;1;1;1;1;3;"JOHN";"john"
2;2;2;2;2;6;"JOHN";"MAX"
3;3;1;;1;;"JOHN";""

有没有更简单的解决方案?

【问题讨论】:

  • 左连接应该可以解决这个问题,就像你在标题中提到的那样,但你还没有在你的代码中使用它们?
  • 欢迎来到 StackOverflow!有关不同类型连接的更多信息,请参阅here
  • 我当然知道左连接,但是如果没有客户的所有记录,我就无法从销售中选择所有记录。
  • 您能编辑您的问题并删除多余的 RDBMS 标签吗?您可能使用 MySQL 或 PostgreSQL,而不是两者。

标签: mysql sql postgresql


【解决方案1】:

您可以尝试使用此查询,其中包含您需要的完全相同的结果

SELECT s.id,s.client1 as c1,c1.district as d1,s.client2 as c2,c2.district as d2
FROM public.t_sales s
LEFT JOIN t_client c1 ON c1.name=s.client1 
LEFT JOIN t_client c2 ON c2.name=s.client2
LEFT JOIN t_sale_district sd1 ON sd1.district_id = c1.district AND sd1.sale_id=s.id
LEFT JOIN t_sale_district sd2 ON sd2.district_id = c2.district AND sd2.sale_id=s.id

【讨论】:

    【解决方案2】:

    使用左连接

    with t1 as 
    (
    (select s.id,s.client1 as c1,s.client2 as c2,c.district from  t_sales s
    
     join t_client c on s.id=c.id
    
     )
     ) ,t2 as
    
     (
    select * from t1 left join  t_sale_district d on t1.district=d.district_id
     )  select * from t2 
    

    对于mysql

        select * from
        (
         select * from  t_sales s    
         join t_client c on s.id=c.id
        ) as t1 left join
         t_sale_district d on t1.district=d.district_id
    

    【讨论】:

    • 不,它包括所有表中的所有记录。
    • @IlyaFilatov 请立即查看
    • 是的,它适用于 Postgresql,你对 MySql 有什么想法吗?
    • 我要导出的数据库是MySQL
    • 这意味着你的数据库不是postgrey这个mysql需要的查询?
    【解决方案3】:

    试试这个

    SELECT s.id,s.client1 as c1,c1.district as d1,s.client2 as c2,c2.district as d2
    FROM public.t_sales s
         left outer JOIN t_client c1 ON c1.name=s.client1 
        left outer JOIN t_client c2 ON c2.name=s.client2
    

    工作示例here

    【讨论】:

      【解决方案4】:

      你可以试试这个 SQL

      SELECT s.id,s.client1 as c1,c1.district as d1,s.client2 as c2,c2.district as d2
      FROM t_sales s
          LEFT JOIN t_client c1 ON c1.name=s.client1 
          LEFT JOIN t_client c2 ON c2.name=s.client2
          LEFT JOIN t_sale_district sd1 ON sd1.district_id = c1.district 
          LEFT JOIN t_sale_district sd2 ON sd2.district_id = c2.district 
          WHERE (sd1.sale_id=s.id AND sd2.sale_id=s.id) OR (sd1.sale_id is null OR sd2.sale_id is null)
      

      【讨论】:

      • 不正确:1;"JOHN";1;"john";1 3;"JOHN";1;""; 2;“约翰”;2;“最大”;2 3;“约翰”;2;“”;
      猜你喜欢
      • 2014-07-19
      • 2014-10-23
      • 1970-01-01
      • 2022-06-10
      • 2019-06-13
      • 2016-03-15
      • 2017-02-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多