mirror of
https://gitee.com/mybatis-flex/mybatis-flex.git
synced 2025-12-07 00:58:24 +08:00
fix SqlServer 多表关联查询,主表去重,执行SQL异常 https://gitee.com/mybatis-flex/mybatis-flex/issues/IABEJG
This commit is contained in:
parent
ca2e10dd70
commit
be559dca98
@ -15,13 +15,15 @@
|
|||||||
*/
|
*/
|
||||||
package com.mybatisflex.core.dialect;
|
package com.mybatisflex.core.dialect;
|
||||||
|
|
||||||
import com.mybatisflex.core.query.*;
|
|
||||||
import com.mybatisflex.core.util.CollectionUtil;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static com.mybatisflex.core.constant.SqlConsts.*;
|
import static com.mybatisflex.core.constant.SqlConsts.*;
|
||||||
|
|
||||||
|
import com.mybatisflex.core.query.CPI;
|
||||||
|
import com.mybatisflex.core.query.QueryOrderBy;
|
||||||
|
import com.mybatisflex.core.query.QueryTable;
|
||||||
|
import com.mybatisflex.core.query.QueryWrapper;
|
||||||
|
import com.mybatisflex.core.util.CollectionUtil;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* limit 和 offset 参数的处理器
|
* limit 和 offset 参数的处理器
|
||||||
*/
|
*/
|
||||||
@ -112,21 +114,6 @@ public interface LimitOffsetProcessor {
|
|||||||
String originalSQL = sql.toString();
|
String originalSQL = sql.toString();
|
||||||
String orderByString;
|
String orderByString;
|
||||||
List<QueryOrderBy> orderBys = CPI.getOrderBys(queryWrapper);
|
List<QueryOrderBy> orderBys = CPI.getOrderBys(queryWrapper);
|
||||||
//with 查询根据查询列返回,去除__rn列
|
|
||||||
List<QueryColumn> columnList = CPI.getSelectColumns(queryWrapper);
|
|
||||||
String selectColumns = ASTERISK;
|
|
||||||
StringBuilder selectColumnsBuilder = new StringBuilder();
|
|
||||||
if (columnList != null && !columnList.isEmpty()) {
|
|
||||||
columnList.forEach(column -> {
|
|
||||||
String alias = column.getAlias();
|
|
||||||
if (alias != null) {
|
|
||||||
selectColumnsBuilder.append(alias).append(DELIMITER);
|
|
||||||
} else {
|
|
||||||
selectColumnsBuilder.append(column.getName()).append(DELIMITER);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
selectColumns = selectColumnsBuilder.deleteCharAt(selectColumnsBuilder.length() - 2).toString();
|
|
||||||
}
|
|
||||||
if (orderBys == null || orderBys.isEmpty()) {
|
if (orderBys == null || orderBys.isEmpty()) {
|
||||||
orderByString = "ORDER BY CURRENT_TIMESTAMP";
|
orderByString = "ORDER BY CURRENT_TIMESTAMP";
|
||||||
} else {
|
} else {
|
||||||
@ -143,16 +130,12 @@ public interface LimitOffsetProcessor {
|
|||||||
orderByString = orderBySql.toString();
|
orderByString = orderBySql.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
StringBuilder newSql = new StringBuilder("WITH temp_datas AS(");
|
StringBuilder newSql = new StringBuilder();
|
||||||
newSql.append("SELECT ROW_NUMBER() OVER (")
|
//fix SqlServer 多表关联查询,主表去重,执行SQL异常 https://gitee.com/mybatis-flex/mybatis-flex/issues/IABEJG
|
||||||
.append(orderByString)
|
newSql.append("WITH temp_datas AS(SELECT __Tab.*, ROW_NUMBER() OVER ( ").append(orderByString)
|
||||||
.append(") as __rn,")
|
.append(") as __rn ").append(" FROM ( ").append(originalSQL).append(" ) as __Tab ) ");
|
||||||
.append(originalSQL.substring(6));
|
newSql.append(" SELECT * FROM temp_datas WHERE __rn BETWEEN ")
|
||||||
newSql.append(")");
|
.append(limitOffset + 1).append(" AND ").append(limitOffset + limitRows);
|
||||||
newSql.append(" SELECT ").append(selectColumns).append(" FROM temp_datas WHERE __rn BETWEEN ")
|
|
||||||
.append(limitOffset + 1)
|
|
||||||
.append(" AND ")
|
|
||||||
.append(limitOffset + limitRows);
|
|
||||||
newSql.append(" ORDER BY __rn");
|
newSql.append(" ORDER BY __rn");
|
||||||
return newSql;
|
return newSql;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,16 +1,18 @@
|
|||||||
package com.mybatisflex.coretest;
|
package com.mybatisflex.coretest;
|
||||||
|
|
||||||
|
import static com.mybatisflex.coretest.table.AccountTableDef.ACCOUNT;
|
||||||
|
import static com.mybatisflex.coretest.table.ArticleTableDef.ARTICLE;
|
||||||
|
|
||||||
import com.mybatisflex.core.dialect.IDialect;
|
import com.mybatisflex.core.dialect.IDialect;
|
||||||
import com.mybatisflex.core.dialect.KeywordWrap;
|
import com.mybatisflex.core.dialect.KeywordWrap;
|
||||||
import com.mybatisflex.core.dialect.LimitOffsetProcessor;
|
import com.mybatisflex.core.dialect.LimitOffsetProcessor;
|
||||||
import com.mybatisflex.core.dialect.impl.CommonsDialectImpl;
|
import com.mybatisflex.core.dialect.impl.CommonsDialectImpl;
|
||||||
|
import com.mybatisflex.core.dialect.impl.Sqlserver2005DialectImpl;
|
||||||
|
import com.mybatisflex.core.query.QueryMethods;
|
||||||
import com.mybatisflex.core.query.QueryWrapper;
|
import com.mybatisflex.core.query.QueryWrapper;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import static com.mybatisflex.coretest.table.AccountTableDef.ACCOUNT;
|
|
||||||
import static com.mybatisflex.coretest.table.ArticleTableDef.ARTICLE;
|
|
||||||
|
|
||||||
public class LimitOffsetProcessorTester {
|
public class LimitOffsetProcessorTester {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -35,4 +37,18 @@ public class LimitOffsetProcessorTester {
|
|||||||
"SELECT ROW_NUMBER() OVER ( ORDER BY [tb_account].[id] DESC) as __rn, * FROM [tb_account] LEFT JOIN [tb_article] ON [tb_article].[account_id] = [tb_account].[id]" +
|
"SELECT ROW_NUMBER() OVER ( ORDER BY [tb_account].[id] DESC) as __rn, * FROM [tb_account] LEFT JOIN [tb_article] ON [tb_article].[account_id] = [tb_account].[id]" +
|
||||||
") SELECT * FROM temp_datas WHERE __rn BETWEEN 11 AND 20 ORDER BY __rn", sql);
|
") SELECT * FROM temp_datas WHERE __rn BETWEEN 11 AND 20 ORDER BY __rn", sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSqlServer2005With() {
|
||||||
|
IDialect dialect = new Sqlserver2005DialectImpl();
|
||||||
|
QueryWrapper allTablequeryWrapper = QueryWrapper.create()
|
||||||
|
.select(QueryMethods.distinct(ACCOUNT.ID, ARTICLE.TITLE, ARTICLE.ID.as("ar_id")),
|
||||||
|
QueryMethods.count(ACCOUNT.ID).as("cnt")).from(ACCOUNT)
|
||||||
|
.leftJoin(ARTICLE).on(ARTICLE.ACCOUNT_ID.eq(ACCOUNT.ID)).orderBy(ACCOUNT.ID.desc()).limit(10, 10);
|
||||||
|
String sql = dialect.forSelectByQuery(allTablequeryWrapper);
|
||||||
|
System.out.println(sql);
|
||||||
|
Assert.assertEquals(
|
||||||
|
"WITH temp_datas AS(SELECT __Tab.*, ROW_NUMBER() OVER ( ORDER BY [tb_account].[id] DESC) as __rn FROM ( SELECT DISTINCT [tb_account].[id], [tb_article].[title], [tb_article].[id] AS [ar_id], COUNT([tb_account].[id]) AS [cnt] FROM [tb_account] LEFT JOIN [tb_article] ON [tb_article].[account_id] = [tb_account].[id] ) as __Tab ) SELECT * FROM temp_datas WHERE __rn BETWEEN 11 AND 20 ORDER BY __rn",
|
||||||
|
sql);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user