用insert into select 以及left join给出
时间: 2023-08-15 20:07:55 浏览: 89
您可以使用INSERT INTO SELECT语句和LEFT JOIN来实现多表融合并去掉多余的字段。以下是使用这种方法的示例:
```sql
INSERT INTO A (a1, b1)
SELECT A.a1, E.b1
FROM A
LEFT JOIN D ON A.a1 = D.a1
LEFT JOIN E ON A.a1 = E.a1
LEFT JOIN F ON E.b1 = F.b1;
```
在这个例子中,我们使用了多个LEFT JOIN语句将表D、E和F与表A进行连接。通过LEFT JOIN,即使没有在所有表中找到匹配的记录,也会返回表A中的记录。最终的SELECT子句中,我们只选择了表A和表E中需要的字段a1和b1。然后,将这些字段的值插入到表A中。这样就实现了多表融合并去掉多余的字段。
相关问题
insert into select from left in
对于insert into select from left in这个问题,可以使用以下方法进行处理。首先,我们需要确保语句的正确性和可读性。其次,我们可以使用INSERT INTO SELECT语句来将左连接的结果插入到目标表中。例如,可以使用以下语句:
INSERT INTO table_name_new (column1, column2...)
SELECT column1, column2...
FROM table_name_old
LEFT JOIN tableC ON table_name_old.column = tableC.column
这里,table_name_new是目标表名,column1、column2...是目标表的字段,table_name_old是源表名,column1、column2...是源表的字段。LEFT JOIN语句用于将table_name_old和tableC进行左连接,可以根据需要修改连接条件。
需要注意的是,在使用INSERT INTO SELECT语句时,要确保源表和目标表的结构一致,以便正确地插入数据。同时,还要确保相关的条件和索引设置正确,以避免出现数据被锁定的情况。
以下是使用Java和druid解析sql,并通过feign接口查询到的表元数据,替换包含left join的insert into table select sql语句中的*的代码示例:
以下是使用Java和druid解析sql,并通过feign接口查询到的表元数据,替换包含left join的insert into table select sql语句中的*的代码示例:
```java
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.ast.statement.*;
import com.alibaba.druid.util.JdbcConstants;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Joiner;
import feign.Feign;
import feign.gson.GsonDecoder;
import feign.gson.GsonEncoder;
import feign.okhttp.OkHttpClient;
import feign.slf4j.Slf4jLogger;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Slf4j
public class SqlParserUtils {
/**
* 解析insert into table select语句中的表名
*/
public static String parseTableName(String sql) {
List<SQLStatement> stmtList = SQLUtils.parseStatements(sql, JdbcConstants.MYSQL);
SQLInsertStatement insertStmt = (SQLInsertStatement) stmtList.get(0);
SQLSelectStatement selectStmt = (SQLSelectStatement) insertStmt.getQuery().getQuery();
SQLSelect sqlSelect = selectStmt.getSelect();
SQLSelectQueryBlock sqlSelectQuery = (SQLSelectQueryBlock) sqlSelect.getQuery();
SQLTableSource tableSource = sqlSelectQuery.getFrom();
if (tableSource instanceof SQLExprTableSource) {
return ((SQLExprTableSource) tableSource).getName().getSimpleName();
} else if (tableSource instanceof SQLJoinTableSource) {
SQLJoinTableSource joinSource = (SQLJoinTableSource) tableSource;
SQLTableSource left = joinSource.getLeft();
if (left instanceof SQLExprTableSource) {
return ((SQLExprTableSource) left).getName().getSimpleName();
}
}
throw new IllegalArgumentException("无法解析的SQL语句");
}
/**
* 解析insert into table select语句中的列名
*/
public static List<String> parseColumnNames(String sql) {
List<SQLStatement> stmtList = SQLUtils.parseStatements(sql, JdbcConstants.MYSQL);
SQLInsertStatement insertStmt = (SQLInsertStatement) stmtList.get(0);
SQLSelectStatement selectStmt = (SQLSelectStatement) insertStmt.getQuery().getQuery();
SQLSelect sqlSelect = selectStmt.getSelect();
SQLSelectQueryBlock sqlSelectQuery = (SQLSelectQueryBlock) sqlSelect.getQuery();
List<SQLSelectItem> selectList = sqlSelectQuery.getSelectList();
List<String> columnNames = new ArrayList<>();
for (SQLSelectItem selectItem : selectList) {
SQLExpr expr = selectItem.getExpr();
if (expr instanceof SQLIdentifierExpr) {
columnNames.add(((SQLIdentifierExpr) expr).getName());
}
}
return columnNames;
}
/**
* 替换insert into table select语句中的*为实际列名
*/
public static String replaceAsterisk(String sql, List<String> columnNames) {
SQLSelectParser parser = new MySqlSelectParser(sql);
SQLSelect select = parser.select();
SQLSelectQueryBlock query = (SQLSelectQueryBlock) select.getQuery();
List<SQLSelectItem> selectList = query.getSelectList();
if (!CollectionUtils.isEmpty(selectList)) {
for (int i = 0; i < selectList.size(); i++) {
SQLSelectItem selectItem = selectList.get(i);
SQLExpr expr = selectItem.getExpr();
if (expr instanceof SQLAllColumnExpr) {
selectList.remove(i);
for (String columnName : columnNames) {
SQLSelectItem newSelectItem = new SQLSelectItem(new SQLIdentifierExpr(columnName));
selectList.add(i, newSelectItem);
i++;
}
break;
}
}
}
return SQLUtils.toMySqlString(select);
}
/**
* 查询表元数据
*/
public static JSONObject getTableMetadata(String tableName, String metadataServiceUrl) {
Feign.Builder builder = Feign.builder()
.encoder(new GsonEncoder())
.decoder(new GsonDecoder())
.logger(new Slf4jLogger(SqlParserUtils.class))
.client(new OkHttpClient());
MetadataServiceClient client = builder.target(MetadataServiceClient.class, metadataServiceUrl);
Map<String, Object> result = client.getTableMetadata(tableName);
return JSON.parseObject(JSON.toJSONString(result));
}
/**
* 替换insert into table select语句中的*为实际列名,并获取列的类型信息
*/
public static String replaceAsteriskAndGetType(String sql, String metadataServiceUrl) {
String tableName = parseTableName(sql);
List<String> columnNames = parseColumnNames(sql);
JSONObject tableMetadata = getTableMetadata(tableName, metadataServiceUrl);
List<JSONObject> columns = tableMetadata.getJSONArray("columns").toJavaList(JSONObject.class);
List<String> columnTypes = columns.stream().filter(column -> columnNames.contains(column.getString("name")))
.map(column -> column.getString("type")).collect(Collectors.toList());
String replacedSql = replaceAsterisk(sql, columnNames);
String columnTypesStr = Joiner.on(",").join(columnTypes);
return String.format("%s/*{%s}*/", replacedSql, columnTypesStr);
}
}
```
其中,MetadataServiceClient为通过Feign实现的调用元数据服务接口的客户端,代码示例如下:
```java
import feign.RequestLine;
import java.util.Map;
public interface MetadataServiceClient {
@RequestLine("GET /metadata/tables/{tableName}")
Map<String, Object> getTableMetadata(String tableName);
}
```