diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/dialect/LimitOffsetProcessor.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/dialect/LimitOffsetProcessor.java index ab5d80c6..2735f7ed 100644 --- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/dialect/LimitOffsetProcessor.java +++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/dialect/LimitOffsetProcessor.java @@ -15,13 +15,15 @@ */ 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 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 参数的处理器 */ @@ -112,21 +114,6 @@ public interface LimitOffsetProcessor { String originalSQL = sql.toString(); String orderByString; List orderBys = CPI.getOrderBys(queryWrapper); - //with 查询根据查询列返回,去除__rn列 - List 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()) { orderByString = "ORDER BY CURRENT_TIMESTAMP"; } else { @@ -143,16 +130,12 @@ public interface LimitOffsetProcessor { orderByString = orderBySql.toString(); } - StringBuilder newSql = new StringBuilder("WITH temp_datas AS("); - newSql.append("SELECT ROW_NUMBER() OVER (") - .append(orderByString) - .append(") as __rn,") - .append(originalSQL.substring(6)); - newSql.append(")"); - newSql.append(" SELECT ").append(selectColumns).append(" FROM temp_datas WHERE __rn BETWEEN ") - .append(limitOffset + 1) - .append(" AND ") - .append(limitOffset + limitRows); + StringBuilder newSql = new StringBuilder(); + //fix SqlServer 多表关联查询,主表去重,执行SQL异常 https://gitee.com/mybatis-flex/mybatis-flex/issues/IABEJG + newSql.append("WITH temp_datas AS(SELECT __Tab.*, ROW_NUMBER() OVER ( ").append(orderByString) + .append(") as __rn ").append(" FROM ( ").append(originalSQL).append(" ) as __Tab ) "); + newSql.append(" SELECT * FROM temp_datas WHERE __rn BETWEEN ") + .append(limitOffset + 1).append(" AND ").append(limitOffset + limitRows); newSql.append(" ORDER BY __rn"); return newSql; } diff --git a/mybatis-flex-core/src/test/java/com/mybatisflex/coretest/LimitOffsetProcessorTester.java b/mybatis-flex-core/src/test/java/com/mybatisflex/coretest/LimitOffsetProcessorTester.java index 452d5a71..e6a4b1e3 100644 --- a/mybatis-flex-core/src/test/java/com/mybatisflex/coretest/LimitOffsetProcessorTester.java +++ b/mybatis-flex-core/src/test/java/com/mybatisflex/coretest/LimitOffsetProcessorTester.java @@ -1,16 +1,18 @@ 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.KeywordWrap; import com.mybatisflex.core.dialect.LimitOffsetProcessor; 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 org.junit.Assert; import org.junit.Test; -import static com.mybatisflex.coretest.table.AccountTableDef.ACCOUNT; -import static com.mybatisflex.coretest.table.ArticleTableDef.ARTICLE; - public class LimitOffsetProcessorTester { @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 * 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); + } }