@@ -429,46 +429,59 @@ private static boolean limitMySqlQueryBlock(SQLSelectQueryBlock queryBlock, DbTy
429
429
}
430
430
431
431
private static String count (SQLSelect select , DbType dbType ) {
432
+ // 去除 ORDER BY
432
433
if (select .getOrderBy () != null ) {
433
- select .setOrderBy (( SQLOrderBy ) null );
434
+ select .setOrderBy (null );
434
435
}
435
436
436
437
SQLSelectQuery query = select .getQuery ();
437
- clearOrderBy (query );
438
+ clearOrderBy (query ); // 自定义的清理嵌套子查询中的 ORDER BY 的方法
439
+
438
440
if (query instanceof SQLSelectQueryBlock ) {
439
- SQLSelectItem countItem = createCountItem (dbType );
440
441
SQLSelectQueryBlock queryBlock = (SQLSelectQueryBlock ) query ;
441
442
List <SQLSelectItem > selectList = queryBlock .getSelectList ();
443
+ int distinctOption = queryBlock .getDistionOption ();
444
+
445
+ // 情况 1: 存在 GROUP BY,需用子查询
442
446
if (queryBlock .getGroupBy () != null && queryBlock .getGroupBy ().getItems ().size () > 0 ) {
443
- if (queryBlock . getSelectList (). size () == 1 && (( SQLSelectItem ) queryBlock . getSelectList (). get (0 ) ).getExpr () instanceof SQLAllColumnExpr ) {
444
- queryBlock . getSelectList () .clear ();
445
- queryBlock . getSelectList () .add (new SQLSelectItem (new SQLIntegerExpr (1 )));
447
+ if (selectList . size () == 1 && selectList . get (0 ).getExpr () instanceof SQLAllColumnExpr ) {
448
+ selectList .clear ();
449
+ selectList .add (new SQLSelectItem (new SQLIntegerExpr (1 )));
446
450
}
447
-
448
451
return createCountUseSubQuery (select , dbType );
449
- } else {
450
- int option = queryBlock .getDistionOption ();
451
- if (option == 2 && selectList .size () >= 1 ) {
452
- SQLAggregateExpr countExpr = new SQLAggregateExpr ("COUNT" , SQLAggregateOption .DISTINCT );
452
+ }
453
453
454
- for (int i = 0 ; i < selectList .size (); ++i ) {
455
- countExpr .addArgument (((SQLSelectItem ) selectList .get (i )).getExpr ());
454
+ // 情况 2: DISTINCT 情况下,Oracle 特别处理
455
+ if (distinctOption == SQLSetQuantifier .DISTINCT ) {
456
+ if (dbType == DbType .oracle && (
457
+ selectList .size () > 1 ||
458
+ (selectList .size () == 1 && selectList .get (0 ).getExpr () instanceof SQLAllColumnExpr )
459
+ )) {
460
+ // SELECT DISTINCT * 或多字段,Oracle 不支持直接 count(distinct ...)
461
+ return createCountUseSubQuery (select , dbType );
462
+ } else {
463
+ // 只有一个字段,Oracle 支持 count(distinct col)
464
+ SQLAggregateExpr countExpr = new SQLAggregateExpr ("COUNT" , SQLAggregateOption .DISTINCT );
465
+ for (SQLSelectItem item : selectList ) {
466
+ countExpr .addArgument (item .getExpr ());
456
467
}
457
-
458
468
selectList .clear ();
459
- queryBlock .setDistionOption (0 );
469
+ queryBlock .setDistionOption (0 ); // 去除 DISTINCT
460
470
queryBlock .addSelectItem (countExpr );
461
- } else {
462
- selectList .clear ();
463
- selectList .add (countItem );
471
+ return SQLUtils .toSQLString (select , dbType );
464
472
}
465
-
466
- return SQLUtils .toSQLString (select , dbType );
467
473
}
474
+
475
+ // 情况 3: 非 DISTINCT,无 GROUP BY,直接 count(*)
476
+ selectList .clear ();
477
+ selectList .add (createCountItem (dbType ));
478
+ return SQLUtils .toSQLString (select , dbType );
479
+
468
480
} else if (query instanceof SQLUnionQuery ) {
481
+ // UNION 情况统一使用子查询
469
482
return createCountUseSubQuery (select , dbType );
470
483
} else {
471
- throw new IllegalStateException ();
484
+ throw new IllegalStateException ("不支持的 SQL 查询类型: " + query . getClass (). getName () );
472
485
}
473
486
}
474
487
0 commit comments