left join 改成子查询
时间: 2024-08-09 16:01:53 浏览: 201
左连接 (LEFT JOIN) 和子查询在 SQL 中都是用来结合两个表的数据,但它们的实现方式不同。
左连接是一种内联操作,它返回左表的所有行以及右表匹配的行,如果右表没有匹配,则结果中的对应列将填充 NULL 值。例如,如果你想查找所有用户及其关联的产品信息,即使有些用户没有购买产品,也会显示出来:
```sql
SELECT users.*, products.*
FROM users
LEFT JOIN products ON users.product_id = products.id;
```
而子查询则是先在一个查询中获取数据,然后在另一个查询中使用这个结果。如果你想要实现类似的效果,可以这样做:
1. 首先创建一个内部查询,找出有产品的用户:
```sql
SELECT user_id FROM products GROUP BY user_id HAVING COUNT(*) > 0;
```
2. 然后在外部查询中,使用这个子查询作为条件来筛选用户:
```sql
SELECT * FROM users WHERE user_id IN (
(SELECT user_id FROM products GROUP BY user_id HAVING COUNT(*) > 0)
);
```
这样也能得到包含所有用户和他们购买的产品信息,只是表达方式不同。
相关问题
left join转换成子查询怎么写
将左连接转换为子查询的一般步骤如下:
1. 将左连接的左表和右表分别转换为子查询。
2. 在左连接的ON子句中使用子查询语句引用左表和右表。
3. 在SELECT子句中使用子查询语句引用右表中的列。
4. 在FROM子句中使用LEFT JOIN关键字和子查询中的表别名,将两个子查询连接起来。
例如,将以下左连接转换为子查询:
```
SELECT *
FROM table1
LEFT JOIN table2 ON table1.id = table2.id;
```
可以转换为以下子查询:
```
SELECT *
FROM (
SELECT *
FROM table1
) AS t1
LEFT JOIN (
SELECT *
FROM table2
) AS t2 ON t1.id = t2.id;
```
在这个例子中,我们将table1和table2分别转换为子查询,并将子查询中的表别名设置为t1和t2。在ON子句中,我们引用了t1和t2中的列,而在SELECT子句中,我们引用了t2中的列。最后,我们使用LEFT JOIN关键字将两个子查询连接起来。
mismatched input 'WITH' expecting {'(', 'SELECT', 'FROM', 'VALUES', 'TABLE', 'INSERT', 'MAP', 'REDUCE'}(line 1, pos 1191) == SQL == WITH TAB_A AS ( select DISTINCT A.IMSI, coalesce(B.COUNTRY,C.COUNTRY) GJ, coalesce(B.OPERATOR,C.OPERATOR) YYS from ( SELECT A.START_TIME, A.END_TIME, A.MSISDN, A.IMSI, A.CALLING_GT, A.OPERATE_CODE, A.RESULT, A.ERROR_CODE, substr(a.CALLING_GT,1,6) CALLING_GT_6, substr(a.CALLING_GT,1,5) CALLING_GT_5, substr(a.CALLING_GT,1,4) CALLING_GT_4 FROM spark_odc_dwd.D_ENS_GMAP_MM a WHERE p_hour='2023060600' ) a left join ( SELECT DISTINCT regexp_replace(E164_IR21,'[^0-9]+','') E164_IR21, SUBSTR(regexp_replace(E164_IR21,'[^0-9]+',''),1,6) E164_IR21_6, SUBSTR(regexp_replace(E164_IR21,'[^0-9]+',''),1,5) E164_IR21_5, SUBSTR(regexp_replace(E164_IR21,'[^0-9]+',''),1,4) E164_IR21_4, COUNTRY, VENDOR_NAME AS OPERATOR FROM spark_odc_data.A_DM_CO_BA_VR_OPT_GT A) b on A.CALLING_GT_5=b.E164_IR21_5 left join ( SELECT DISTINCT regexp_replace(E164_IR21,'[^0-9]+','') E164_IR21, SUBSTR(regexp_replace(E164_IR21,'[^0-9]+',''),1,6) E164_IR21_6, SUBSTR(regexp_replace(E164_IR21,'[^0-9]+',''),1,5) E164_IR21_5, SUBSTR(regexp_replace(E164_IR21,'[^0-9]+',''),1,4) E164_IR21_4, COUNTRY, VENDOR_NAME AS OPERATOR FROM spark_odc_data.A_DM_CO_BA_VR_OPT_GT A) c on A.CALLING_GT_4=c.E164_IR21_4)
这个报错与前一个类似,是因为WITH语句不被支持或者不被SQL版本所支持。你可以将WITH语句改写成子查询的形式,例如:
```
SELECT DISTINCT A.IMSI, coalesce(B.COUNTRY,C.COUNTRY) AS GJ, coalesce(B.OPERATOR,C.OPERATOR) AS YYS
FROM (
SELECT START_TIME, END_TIME, MSISDN, IMSI, CALLING_GT, OPERATE_CODE, RESULT, ERROR_CODE, substr(CALLING_GT,1,6) AS CALLING_GT_6, substr(CALLING_GT,1,5) AS CALLING_GT_5, substr(CALLING_GT,1,4) AS CALLING_GT_4
FROM spark_odc_dwd.D_ENS_GMAP_MM
WHERE p_hour='2023060600'
) A
LEFT JOIN (
SELECT DISTINCT regexp_replace(E164_IR21,'[^0-9]+','') AS E164_IR21, SUBSTR(regexp_replace(E164_IR21,'[^0-9]+',''),1,6) AS E164_IR21_6, SUBSTR(regexp_replace(E164_IR21,'[^0-9]+',''),1,5) AS E164_IR21_5, SUBSTR(regexp_replace(E164_IR21,'[^0-9]+',''),1,4) AS E164_IR21_4, COUNTRY, VENDOR_NAME AS OPERATOR
FROM spark_odc_data.A_DM_CO_BA_VR_OPT_GT
) B ON A.CALLING_GT_5=B.E164_IR21_5
LEFT JOIN (
SELECT DISTINCT regexp_replace(E164_IR21,'[^0-9]+','') AS E164_IR21, SUBSTR(regexp_replace(E164_IR21,'[^0-9]+',''),1,6) AS E164_IR21_6, SUBSTR(regexp_replace(E164_IR21,'[^0-9]+',''),1,5) AS E164_IR21_5, SUBSTR(regexp_replace(E164_IR21,'[^0-9]+',''),1,4) AS E164_IR21_4, COUNTRY, VENDOR_NAME AS OPERATOR
FROM spark_odc_data.A_DM_CO_BA_VR_OPT_GT
) C ON A.CALLING_GT_4=C.E164_IR21_4;
```
这样就可以避免使用WITH语句而得到正确的结果。
阅读全文