diff --git a/common/src/main/java/com/tencent/supersonic/common/jsqlparser/SqlReplaceHelper.java b/common/src/main/java/com/tencent/supersonic/common/jsqlparser/SqlReplaceHelper.java index 6604f2487..d5443c328 100644 --- a/common/src/main/java/com/tencent/supersonic/common/jsqlparser/SqlReplaceHelper.java +++ b/common/src/main/java/com/tencent/supersonic/common/jsqlparser/SqlReplaceHelper.java @@ -528,7 +528,7 @@ public class SqlReplaceHelper { } } - private static Select replaceAggAliasOrderItem(Select selectStatement) { + private static Select replaceAggAliasOrderbyField(Select selectStatement) { if (selectStatement instanceof PlainSelect) { PlainSelect plainSelect = (PlainSelect) selectStatement; if (Objects.nonNull(plainSelect.getOrderByElements())) { @@ -564,15 +564,15 @@ public class SqlReplaceHelper { if (plainSelect.getFromItem() instanceof ParenthesedSelect) { ParenthesedSelect parenthesedSelect = (ParenthesedSelect) plainSelect.getFromItem(); parenthesedSelect - .setSelect(replaceAggAliasOrderItem(parenthesedSelect.getSelect())); + .setSelect(replaceAggAliasOrderbyField(parenthesedSelect.getSelect())); } return selectStatement; } return selectStatement; } - public static String replaceAggAliasOrderItem(String sql) { - Select selectStatement = replaceAggAliasOrderItem(SqlSelectHelper.getSelect(sql)); + public static String replaceAggAliasOrderbyField(String sql) { + Select selectStatement = replaceAggAliasOrderbyField(SqlSelectHelper.getSelect(sql)); return selectStatement.toString(); } diff --git a/common/src/main/java/com/tencent/supersonic/common/pojo/Filter.java b/common/src/main/java/com/tencent/supersonic/common/pojo/Filter.java index 9ecb491ec..adaab80d1 100644 --- a/common/src/main/java/com/tencent/supersonic/common/pojo/Filter.java +++ b/common/src/main/java/com/tencent/supersonic/common/pojo/Filter.java @@ -2,6 +2,7 @@ package com.tencent.supersonic.common.pojo; import com.tencent.supersonic.common.pojo.enums.FilterOperatorEnum; import lombok.AllArgsConstructor; +import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; @@ -10,6 +11,7 @@ import java.util.List; @Data @AllArgsConstructor @NoArgsConstructor +@Builder public class Filter { private Relation relation = Relation.FILTER; diff --git a/common/src/main/java/com/tencent/supersonic/common/pojo/enums/EngineType.java b/common/src/main/java/com/tencent/supersonic/common/pojo/enums/EngineType.java index 4b05d2620..7acd72ed1 100644 --- a/common/src/main/java/com/tencent/supersonic/common/pojo/enums/EngineType.java +++ b/common/src/main/java/com/tencent/supersonic/common/pojo/enums/EngineType.java @@ -8,7 +8,8 @@ public enum EngineType { KAFKA(4, "kafka"), H2(5, "h2"), POSTGRESQL(6, "postgresql"), - OTHER(7, "other"); + OTHER(7, "other"), + DUCKDB(8, "duckdb"); private Integer code; diff --git a/common/src/main/java/com/tencent/supersonic/common/util/DateModeUtils.java b/common/src/main/java/com/tencent/supersonic/common/util/DateModeUtils.java index a5753c085..75ee5a597 100644 --- a/common/src/main/java/com/tencent/supersonic/common/util/DateModeUtils.java +++ b/common/src/main/java/com/tencent/supersonic/common/util/DateModeUtils.java @@ -4,6 +4,7 @@ import com.tencent.supersonic.common.pojo.Constants; import com.tencent.supersonic.common.pojo.DateConf; import com.tencent.supersonic.common.pojo.ItemDateResp; import com.tencent.supersonic.common.pojo.enums.DatePeriodEnum; +import com.tencent.supersonic.common.pojo.enums.TimeDimensionEnum; import lombok.Data; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; @@ -32,14 +33,9 @@ import static com.tencent.supersonic.common.pojo.Constants.MONTH_FORMAT; @Data public class DateModeUtils { - @Value("${s2.query.parameter.sys.date:sys_imp_date}") - private String sysDateCol; - - @Value("${s2.query.parameter.sys.month:sys_imp_month}") - private String sysDateMonthCol; - - @Value("${s2.query.parameter.sys.month:sys_imp_week}") - private String sysDateWeekCol; + private final String sysDateCol = TimeDimensionEnum.DAY.getName(); + private final String sysDateMonthCol = TimeDimensionEnum.MONTH.getName(); + private final String sysDateWeekCol = TimeDimensionEnum.WEEK.getName(); @Value("${s2.query.parameter.sys.zipper.begin:start_}") private String sysZipperDateColBegin; diff --git a/common/src/main/java/com/tencent/supersonic/common/util/DateUtils.java b/common/src/main/java/com/tencent/supersonic/common/util/DateUtils.java index 1b2007ed9..5ab669aa4 100644 --- a/common/src/main/java/com/tencent/supersonic/common/util/DateUtils.java +++ b/common/src/main/java/com/tencent/supersonic/common/util/DateUtils.java @@ -16,6 +16,7 @@ import java.time.temporal.TemporalAdjuster; import java.time.temporal.TemporalAdjusters; import java.util.ArrayList; import java.util.Arrays; +import java.util.Calendar; import java.util.Date; import java.util.List; import java.util.Objects; @@ -201,6 +202,13 @@ public class DateUtils { return false; } + public static Long calculateDiffMs(Date createAt) { + Calendar calendar = Calendar.getInstance(); + Date now = calendar.getTime(); + long milliseconds = now.getTime() - createAt.getTime(); + return milliseconds; + } + public static boolean isDateString(String value, String format) { try { DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format); diff --git a/common/src/test/java/com/tencent/supersonic/common/jsqlparser/SqlReplaceHelperTest.java b/common/src/test/java/com/tencent/supersonic/common/jsqlparser/SqlReplaceHelperTest.java index a641b2539..084978319 100644 --- a/common/src/test/java/com/tencent/supersonic/common/jsqlparser/SqlReplaceHelperTest.java +++ b/common/src/test/java/com/tencent/supersonic/common/jsqlparser/SqlReplaceHelperTest.java @@ -325,10 +325,10 @@ class SqlReplaceHelperTest { } @Test - void testReplaceAggAliasOrderItem() { + void testReplaceAggAliasOrderbyField() { String sql = "SELECT SUM(访问次数) AS top10总播放量 FROM (SELECT 部门, SUM(访问次数) AS 访问次数 FROM 超音数 " + "GROUP BY 部门 ORDER BY SUM(访问次数) DESC LIMIT 10) AS top10"; - String replaceSql = SqlReplaceHelper.replaceAggAliasOrderItem(sql); + String replaceSql = SqlReplaceHelper.replaceAggAliasOrderbyField(sql); Assert.assertEquals( "SELECT SUM(访问次数) AS top10总播放量 FROM (SELECT 部门, SUM(访问次数) AS 访问次数 FROM 超音数 " + "GROUP BY 部门 ORDER BY 2 DESC LIMIT 10) AS top10", diff --git a/headless/api/src/main/java/com/tencent/supersonic/headless/api/pojo/MetricTable.java b/headless/api/src/main/java/com/tencent/supersonic/headless/api/pojo/MetricTable.java deleted file mode 100644 index 9740891de..000000000 --- a/headless/api/src/main/java/com/tencent/supersonic/headless/api/pojo/MetricTable.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.tencent.supersonic.headless.api.pojo; - -import com.google.common.collect.Lists; -import com.tencent.supersonic.headless.api.pojo.enums.AggOption; -import lombok.Data; - -import java.util.List; - -@Data -public class MetricTable { - - private String alias; - private List metrics = Lists.newArrayList(); - private List dimensions = Lists.newArrayList(); - private String where; - private AggOption aggOption = AggOption.DEFAULT; -} diff --git a/headless/api/src/main/java/com/tencent/supersonic/headless/api/pojo/enums/DataType.java b/headless/api/src/main/java/com/tencent/supersonic/headless/api/pojo/enums/DataType.java index 38a3b0515..03578c0f9 100644 --- a/headless/api/src/main/java/com/tencent/supersonic/headless/api/pojo/enums/DataType.java +++ b/headless/api/src/main/java/com/tencent/supersonic/headless/api/pojo/enums/DataType.java @@ -45,7 +45,8 @@ public enum DataType { TDENGINE("TAOS", "TAOS", "com.taosdata.jdbc.TSDBDriver", "'", "'", "\"", "\""), - POSTGRESQL("postgresql", "postgresql", "org.postgresql.Driver", "'", "'", "\"", "\""); + POSTGRESQL("postgresql", "postgresql", "org.postgresql.Driver", "'", "'", "\"", "\""), + DUCKDB("duckdb", "duckdb", "org.duckdb.DuckDBDriver", "'", "'", "\"", "\""); private String feature; private String desc; diff --git a/headless/api/src/main/java/com/tencent/supersonic/headless/api/pojo/request/ParseSqlReq.java b/headless/api/src/main/java/com/tencent/supersonic/headless/api/pojo/request/ParseSqlReq.java deleted file mode 100644 index ec4519030..000000000 --- a/headless/api/src/main/java/com/tencent/supersonic/headless/api/pojo/request/ParseSqlReq.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.tencent.supersonic.headless.api.pojo.request; - -import com.tencent.supersonic.headless.api.pojo.MetricTable; -import lombok.Data; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -@Data -public class ParseSqlReq { - private Map variables; - private String sql = ""; - private List tables; - private boolean supportWith = true; - private boolean withAlias = true; - - public Map getVariables() { - if (variables == null) { - variables = new HashMap<>(); - } - return variables; - } -} diff --git a/headless/api/src/main/java/com/tencent/supersonic/headless/api/pojo/request/QueryFilter.java b/headless/api/src/main/java/com/tencent/supersonic/headless/api/pojo/request/QueryFilter.java index b06814aef..446377a98 100644 --- a/headless/api/src/main/java/com/tencent/supersonic/headless/api/pojo/request/QueryFilter.java +++ b/headless/api/src/main/java/com/tencent/supersonic/headless/api/pojo/request/QueryFilter.java @@ -34,12 +34,11 @@ public class QueryFilter implements Serializable { QueryFilter that = (QueryFilter) o; return Objects.equal(bizName, that.bizName) && Objects.equal(name, that.name) && operator == that.operator && Objects.equal(value, that.value) - && Objects.equal(elementID, that.elementID) && Objects.equal(function, that.function); } @Override public int hashCode() { - return Objects.hashCode(bizName, name, operator, value, elementID, function); + return Objects.hashCode(bizName, name, operator, value, function); } } diff --git a/headless/api/src/main/java/com/tencent/supersonic/headless/api/pojo/request/ValueTaskQueryReq.java b/headless/api/src/main/java/com/tencent/supersonic/headless/api/pojo/request/ValueTaskQueryReq.java new file mode 100644 index 000000000..f425ff261 --- /dev/null +++ b/headless/api/src/main/java/com/tencent/supersonic/headless/api/pojo/request/ValueTaskQueryReq.java @@ -0,0 +1,23 @@ +package com.tencent.supersonic.headless.api.pojo.request; + +import javax.validation.constraints.NotNull; + +import com.tencent.supersonic.common.pojo.PageBaseReq; +import lombok.Data; + +import java.util.List; + +/** + * @author: kanedai + * @date: 2024/11/24 + */ +@Data +public class ValueTaskQueryReq extends PageBaseReq { + + @NotNull + private Long itemId; + + private List taskStatusList; + + private String key; +} diff --git a/headless/chat/src/main/java/com/tencent/supersonic/headless/chat/parser/llm/OnePassSCSqlGenStrategy.java b/headless/chat/src/main/java/com/tencent/supersonic/headless/chat/parser/llm/OnePassSCSqlGenStrategy.java index a41be00ab..68f6fe39a 100644 --- a/headless/chat/src/main/java/com/tencent/supersonic/headless/chat/parser/llm/OnePassSCSqlGenStrategy.java +++ b/headless/chat/src/main/java/com/tencent/supersonic/headless/chat/parser/llm/OnePassSCSqlGenStrategy.java @@ -37,8 +37,8 @@ public class OnePassSCSqlGenStrategy extends SqlGenStrategy { + "please convert it to a SQL query so that relevant data could be returned " + "by executing the SQL query against underlying database." + "\n#Rules:" + "\n1.SQL columns and values must be mentioned in the `Schema`, DO NOT hallucinate." - + "\n2.ALWAYS specify date filter using `>`,`<`,`>=`,`<=` operator." - + "\n3.DO NOT include date filter in the where clause if not explicitly expressed in the `Question`." + + "\n2.ALWAYS specify time range using `>`,`<`,`>=`,`<=` operator." + + "\n3.DO NOT include time range in the where clause if not explicitly expressed in the `Question`." + "\n4.DO NOT calculate date range using functions." + "\n5.ALWAYS use `with` statement if nested aggregation is needed." + "\n6.ALWAYS enclose alias declared by `AS` command in underscores." diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/adaptor/db/ClickHouseAdaptor.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/adaptor/db/ClickHouseAdaptor.java index 0b9dfd68e..508b2bdba 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/adaptor/db/ClickHouseAdaptor.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/adaptor/db/ClickHouseAdaptor.java @@ -34,7 +34,7 @@ public class ClickHouseAdaptor extends BaseDbAdaptor { } @Override - public String functionNameCorrector(String sql) { + public String rewriteSql(String sql) { Map functionMap = new HashMap<>(); functionMap.put("MONTH".toLowerCase(), "toMonth"); functionMap.put("DAY".toLowerCase(), "toDayOfMonth"); diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/adaptor/db/DbAdaptor.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/adaptor/db/DbAdaptor.java index 63a478e7f..f2e650177 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/adaptor/db/DbAdaptor.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/adaptor/db/DbAdaptor.java @@ -11,7 +11,7 @@ public interface DbAdaptor { String getDateFormat(String dateType, String dateFormat, String column); - String functionNameCorrector(String sql); + String rewriteSql(String sql); List getDBs(ConnectInfo connectInfo) throws SQLException; diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/adaptor/db/DbAdaptorFactory.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/adaptor/db/DbAdaptorFactory.java index 74c7762cb..c8e0aa582 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/adaptor/db/DbAdaptorFactory.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/adaptor/db/DbAdaptorFactory.java @@ -16,6 +16,7 @@ public class DbAdaptorFactory { dbAdaptorMap.put(EngineType.H2.getName(), new H2Adaptor()); dbAdaptorMap.put(EngineType.POSTGRESQL.getName(), new PostgresqlAdaptor()); dbAdaptorMap.put(EngineType.OTHER.getName(), new DefaultDbAdaptor()); + dbAdaptorMap.put(EngineType.DUCKDB.getName(), new DuckdbAdaptor()); } public static DbAdaptor getEngineAdaptor(String engineType) { diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/adaptor/db/DefaultDbAdaptor.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/adaptor/db/DefaultDbAdaptor.java index ae7caae10..16816d64f 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/adaptor/db/DefaultDbAdaptor.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/adaptor/db/DefaultDbAdaptor.java @@ -8,7 +8,7 @@ public class DefaultDbAdaptor extends BaseDbAdaptor { } @Override - public String functionNameCorrector(String sql) { + public String rewriteSql(String sql) { return sql; } } diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/adaptor/db/DuckdbAdaptor.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/adaptor/db/DuckdbAdaptor.java new file mode 100644 index 000000000..f578cbdce --- /dev/null +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/adaptor/db/DuckdbAdaptor.java @@ -0,0 +1,42 @@ +package com.tencent.supersonic.headless.core.adaptor.db; + +import com.google.common.collect.Lists; +import com.tencent.supersonic.headless.api.pojo.DBColumn; +import com.tencent.supersonic.headless.api.pojo.enums.FieldType; +import com.tencent.supersonic.headless.core.pojo.ConnectInfo; +import lombok.extern.slf4j.Slf4j; + +import java.sql.DatabaseMetaData; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; + +@Slf4j +public class DuckdbAdaptor extends DefaultDbAdaptor { + + protected ResultSet getResultSet(String schemaName, DatabaseMetaData metaData) + throws SQLException { + return metaData.getTables(schemaName, null, null, new String[] {"TABLE", "VIEW"}); + } + + public List getColumns(ConnectInfo connectInfo, String schemaName, String tableName) + throws SQLException { + List dbColumns = Lists.newArrayList(); + DatabaseMetaData metaData = getDatabaseMetaData(connectInfo); + ResultSet columns = metaData.getColumns(schemaName, null, tableName, null); + while (columns.next()) { + String columnName = columns.getString("COLUMN_NAME"); + String dataType = columns.getString("TYPE_NAME"); + String remarks = columns.getString("REMARKS"); + FieldType fieldType = classifyColumnType(dataType); + dbColumns.add(new DBColumn(columnName, dataType, remarks, fieldType)); + } + return dbColumns; + } + + @Override + public String rewriteSql(String sql) { + return sql.replaceAll("`", ""); + } + +} diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/adaptor/db/H2Adaptor.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/adaptor/db/H2Adaptor.java index 7ae1e7cc1..5d7e4151d 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/adaptor/db/H2Adaptor.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/adaptor/db/H2Adaptor.java @@ -62,7 +62,7 @@ public class H2Adaptor extends BaseDbAdaptor { } @Override - public String functionNameCorrector(String sql) { + public String rewriteSql(String sql) { return sql; } } diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/adaptor/db/MysqlAdaptor.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/adaptor/db/MysqlAdaptor.java index 64e3a5a4c..5a21036be 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/adaptor/db/MysqlAdaptor.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/adaptor/db/MysqlAdaptor.java @@ -31,7 +31,7 @@ public class MysqlAdaptor extends BaseDbAdaptor { } @Override - public String functionNameCorrector(String sql) { + public String rewriteSql(String sql) { return sql; } } diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/adaptor/db/PostgresqlAdaptor.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/adaptor/db/PostgresqlAdaptor.java index 42cff0c5b..7facc8e97 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/adaptor/db/PostgresqlAdaptor.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/adaptor/db/PostgresqlAdaptor.java @@ -48,7 +48,7 @@ public class PostgresqlAdaptor extends BaseDbAdaptor { } @Override - public String functionNameCorrector(String sql) { + public String rewriteSql(String sql) { Map functionMap = new HashMap<>(); functionMap.put("MONTH".toLowerCase(), "TO_CHAR"); functionMap.put("DAY".toLowerCase(), "TO_CHAR"); diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/executor/AbstractAccelerator.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/executor/AbstractAccelerator.java index 282a60a35..175ff2497 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/executor/AbstractAccelerator.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/executor/AbstractAccelerator.java @@ -3,10 +3,10 @@ package com.tencent.supersonic.headless.core.executor; import com.tencent.supersonic.common.calcite.Configuration; import com.tencent.supersonic.common.jsqlparser.SqlSelectHelper; import com.tencent.supersonic.headless.core.pojo.Materialization; -import com.tencent.supersonic.headless.core.translator.calcite.s2sql.TimeRange; -import com.tencent.supersonic.headless.core.translator.calcite.sql.S2CalciteTable; -import com.tencent.supersonic.headless.core.translator.calcite.sql.S2CalciteTable.Builder; -import com.tencent.supersonic.headless.core.translator.calcite.sql.SchemaBuilder; +import com.tencent.supersonic.headless.core.translator.parser.calcite.S2CalciteTable; +import com.tencent.supersonic.headless.core.translator.parser.calcite.S2CalciteTable.Builder; +import com.tencent.supersonic.headless.core.translator.parser.calcite.SchemaBuilder; +import com.tencent.supersonic.headless.core.translator.parser.s2sql.TimeRange; import lombok.extern.slf4j.Slf4j; import org.apache.calcite.adapter.enumerable.EnumerableRules; import org.apache.calcite.config.CalciteConnectionConfigImpl; diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/pojo/DataSetQueryParam.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/pojo/DataSetQueryParam.java deleted file mode 100644 index e6f613651..000000000 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/pojo/DataSetQueryParam.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.tencent.supersonic.headless.core.pojo; - -import com.tencent.supersonic.headless.api.pojo.MetricTable; -import lombok.Data; - -import java.util.List; - -@Data -public class DataSetQueryParam { - private String sql = ""; - private List tables; - private boolean supportWith = true; - private boolean withAlias = true; -} diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/pojo/Database.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/pojo/Database.java index 51a908024..5227166cc 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/pojo/Database.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/pojo/Database.java @@ -2,6 +2,7 @@ package com.tencent.supersonic.headless.core.pojo; import com.google.common.collect.Lists; import com.tencent.supersonic.common.pojo.RecordInfo; +import com.tencent.supersonic.common.pojo.enums.EngineType; import com.tencent.supersonic.common.util.AESEncryptionUtil; import lombok.AllArgsConstructor; import lombok.Builder; @@ -36,7 +37,7 @@ public class Database extends RecordInfo { private String schema; /** mysql,clickhouse */ - private String type; + private EngineType type; private List admins = Lists.newArrayList(); diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/pojo/MetricQueryParam.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/pojo/MetricQueryParam.java deleted file mode 100644 index 2a3bc8b8b..000000000 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/pojo/MetricQueryParam.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.tencent.supersonic.headless.core.pojo; - -import com.tencent.supersonic.common.pojo.ColumnOrder; -import lombok.Data; - -import java.util.List; - -@Data -public class MetricQueryParam { - - private List metrics; - private List dimensions; - private String where; - private Long limit; - private List order; - private boolean nativeQuery = false; -} diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/pojo/QueryStatement.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/pojo/QueryStatement.java index 33266cc7a..8360ec944 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/pojo/QueryStatement.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/pojo/QueryStatement.java @@ -1,34 +1,25 @@ package com.tencent.supersonic.headless.core.pojo; -import com.tencent.supersonic.headless.api.pojo.QueryParam; import com.tencent.supersonic.headless.api.pojo.response.SemanticSchemaResp; -import com.tencent.supersonic.headless.core.translator.calcite.s2sql.Ontology; +import com.tencent.supersonic.headless.core.translator.parser.s2sql.Ontology; +import com.tencent.supersonic.headless.core.translator.parser.s2sql.OntologyQueryParam; import lombok.Data; import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.Triple; -import java.util.List; - @Data public class QueryStatement { private Long dataSetId; - private List modelIds; private String sql; private String errMsg; - private QueryParam queryParam; - private MetricQueryParam metricQueryParam; - private DataSetQueryParam dataSetQueryParam; + private StructQueryParam structQueryParam; + private SqlQueryParam sqlQueryParam; + private OntologyQueryParam ontologyQueryParam; private Integer status = 0; private Boolean isS2SQL = false; - private List> timeRanges; private Boolean enableOptimize = true; private Triple minMaxTime; - private String dataSetSql; - private String dataSetAlias; - private String dataSetSimplifySql; - private Boolean enableLimitWrapper = false; private Ontology ontology; private SemanticSchemaResp semanticSchemaResp; private Integer limit = 1000; @@ -41,9 +32,4 @@ public class QueryStatement { public boolean isTranslated() { return isTranslated != null && isTranslated && isOk(); } - - public QueryStatement error(String msg) { - this.setErrMsg(msg); - return this; - } } diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/pojo/SqlQueryParam.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/pojo/SqlQueryParam.java new file mode 100644 index 000000000..086397e88 --- /dev/null +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/pojo/SqlQueryParam.java @@ -0,0 +1,12 @@ +package com.tencent.supersonic.headless.core.pojo; + +import lombok.Data; + +@Data +public class SqlQueryParam { + private String sql; + private String table; + private boolean supportWith = true; + private boolean withAlias = true; + private String simplifiedSql; +} diff --git a/headless/api/src/main/java/com/tencent/supersonic/headless/api/pojo/QueryParam.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/pojo/StructQueryParam.java similarity index 57% rename from headless/api/src/main/java/com/tencent/supersonic/headless/api/pojo/QueryParam.java rename to headless/core/src/main/java/com/tencent/supersonic/headless/core/pojo/StructQueryParam.java index 401d18204..8fd129885 100644 --- a/headless/api/src/main/java/com/tencent/supersonic/headless/api/pojo/QueryParam.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/pojo/StructQueryParam.java @@ -1,21 +1,18 @@ -package com.tencent.supersonic.headless.api.pojo; +package com.tencent.supersonic.headless.core.pojo; import com.tencent.supersonic.common.pojo.Aggregator; -import com.tencent.supersonic.common.pojo.ColumnOrder; import com.tencent.supersonic.common.pojo.DateConf; import com.tencent.supersonic.common.pojo.Filter; import com.tencent.supersonic.common.pojo.Order; import com.tencent.supersonic.common.pojo.enums.QueryType; +import com.tencent.supersonic.headless.api.pojo.Param; import lombok.Data; import java.util.ArrayList; -import java.util.HashSet; import java.util.List; -import java.util.Set; @Data -public class QueryParam { - // struct +public class StructQueryParam { private List groups = new ArrayList(); private List aggregators = new ArrayList(); private List orders = new ArrayList(); @@ -24,17 +21,5 @@ public class QueryParam { private DateConf dateInfo; private Long limit = 2000L; private QueryType queryType; - private String s2SQL; - private String correctS2SQL; - private Long dataSetId; - private String dataSetName; - private Set modelIds = new HashSet<>(); private List params = new ArrayList<>(); - - // metric - private List metrics = new ArrayList(); - private List dimensions; - private String where; - private List order; - private boolean nativeQuery = false; } diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/DefaultSemanticTranslator.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/DefaultSemanticTranslator.java index a1f7a5f48..3af2e4bbc 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/DefaultSemanticTranslator.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/DefaultSemanticTranslator.java @@ -1,507 +1,95 @@ package com.tencent.supersonic.headless.core.translator; import com.tencent.supersonic.common.calcite.SqlMergeWithUtils; -import com.tencent.supersonic.common.jsqlparser.SqlRemoveHelper; -import com.tencent.supersonic.common.jsqlparser.SqlReplaceHelper; -import com.tencent.supersonic.common.jsqlparser.SqlSelectFunctionHelper; -import com.tencent.supersonic.common.jsqlparser.SqlSelectHelper; -import com.tencent.supersonic.common.pojo.Aggregator; -import com.tencent.supersonic.common.pojo.Constants; -import com.tencent.supersonic.common.pojo.enums.AggOperatorEnum; import com.tencent.supersonic.common.pojo.enums.EngineType; -import com.tencent.supersonic.common.pojo.enums.QueryType; -import com.tencent.supersonic.common.pojo.enums.TimeDimensionEnum; -import com.tencent.supersonic.common.util.StringUtil; -import com.tencent.supersonic.headless.api.pojo.Measure; -import com.tencent.supersonic.headless.api.pojo.MetricTable; -import com.tencent.supersonic.headless.api.pojo.QueryParam; -import com.tencent.supersonic.headless.api.pojo.SchemaItem; -import com.tencent.supersonic.headless.api.pojo.enums.AggOption; -import com.tencent.supersonic.headless.api.pojo.enums.MetricType; -import com.tencent.supersonic.headless.api.pojo.request.QueryStructReq; -import com.tencent.supersonic.headless.api.pojo.response.DatabaseResp; -import com.tencent.supersonic.headless.api.pojo.response.DimSchemaResp; -import com.tencent.supersonic.headless.api.pojo.response.MetricResp; -import com.tencent.supersonic.headless.api.pojo.response.MetricSchemaResp; -import com.tencent.supersonic.headless.api.pojo.response.ModelResp; -import com.tencent.supersonic.headless.api.pojo.response.SemanticSchemaResp; -import com.tencent.supersonic.headless.core.adaptor.db.DbAdaptor; -import com.tencent.supersonic.headless.core.adaptor.db.DbAdaptorFactory; -import com.tencent.supersonic.headless.core.pojo.DataSetQueryParam; -import com.tencent.supersonic.headless.core.pojo.MetricQueryParam; import com.tencent.supersonic.headless.core.pojo.QueryStatement; -import com.tencent.supersonic.headless.core.translator.calcite.s2sql.Ontology; +import com.tencent.supersonic.headless.core.pojo.SqlQueryParam; import com.tencent.supersonic.headless.core.translator.converter.QueryConverter; +import com.tencent.supersonic.headless.core.translator.optimizer.QueryOptimizer; +import com.tencent.supersonic.headless.core.translator.parser.s2sql.OntologyQueryParam; import com.tencent.supersonic.headless.core.utils.ComponentFactory; -import com.tencent.supersonic.headless.core.utils.SqlGenerateUtils; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.Pair; -import org.springframework.beans.BeanUtils; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import org.springframework.util.CollectionUtils; import java.util.ArrayList; -import java.util.Comparator; -import java.util.HashMap; -import java.util.HashSet; import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Set; import java.util.stream.Collectors; -import java.util.stream.Stream; @Component @Slf4j public class DefaultSemanticTranslator implements SemanticTranslator { - @Autowired - private SqlGenerateUtils sqlGenerateUtils; - public void translate(QueryStatement queryStatement) { if (queryStatement.isTranslated()) { return; } - try { - preprocess(queryStatement); - parse(queryStatement); - optimize(queryStatement); + for (QueryConverter converter : ComponentFactory.getQueryConverters()) { + if (converter.accept(queryStatement)) { + log.debug("QueryConverter accept [{}]", converter.getClass().getName()); + converter.convert(queryStatement); + } + } + doOntologyParse(queryStatement); + + if (StringUtils.isNotBlank(queryStatement.getSqlQueryParam().getSimplifiedSql())) { + queryStatement.setSql(queryStatement.getSqlQueryParam().getSimplifiedSql()); + } + if (StringUtils.isBlank(queryStatement.getSql())) { + throw new RuntimeException("parse exception: " + queryStatement.getErrMsg()); + } + + for (QueryOptimizer queryOptimizer : ComponentFactory.getQueryOptimizers()) { + queryOptimizer.rewrite(queryStatement); + } } catch (Exception e) { queryStatement.setErrMsg(e.getMessage()); + log.error("Failed to translate query [{}]", e.getMessage(), e); } } - private void parse(QueryStatement queryStatement) throws Exception { - QueryParam queryParam = queryStatement.getQueryParam(); - if (Objects.isNull(queryStatement.getDataSetQueryParam())) { - queryStatement.setDataSetQueryParam(new DataSetQueryParam()); - } - if (Objects.isNull(queryStatement.getMetricQueryParam())) { - queryStatement.setMetricQueryParam(new MetricQueryParam()); + private void doOntologyParse(QueryStatement queryStatement) throws Exception { + OntologyQueryParam ontologyQueryParam = queryStatement.getOntologyQueryParam(); + log.info("parse with ontology: [{}]", ontologyQueryParam); + ComponentFactory.getQueryParser().parse(queryStatement); + if (!queryStatement.isOk()) { + throw new Exception(String.format("parse ontology table [%s] error [%s]", + queryStatement.getSqlQueryParam().getTable(), queryStatement.getErrMsg())); } - log.debug("SemanticConverter before [{}]", queryParam); - for (QueryConverter headlessConverter : ComponentFactory.getQueryConverters()) { - if (headlessConverter.accept(queryStatement)) { - log.debug("SemanticConverter accept [{}]", headlessConverter.getClass().getName()); - headlessConverter.convert(queryStatement); + SqlQueryParam sqlQueryParam = queryStatement.getSqlQueryParam(); + String ontologyQuerySql = sqlQueryParam.getSql(); + String ontologyInnerTable = sqlQueryParam.getTable(); + String ontologyInnerSql = queryStatement.getSql(); + + List> tables = new ArrayList<>(); + tables.add(Pair.of(ontologyInnerTable, ontologyInnerSql)); + if (sqlQueryParam.isSupportWith()) { + EngineType engineType = queryStatement.getOntology().getDatabase().getType(); + if (!SqlMergeWithUtils.hasWith(engineType, ontologyQuerySql)) { + String withSql = "with " + tables.stream() + .map(t -> String.format("%s as (%s)", t.getLeft(), t.getRight())) + .collect(Collectors.joining(",")) + "\n" + ontologyQuerySql; + queryStatement.setSql(withSql); + } else { + List withTableList = + tables.stream().map(Pair::getLeft).collect(Collectors.toList()); + List withSqlList = + tables.stream().map(Pair::getRight).collect(Collectors.toList()); + String mergeSql = SqlMergeWithUtils.mergeWith(engineType, ontologyQuerySql, + withSqlList, withTableList); + queryStatement.setSql(mergeSql); } - } - log.debug("SemanticConverter after {} {} {}", queryParam, - queryStatement.getDataSetQueryParam(), queryStatement.getMetricQueryParam()); - - if (!queryStatement.getDataSetQueryParam().getSql().isEmpty()) { - doParse(queryStatement.getDataSetQueryParam(), queryStatement); } else { - queryStatement.getMetricQueryParam() - .setNativeQuery(queryParam.getQueryType().isNativeAggQuery()); - doParse(queryStatement, - AggOption.getAggregation(queryStatement.getMetricQueryParam().isNativeQuery())); - } - - if (StringUtils.isEmpty(queryStatement.getSql())) { - throw new RuntimeException("parse Exception: " + queryStatement.getErrMsg()); - } - if (StringUtils.isNotBlank(queryStatement.getSql()) - && !SqlSelectHelper.hasLimit(queryStatement.getSql())) { - String querySql = - queryStatement.getSql() + " limit " + queryStatement.getLimit().toString(); - queryStatement.setSql(querySql); - } - } - - private QueryStatement doParse(DataSetQueryParam dataSetQueryParam, - QueryStatement queryStatement) { - log.info("parse dataSetQuery [{}] ", dataSetQueryParam); - Ontology ontology = queryStatement.getOntology(); - EngineType engineType = EngineType.fromString(ontology.getDatabase().getType()); - try { - if (!CollectionUtils.isEmpty(dataSetQueryParam.getTables())) { - List tables = new ArrayList<>(); - boolean isSingleTable = dataSetQueryParam.getTables().size() == 1; - for (MetricTable metricTable : dataSetQueryParam.getTables()) { - QueryStatement tableSql = parserSql(metricTable, isSingleTable, - dataSetQueryParam, queryStatement); - if (isSingleTable && StringUtils.isNotBlank(tableSql.getDataSetSimplifySql())) { - queryStatement.setSql(tableSql.getDataSetSimplifySql()); - queryStatement.setDataSetQueryParam(dataSetQueryParam); - return queryStatement; - } - tables.add(new String[] {metricTable.getAlias(), tableSql.getSql()}); - } - if (!tables.isEmpty()) { - String sql; - if (dataSetQueryParam.isSupportWith()) { - if (!SqlMergeWithUtils.hasWith(engineType, dataSetQueryParam.getSql())) { - sql = "with " - + tables.stream() - .map(t -> String.format("%s as (%s)", t[0], t[1])) - .collect(Collectors.joining(",")) - + "\n" + dataSetQueryParam.getSql(); - } else { - List parentWithNameList = tables.stream().map(table -> table[0]) - .collect(Collectors.toList()); - List parentSqlList = tables.stream().map(table -> table[1]) - .collect(Collectors.toList()); - sql = SqlMergeWithUtils.mergeWith(engineType, - dataSetQueryParam.getSql(), parentSqlList, parentWithNameList); - } - } else { - sql = dataSetQueryParam.getSql(); - for (String[] tb : tables) { - sql = StringUtils.replace(sql, tb[0], "(" + tb[1] + ") " - + (dataSetQueryParam.isWithAlias() ? "" : tb[0]), -1); - } - } - queryStatement.setSql(sql); - queryStatement.setDataSetQueryParam(dataSetQueryParam); - return queryStatement; - } + for (Pair tb : tables) { + ontologyQuerySql = + StringUtils.replace(ontologyQuerySql, tb.getLeft(), "(" + tb.getRight() + + ") " + (sqlQueryParam.isWithAlias() ? "" : tb.getLeft()), -1); } - } catch (Exception e) { - log.error("physicalSql error {}", e); - queryStatement.setErrMsg(e.getMessage()); - } - return queryStatement; - } - - private QueryStatement doParse(QueryStatement queryStatement, AggOption isAgg) { - MetricQueryParam metricQueryParam = queryStatement.getMetricQueryParam(); - log.info("parse metricQuery [{}] isAgg [{}]", metricQueryParam, isAgg); - try { - ComponentFactory.getQueryParser().parse(queryStatement, isAgg); - } catch (Exception e) { - queryStatement.setErrMsg(e.getMessage()); - log.error("parser error metricQueryReq[{}] error [{}]", metricQueryParam, e); - } - return queryStatement; - } - - private QueryStatement parserSql(MetricTable metricTable, Boolean isSingleMetricTable, - DataSetQueryParam dataSetQueryParam, QueryStatement queryStatement) throws Exception { - MetricQueryParam metricQueryParam = new MetricQueryParam(); - metricQueryParam.setMetrics(metricTable.getMetrics()); - metricQueryParam.setDimensions(metricTable.getDimensions()); - metricQueryParam.setWhere(StringUtil.formatSqlQuota(metricTable.getWhere())); - metricQueryParam.setNativeQuery(!AggOption.isAgg(metricTable.getAggOption())); - - QueryStatement tableSql = new QueryStatement(); - tableSql.setIsS2SQL(false); - tableSql.setMetricQueryParam(metricQueryParam); - tableSql.setMinMaxTime(queryStatement.getMinMaxTime()); - tableSql.setEnableOptimize(queryStatement.getEnableOptimize()); - tableSql.setDataSetId(queryStatement.getDataSetId()); - tableSql.setOntology(queryStatement.getOntology()); - if (isSingleMetricTable) { - tableSql.setDataSetSql(dataSetQueryParam.getSql()); - tableSql.setDataSetAlias(metricTable.getAlias()); - } - tableSql = doParse(tableSql, metricTable.getAggOption()); - if (!tableSql.isOk()) { - throw new Exception(String.format("parser table [%s] error [%s]", - metricTable.getAlias(), tableSql.getErrMsg())); - } - return tableSql; - } - - private void optimize(QueryStatement queryStatement) { - for (QueryOptimizer queryOptimizer : ComponentFactory.getQueryOptimizers()) { - queryOptimizer.rewrite(queryStatement); + queryStatement.setSql(ontologyQuerySql); } } - private void preprocess(QueryStatement queryStatement) { - if (StringUtils.isBlank(queryStatement.getSql())) { - return; - } - SemanticSchemaResp semanticSchemaResp = queryStatement.getSemanticSchemaResp(); - - convertNameToBizName(queryStatement); - rewriteFunction(queryStatement); - queryStatement.setSql(SqlRemoveHelper.removeUnderscores(queryStatement.getSql())); - - String tableName = SqlSelectHelper.getTableName(queryStatement.getSql()); - if (StringUtils.isEmpty(tableName)) { - return; - } - // correct order item is same as agg alias - String reqSql = queryStatement.getSql(); - queryStatement.setSql(SqlReplaceHelper.replaceAggAliasOrderItem(queryStatement.getSql())); - log.debug("replaceOrderAggSameAlias {} -> {}", reqSql, queryStatement.getSql()); - // 5.build MetricTables - List allFields = SqlSelectHelper.getAllSelectFields(queryStatement.getSql()); - List metricSchemas = getMetrics(semanticSchemaResp, allFields); - List metrics = - metricSchemas.stream().map(SchemaItem::getBizName).collect(Collectors.toList()); - Set dimensions = getDimensions(semanticSchemaResp, allFields); - QueryStructReq queryStructReq = new QueryStructReq(); - - MetricTable metricTable = new MetricTable(); - metricTable.getMetrics().addAll(metrics); - metricTable.getDimensions().addAll(dimensions); - metricTable.setAlias(tableName.toLowerCase()); - // if metric empty , fill model default - if (CollectionUtils.isEmpty(metricTable.getMetrics())) { - metricTable.getMetrics().add(sqlGenerateUtils.generateInternalMetricName( - getDefaultModel(semanticSchemaResp, metricTable.getDimensions()))); - } else { - queryStructReq.getAggregators() - .addAll(metricTable.getMetrics().stream() - .map(m -> new Aggregator(m, AggOperatorEnum.UNKNOWN)) - .collect(Collectors.toList())); - } - AggOption aggOption = getAggOption(queryStatement, metricSchemas); - metricTable.setAggOption(aggOption); - List tables = new ArrayList<>(); - tables.add(metricTable); - - // 6.build ParseSqlReq - DataSetQueryParam datasetQueryParam = new DataSetQueryParam(); - datasetQueryParam.setTables(tables); - datasetQueryParam.setSql(queryStatement.getSql()); - DatabaseResp database = semanticSchemaResp.getDatabaseResp(); - if (!sqlGenerateUtils.isSupportWith(EngineType.fromString(database.getType().toUpperCase()), - database.getVersion())) { - datasetQueryParam.setSupportWith(false); - datasetQueryParam.setWithAlias(false); - } - - // 7. do deriveMetric - generateDerivedMetric(semanticSchemaResp, aggOption, datasetQueryParam); - - // 8.physicalSql by ParseSqlReq - // queryStructReq.setDateInfo(queryStructUtils.getDateConfBySql(queryStatement.getSql())); - queryStructReq.setDataSetId(queryStatement.getDataSetId()); - queryStructReq.setQueryType(getQueryType(aggOption)); - log.debug("QueryReqConverter queryStructReq[{}]", queryStructReq); - QueryParam queryParam = new QueryParam(); - BeanUtils.copyProperties(queryStructReq, queryParam); - queryStatement.setQueryParam(queryParam); - queryStatement.setDataSetQueryParam(datasetQueryParam); - // queryStatement.setMinMaxTime(queryStructUtils.getBeginEndTime(queryStructReq)); - } - - private AggOption getAggOption(QueryStatement queryStatement, - List metricSchemas) { - String sql = queryStatement.getSql(); - if (!SqlSelectFunctionHelper.hasAggregateFunction(sql) && !SqlSelectHelper.hasGroupBy(sql) - && !SqlSelectHelper.hasWith(sql) && !SqlSelectHelper.hasSubSelect(sql)) { - log.debug("getAggOption simple sql set to DEFAULT"); - return AggOption.DEFAULT; - } - // if there is no group by in S2SQL,set MetricTable's aggOption to "NATIVE" - // if there is count() in S2SQL,set MetricTable's aggOption to "NATIVE" - if (!SqlSelectFunctionHelper.hasAggregateFunction(sql) - || SqlSelectFunctionHelper.hasFunction(sql, "count") - || SqlSelectFunctionHelper.hasFunction(sql, "count_distinct")) { - return AggOption.OUTER; - } - // if (queryStatement.isInnerLayerNative()) { - // return AggOption.NATIVE; - // } - if (SqlSelectHelper.hasSubSelect(sql) || SqlSelectHelper.hasWith(sql) - || SqlSelectHelper.hasGroupBy(sql)) { - return AggOption.OUTER; - } - long defaultAggNullCnt = metricSchemas.stream().filter( - m -> Objects.isNull(m.getDefaultAgg()) || StringUtils.isBlank(m.getDefaultAgg())) - .count(); - if (defaultAggNullCnt > 0) { - log.debug("getAggOption find null defaultAgg metric set to NATIVE"); - return AggOption.OUTER; - } - return AggOption.DEFAULT; - } - - private void convertNameToBizName(QueryStatement queryStatement) { - SemanticSchemaResp semanticSchemaResp = queryStatement.getSemanticSchemaResp(); - Map fieldNameToBizNameMap = getFieldNameToBizNameMap(semanticSchemaResp); - String sql = queryStatement.getSql(); - log.debug("dataSetId:{},convert name to bizName before:{}", queryStatement.getDataSetId(), - sql); - sql = SqlReplaceHelper.replaceSqlByPositions(sql); - log.debug("replaceSqlByPositions:{}", sql); - sql = SqlReplaceHelper.replaceFields(sql, fieldNameToBizNameMap, true); - log.debug("dataSetId:{},convert name to bizName after:{}", queryStatement.getDataSetId(), - sql); - sql = SqlReplaceHelper.replaceTable(sql, - Constants.TABLE_PREFIX + queryStatement.getDataSetId()); - log.debug("replaceTableName after:{}", sql); - queryStatement.setSql(sql); - } - - private Set getDimensions(SemanticSchemaResp semanticSchemaResp, - List allFields) { - Map dimensionLowerToNameMap = semanticSchemaResp.getDimensions().stream() - .collect(Collectors.toMap(entry -> entry.getBizName().toLowerCase(), - SchemaItem::getBizName, (k1, k2) -> k1)); - dimensionLowerToNameMap.put(TimeDimensionEnum.DAY.getName(), - TimeDimensionEnum.DAY.getName()); - return allFields.stream() - .filter(entry -> dimensionLowerToNameMap.containsKey(entry.toLowerCase())) - .map(entry -> dimensionLowerToNameMap.get(entry.toLowerCase())) - .collect(Collectors.toSet()); - } - - private List getMetrics(SemanticSchemaResp semanticSchemaResp, - List allFields) { - Map metricLowerToNameMap = - semanticSchemaResp.getMetrics().stream().collect(Collectors - .toMap(entry -> entry.getBizName().toLowerCase(), entry -> entry)); - return allFields.stream() - .filter(entry -> metricLowerToNameMap.containsKey(entry.toLowerCase())) - .map(entry -> metricLowerToNameMap.get(entry.toLowerCase())) - .collect(Collectors.toList()); - } - - private void rewriteFunction(QueryStatement queryStatement) { - SemanticSchemaResp semanticSchemaResp = queryStatement.getSemanticSchemaResp(); - DatabaseResp database = semanticSchemaResp.getDatabaseResp(); - if (Objects.isNull(database) || Objects.isNull(database.getType())) { - return; - } - String type = database.getType(); - DbAdaptor engineAdaptor = DbAdaptorFactory.getEngineAdaptor(type.toLowerCase()); - if (Objects.nonNull(engineAdaptor)) { - String functionNameCorrector = - engineAdaptor.functionNameCorrector(queryStatement.getSql()); - queryStatement.setSql(functionNameCorrector); - } - } - - protected Map getFieldNameToBizNameMap(SemanticSchemaResp semanticSchemaResp) { - // support fieldName and field alias to bizName - Map dimensionResults = semanticSchemaResp.getDimensions().stream().flatMap( - entry -> getPairStream(entry.getAlias(), entry.getName(), entry.getBizName())) - .collect(Collectors.toMap(Pair::getLeft, Pair::getRight, (k1, k2) -> k1)); - - Map metricResults = semanticSchemaResp.getMetrics().stream().flatMap( - entry -> getPairStream(entry.getAlias(), entry.getName(), entry.getBizName())) - .collect(Collectors.toMap(Pair::getLeft, Pair::getRight, (k1, k2) -> k1)); - - dimensionResults.putAll(TimeDimensionEnum.getChNameToNameMap()); - dimensionResults.putAll(TimeDimensionEnum.getNameToNameMap()); - dimensionResults.putAll(metricResults); - return dimensionResults; - } - - private Stream> getPairStream(String aliasStr, String name, - String bizName) { - Set> elements = new HashSet<>(); - elements.add(Pair.of(name, bizName)); - if (StringUtils.isNotBlank(aliasStr)) { - List aliasList = SchemaItem.getAliasList(aliasStr); - for (String alias : aliasList) { - elements.add(Pair.of(alias, bizName)); - } - } - return elements.stream(); - } - - private QueryType getQueryType(AggOption aggOption) { - boolean isAgg = AggOption.isAgg(aggOption); - QueryType queryType = QueryType.DETAIL; - if (isAgg) { - queryType = QueryType.AGGREGATE; - } - return queryType; - } - - private void generateDerivedMetric(SemanticSchemaResp semanticSchemaResp, AggOption aggOption, - DataSetQueryParam viewQueryParam) { - String sql = viewQueryParam.getSql(); - for (MetricTable metricTable : viewQueryParam.getTables()) { - Set measures = new HashSet<>(); - Map replaces = generateDerivedMetric(semanticSchemaResp, aggOption, - metricTable.getMetrics(), metricTable.getDimensions(), measures); - - if (!CollectionUtils.isEmpty(replaces)) { - // metricTable sql use measures replace metric - sql = SqlReplaceHelper.replaceSqlByExpression(sql, replaces); - metricTable.setAggOption(AggOption.NATIVE); - // metricTable use measures replace metric - if (!CollectionUtils.isEmpty(measures)) { - metricTable.setMetrics(new ArrayList<>(measures)); - } else { - // empty measure , fill default - metricTable.setMetrics(new ArrayList<>()); - metricTable.getMetrics().add(sqlGenerateUtils.generateInternalMetricName( - getDefaultModel(semanticSchemaResp, metricTable.getDimensions()))); - } - } - } - viewQueryParam.setSql(sql); - } - - private Map generateDerivedMetric(SemanticSchemaResp semanticSchemaResp, - AggOption aggOption, List metrics, List dimensions, - Set measures) { - Map result = new HashMap<>(); - List metricResps = semanticSchemaResp.getMetrics(); - List dimensionResps = semanticSchemaResp.getDimensions(); - - // Check if any metric is derived - boolean hasDerivedMetrics = - metricResps.stream().anyMatch(m -> metrics.contains(m.getBizName()) && MetricType - .isDerived(m.getMetricDefineType(), m.getMetricDefineByMeasureParams())); - if (!hasDerivedMetrics) { - return result; - } - - log.debug("begin to generateDerivedMetric {} [{}]", aggOption, metrics); - - Set allFields = new HashSet<>(); - Map allMeasures = new HashMap<>(); - semanticSchemaResp.getModelResps().forEach(modelResp -> { - allFields.addAll(modelResp.getFieldList()); - if (modelResp.getModelDetail().getMeasures() != null) { - modelResp.getModelDetail().getMeasures() - .forEach(measure -> allMeasures.put(measure.getBizName(), measure)); - } - }); - - Set derivedDimensions = new HashSet<>(); - Set derivedMetrics = new HashSet<>(); - Map visitedMetrics = new HashMap<>(); - - for (MetricResp metricResp : metricResps) { - if (metrics.contains(metricResp.getBizName())) { - boolean isDerived = MetricType.isDerived(metricResp.getMetricDefineType(), - metricResp.getMetricDefineByMeasureParams()); - if (isDerived) { - String expr = sqlGenerateUtils.generateDerivedMetric(metricResps, allFields, - allMeasures, dimensionResps, sqlGenerateUtils.getExpr(metricResp), - metricResp.getMetricDefineType(), aggOption, visitedMetrics, - derivedMetrics, derivedDimensions); - result.put(metricResp.getBizName(), expr); - log.debug("derived metric {}->{}", metricResp.getBizName(), expr); - } else { - measures.add(metricResp.getBizName()); - } - } - } - - measures.addAll(derivedMetrics); - derivedDimensions.stream().filter(dimension -> !dimensions.contains(dimension)) - .forEach(dimensions::add); - - return result; - } - - private String getDefaultModel(SemanticSchemaResp semanticSchemaResp, List dimensions) { - if (!CollectionUtils.isEmpty(dimensions)) { - Map modelMatchCnt = new HashMap<>(); - for (ModelResp modelResp : semanticSchemaResp.getModelResps()) { - modelMatchCnt.put(modelResp.getBizName(), modelResp.getModelDetail().getDimensions() - .stream().filter(d -> dimensions.contains(d.getBizName())).count()); - } - return modelMatchCnt.entrySet().stream() - .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())) - .map(m -> m.getKey()).findFirst().orElse(""); - } - return semanticSchemaResp.getModelResps().get(0).getBizName(); - } } diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/DetailQueryOptimizer.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/DetailQueryOptimizer.java deleted file mode 100644 index bf84cbb2b..000000000 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/DetailQueryOptimizer.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.tencent.supersonic.headless.core.translator; - -import com.tencent.supersonic.headless.api.pojo.QueryParam; -import com.tencent.supersonic.headless.core.pojo.QueryStatement; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; -import org.springframework.stereotype.Component; -import org.springframework.util.CollectionUtils; - -import java.util.Objects; -import java.util.stream.Collectors; - -/** Remove the default metric added by the system when the query only has dimensions */ -@Slf4j -@Component("DetailQueryOptimizer") -public class DetailQueryOptimizer implements QueryOptimizer { - - @Override - public void rewrite(QueryStatement queryStatement) { - QueryParam queryParam = queryStatement.getQueryParam(); - String sqlRaw = queryStatement.getSql().trim(); - if (StringUtils.isEmpty(sqlRaw)) { - throw new RuntimeException("sql is empty or null"); - } - log.debug("before handleNoMetric, sql:{}", sqlRaw); - if (isDetailQuery(queryParam)) { - if (queryParam.getMetrics().size() == 0 - && !CollectionUtils.isEmpty(queryParam.getGroups())) { - String sqlForm = "select %s from ( %s ) src_no_metric"; - String sql = String.format(sqlForm, - queryParam.getGroups().stream().collect(Collectors.joining(",")), sqlRaw); - queryStatement.setSql(sql); - } - } - log.debug("after handleNoMetric, sql:{}", queryStatement.getSql()); - } - - public boolean isDetailQuery(QueryParam queryParam) { - return Objects.nonNull(queryParam) && queryParam.getQueryType().isNativeAggQuery() - && CollectionUtils.isEmpty(queryParam.getMetrics()); - } -} diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/QueryParser.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/QueryParser.java deleted file mode 100644 index b15212c65..000000000 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/QueryParser.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.tencent.supersonic.headless.core.translator; - -import com.tencent.supersonic.headless.api.pojo.enums.AggOption; -import com.tencent.supersonic.headless.core.pojo.QueryStatement; - -/** A query parser generates physical SQL for the QueryStatement. */ -public interface QueryParser { - void parse(QueryStatement queryStatement, AggOption aggOption) throws Exception; -} diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/SqlBuilder.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/SqlBuilder.java deleted file mode 100644 index 971886ed4..000000000 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/SqlBuilder.java +++ /dev/null @@ -1,176 +0,0 @@ -package com.tencent.supersonic.headless.core.translator.calcite.sql; - -import com.tencent.supersonic.common.calcite.Configuration; -import com.tencent.supersonic.common.calcite.SqlMergeWithUtils; -import com.tencent.supersonic.common.pojo.enums.EngineType; -import com.tencent.supersonic.headless.api.pojo.enums.AggOption; -import com.tencent.supersonic.headless.core.pojo.Database; -import com.tencent.supersonic.headless.core.pojo.MetricQueryParam; -import com.tencent.supersonic.headless.core.pojo.QueryStatement; -import com.tencent.supersonic.headless.core.translator.calcite.s2sql.Constants; -import com.tencent.supersonic.headless.core.translator.calcite.s2sql.DataModel; -import com.tencent.supersonic.headless.core.translator.calcite.sql.node.DataModelNode; -import com.tencent.supersonic.headless.core.translator.calcite.sql.node.SemanticNode; -import com.tencent.supersonic.headless.core.translator.calcite.sql.render.FilterRender; -import com.tencent.supersonic.headless.core.translator.calcite.sql.render.OutputRender; -import com.tencent.supersonic.headless.core.translator.calcite.sql.render.Renderer; -import com.tencent.supersonic.headless.core.translator.calcite.sql.render.SourceRender; -import lombok.extern.slf4j.Slf4j; -import org.apache.calcite.sql.SqlNode; -import org.apache.calcite.sql.parser.SqlParseException; -import org.apache.calcite.sql.parser.SqlParser; -import org.apache.calcite.sql.validate.SqlValidatorScope; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; -import java.util.ListIterator; -import java.util.Objects; - -/** parsing from query dimensions and metrics */ -@Slf4j -public class SqlBuilder { - - private final S2CalciteSchema schema; - private MetricQueryParam metricQueryParam; - private SqlValidatorScope scope; - private SqlNode parserNode; - private boolean isAgg = false; - private AggOption aggOption = AggOption.DEFAULT; - - public SqlBuilder(S2CalciteSchema schema) { - this.schema = schema; - } - - public void build(QueryStatement queryStatement, AggOption aggOption) throws Exception { - this.metricQueryParam = queryStatement.getMetricQueryParam(); - if (metricQueryParam.getMetrics() == null) { - metricQueryParam.setMetrics(new ArrayList<>()); - } - if (metricQueryParam.getDimensions() == null) { - metricQueryParam.setDimensions(new ArrayList<>()); - } - if (metricQueryParam.getLimit() == null) { - metricQueryParam.setLimit(0L); - } - this.aggOption = aggOption; - - buildParseNode(); - Database database = queryStatement.getOntology().getDatabase(); - EngineType engineType = EngineType.fromString(database.getType()); - optimizeParseNode(engineType); - String sql = getSql(engineType); - - queryStatement.setSql(sql); - if (Objects.nonNull(queryStatement.getEnableOptimize()) - && queryStatement.getEnableOptimize() - && Objects.nonNull(queryStatement.getDataSetAlias()) - && !queryStatement.getDataSetAlias().isEmpty()) { - // simplify model sql with query sql - String simplifySql = rewrite(getSqlByDataSet(engineType, sql, - queryStatement.getDataSetSql(), queryStatement.getDataSetAlias()), engineType); - if (Objects.nonNull(simplifySql) && !simplifySql.isEmpty()) { - log.debug("simplifySql [{}]", simplifySql); - queryStatement.setDataSetSimplifySql(simplifySql); - } - } - } - - private void buildParseNode() throws Exception { - // find the match Datasource - scope = SchemaBuilder.getScope(schema); - List dataModels = - DataModelNode.getRelatedDataModels(scope, schema, metricQueryParam); - if (dataModels == null || dataModels.isEmpty()) { - throw new Exception("data model not found"); - } - isAgg = getAgg(dataModels.get(0)); - - // build level by level - LinkedList builders = new LinkedList<>(); - builders.add(new SourceRender()); - builders.add(new FilterRender()); - builders.add(new OutputRender()); - ListIterator it = builders.listIterator(); - int i = 0; - Renderer previous = null; - while (it.hasNext()) { - Renderer renderer = it.next(); - if (previous != null) { - previous.render(metricQueryParam, dataModels, scope, schema, !isAgg); - renderer.setTable(previous - .builderAs(DataModelNode.getNames(dataModels) + "_" + String.valueOf(i))); - i++; - } - previous = renderer; - } - builders.getLast().render(metricQueryParam, dataModels, scope, schema, !isAgg); - parserNode = builders.getLast().builder(); - } - - private boolean getAgg(DataModel dataModel) { - if (!AggOption.DEFAULT.equals(aggOption)) { - return AggOption.isAgg(aggOption); - } - // default by dataModel time aggregation - if (Objects.nonNull(dataModel.getAggTime()) && !dataModel.getAggTime() - .equalsIgnoreCase(Constants.DIMENSION_TYPE_TIME_GRANULARITY_NONE)) { - if (!metricQueryParam.isNativeQuery()) { - return true; - } - } - return isAgg; - } - - public String getSql(EngineType engineType) { - return SemanticNode.getSql(parserNode, engineType); - } - - private String rewrite(String sql, EngineType engineType) { - try { - SqlNode sqlNode = - SqlParser.create(sql, Configuration.getParserConfig(engineType)).parseStmt(); - if (Objects.nonNull(sqlNode)) { - return SemanticNode.getSql( - SemanticNode.optimize(scope, schema, sqlNode, engineType), engineType); - } - } catch (Exception e) { - log.error("optimize error {}", e.toString()); - } - return ""; - } - - private void optimizeParseNode(EngineType engineType) { - if (Objects.isNull(schema.getRuntimeOptions()) - || Objects.isNull(schema.getRuntimeOptions().getEnableOptimize()) - || !schema.getRuntimeOptions().getEnableOptimize()) { - return; - } - - SqlNode optimizeNode = null; - try { - SqlNode sqlNode = SqlParser.create(SemanticNode.getSql(parserNode, engineType), - Configuration.getParserConfig(engineType)).parseStmt(); - if (Objects.nonNull(sqlNode)) { - optimizeNode = SemanticNode.optimize(scope, schema, sqlNode, engineType); - } - } catch (Exception e) { - log.error("optimize error {}", e); - } - - if (Objects.nonNull(optimizeNode)) { - parserNode = optimizeNode; - } - } - - private String getSqlByDataSet(EngineType engineType, String parentSql, String dataSetSql, - String parentAlias) throws SqlParseException { - if (!SqlMergeWithUtils.hasWith(engineType, dataSetSql)) { - return String.format("with %s as (%s) %s", parentAlias, parentSql, dataSetSql); - } - return SqlMergeWithUtils.mergeWith(engineType, dataSetSql, - Collections.singletonList(parentSql), Collections.singletonList(parentAlias)); - } - -} diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/converter/DefaultDimValueConverter.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/converter/DefaultDimValueConverter.java index 54b24dd84..46f3494b5 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/converter/DefaultDimValueConverter.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/converter/DefaultDimValueConverter.java @@ -4,9 +4,8 @@ import com.google.common.collect.Lists; import com.tencent.supersonic.common.jsqlparser.SqlAddHelper; import com.tencent.supersonic.common.jsqlparser.SqlSelectHelper; import com.tencent.supersonic.common.pojo.enums.TimeDimensionEnum; -import com.tencent.supersonic.headless.api.pojo.MetricTable; import com.tencent.supersonic.headless.core.pojo.QueryStatement; -import com.tencent.supersonic.headless.core.translator.calcite.s2sql.Dimension; +import com.tencent.supersonic.headless.core.translator.parser.s2sql.Dimension; import lombok.extern.slf4j.Slf4j; import net.sf.jsqlparser.expression.Expression; import net.sf.jsqlparser.expression.StringValue; @@ -28,8 +27,8 @@ public class DefaultDimValueConverter implements QueryConverter { @Override public boolean accept(QueryStatement queryStatement) { - return !Objects.isNull(queryStatement.getDataSetQueryParam()) - && !StringUtils.isBlank(queryStatement.getDataSetQueryParam().getSql()); + return Objects.nonNull(queryStatement.getSqlQueryParam()) + && StringUtils.isNotBlank(queryStatement.getSqlQueryParam().getSql()); } @Override @@ -40,15 +39,13 @@ public class DefaultDimValueConverter implements QueryConverter { if (CollectionUtils.isEmpty(dimensions)) { return; } - String sql = queryStatement.getDataSetQueryParam().getSql(); + String sql = queryStatement.getSqlQueryParam().getSql(); List whereFields = SqlSelectHelper.getWhereFields(sql).stream() .filter(field -> !TimeDimensionEnum.containsTimeDimension(field)) .collect(Collectors.toList()); if (!CollectionUtils.isEmpty(whereFields)) { return; } - MetricTable metricTable = - queryStatement.getDataSetQueryParam().getTables().stream().findFirst().orElse(null); List expressions = Lists.newArrayList(); for (Dimension dimension : dimensions) { ExpressionList expressionList = new ExpressionList(); @@ -59,11 +56,11 @@ public class DefaultDimValueConverter implements QueryConverter { inExpression.setLeftExpression(new Column(dimension.getBizName())); inExpression.setRightExpression(expressionList); expressions.add(inExpression); - if (metricTable != null) { - metricTable.getDimensions().add(dimension.getBizName()); + if (Objects.nonNull(queryStatement.getSqlQueryParam().getTable())) { + queryStatement.getOntologyQueryParam().getDimensions().add(dimension.getBizName()); } } sql = SqlAddHelper.addWhere(sql, expressions); - queryStatement.getDataSetQueryParam().setSql(sql); + queryStatement.getSqlQueryParam().setSql(sql); } } diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/converter/CalculateAggConverter.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/converter/MetricRatioConverter.java similarity index 50% rename from headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/converter/CalculateAggConverter.java rename to headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/converter/MetricRatioConverter.java index e0287e427..5bc209587 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/converter/CalculateAggConverter.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/converter/MetricRatioConverter.java @@ -6,82 +6,46 @@ import com.tencent.supersonic.common.pojo.enums.DatePeriodEnum; import com.tencent.supersonic.common.pojo.enums.EngineType; import com.tencent.supersonic.common.util.ContextUtils; import com.tencent.supersonic.common.util.DateModeUtils; -import com.tencent.supersonic.headless.api.pojo.MetricTable; -import com.tencent.supersonic.headless.api.pojo.QueryParam; import com.tencent.supersonic.headless.api.pojo.enums.AggOption; -import com.tencent.supersonic.headless.core.pojo.DataSetQueryParam; import com.tencent.supersonic.headless.core.pojo.Database; import com.tencent.supersonic.headless.core.pojo.QueryStatement; +import com.tencent.supersonic.headless.core.pojo.SqlQueryParam; +import com.tencent.supersonic.headless.core.pojo.StructQueryParam; +import com.tencent.supersonic.headless.core.translator.parser.s2sql.OntologyQueryParam; import com.tencent.supersonic.headless.core.utils.SqlGenerateUtils; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.stream.Collectors; -/** supplement the QueryStatement when query with custom aggregation method */ @Component("CalculateAggConverter") @Slf4j -public class CalculateAggConverter implements QueryConverter { +public class MetricRatioConverter implements QueryConverter { public interface EngineSql { - String sql(QueryParam queryParam, boolean isOver, boolean asWith, String metricSql); - } - - public DataSetQueryParam generateSqlCommend(QueryStatement queryStatement, - EngineType engineTypeEnum, String version) throws Exception { - SqlGenerateUtils sqlGenerateUtils = ContextUtils.getBean(SqlGenerateUtils.class); - QueryParam queryParam = queryStatement.getQueryParam(); - // 同环比 - if (isRatioAccept(queryParam)) { - return generateRatioSqlCommand(queryStatement, engineTypeEnum, version); - } - DataSetQueryParam sqlCommand = new DataSetQueryParam(); - String metricTableName = "v_metric_tb_tmp"; - MetricTable metricTable = new MetricTable(); - metricTable.setAlias(metricTableName); - metricTable.setMetrics(queryParam.getMetrics()); - metricTable.setDimensions(queryParam.getGroups()); - String where = sqlGenerateUtils.generateWhere(queryParam, null); - log.info("in generateSqlCommand, complete where:{}", where); - metricTable.setWhere(where); - metricTable.setAggOption(AggOption.AGGREGATION); - sqlCommand.setTables(new ArrayList<>(Collections.singletonList(metricTable))); - String sql = String.format("select %s from %s %s %s %s", - sqlGenerateUtils.getSelect(queryParam), metricTableName, - sqlGenerateUtils.getGroupBy(queryParam), sqlGenerateUtils.getOrderBy(queryParam), - sqlGenerateUtils.getLimit(queryParam)); - if (!sqlGenerateUtils.isSupportWith(engineTypeEnum, version)) { - sqlCommand.setSupportWith(false); - sql = String.format("select %s from %s t0 %s %s %s", - sqlGenerateUtils.getSelect(queryParam), metricTableName, - sqlGenerateUtils.getGroupBy(queryParam), - sqlGenerateUtils.getOrderBy(queryParam), sqlGenerateUtils.getLimit(queryParam)); - } - sqlCommand.setSql(sql); - return sqlCommand; + String sql(StructQueryParam structQueryParam, boolean isOver, boolean asWith, + String metricSql); } @Override public boolean accept(QueryStatement queryStatement) { - if (Objects.isNull(queryStatement.getQueryParam()) || queryStatement.getIsS2SQL()) { + if (Objects.isNull(queryStatement.getStructQueryParam()) || queryStatement.getIsS2SQL() + || !isRatioAccept(queryStatement.getStructQueryParam())) { return false; } - QueryParam queryParam = queryStatement.getQueryParam(); - if (queryParam.getQueryType().isNativeAggQuery()) { - return false; - } - if (CollectionUtils.isEmpty(queryParam.getAggregators())) { + StructQueryParam structQueryParam = queryStatement.getStructQueryParam(); + if (structQueryParam.getQueryType().isNativeAggQuery() + || CollectionUtils.isEmpty(structQueryParam.getAggregators())) { return false; } int nonSumFunction = 0; - for (Aggregator agg : queryParam.getAggregators()) { + for (Aggregator agg : structQueryParam.getAggregators()) { if (agg.getFunc() == null || "".equals(agg.getFunc())) { return false; } @@ -98,14 +62,12 @@ public class CalculateAggConverter implements QueryConverter { @Override public void convert(QueryStatement queryStatement) throws Exception { Database database = queryStatement.getOntology().getDatabase(); - DataSetQueryParam dataSetQueryParam = generateSqlCommend(queryStatement, - EngineType.fromString(database.getType().toUpperCase()), database.getVersion()); - queryStatement.setDataSetQueryParam(dataSetQueryParam); + generateRatioSql(queryStatement, database.getType(), database.getVersion()); } /** Ratio */ - public boolean isRatioAccept(QueryParam queryParam) { - Long ratioFuncNum = queryParam.getAggregators().stream() + public boolean isRatioAccept(StructQueryParam structQueryParam) { + Long ratioFuncNum = structQueryParam.getAggregators().stream() .filter(f -> (f.getFunc().equals(AggOperatorEnum.RATIO_ROLL) || f.getFunc().equals(AggOperatorEnum.RATIO_OVER))) .count(); @@ -115,53 +77,47 @@ public class CalculateAggConverter implements QueryConverter { return false; } - public DataSetQueryParam generateRatioSqlCommand(QueryStatement queryStatement, - EngineType engineTypeEnum, String version) throws Exception { + public void generateRatioSql(QueryStatement queryStatement, EngineType engineTypeEnum, + String version) throws Exception { SqlGenerateUtils sqlGenerateUtils = ContextUtils.getBean(SqlGenerateUtils.class); - QueryParam queryParam = queryStatement.getQueryParam(); - check(queryParam); + StructQueryParam structQueryParam = queryStatement.getStructQueryParam(); + check(structQueryParam); queryStatement.setEnableOptimize(false); - DataSetQueryParam sqlCommand = new DataSetQueryParam(); + OntologyQueryParam ontologyQueryParam = queryStatement.getOntologyQueryParam(); + ontologyQueryParam.setAggOption(AggOption.AGGREGATION); String metricTableName = "v_metric_tb_tmp"; - MetricTable metricTable = new MetricTable(); - metricTable.setAlias(metricTableName); - metricTable.setMetrics(queryParam.getMetrics()); - metricTable.setDimensions(queryParam.getGroups()); - String where = sqlGenerateUtils.generateWhere(queryParam, null); - log.info("in generateSqlCommend, complete where:{}", where); - metricTable.setWhere(where); - metricTable.setAggOption(AggOption.AGGREGATION); - sqlCommand.setTables(new ArrayList<>(Collections.singletonList(metricTable))); - boolean isOver = isOverRatio(queryParam); + boolean isOver = isOverRatio(structQueryParam); String sql = ""; + + SqlQueryParam dsParam = queryStatement.getSqlQueryParam(); + dsParam.setTable(metricTableName); switch (engineTypeEnum) { case H2: - sql = new H2EngineSql().sql(queryParam, isOver, true, metricTableName); + sql = new H2EngineSql().sql(structQueryParam, isOver, true, metricTableName); break; case MYSQL: case DORIS: case CLICKHOUSE: if (!sqlGenerateUtils.isSupportWith(engineTypeEnum, version)) { - sqlCommand.setSupportWith(false); + dsParam.setSupportWith(false); } if (!engineTypeEnum.equals(engineTypeEnum.CLICKHOUSE)) { - sql = new MysqlEngineSql().sql(queryParam, isOver, sqlCommand.isSupportWith(), - metricTableName); + sql = new MysqlEngineSql().sql(structQueryParam, isOver, + dsParam.isSupportWith(), metricTableName); } else { - sql = new CkEngineSql().sql(queryParam, isOver, sqlCommand.isSupportWith(), + sql = new CkEngineSql().sql(structQueryParam, isOver, dsParam.isSupportWith(), metricTableName); } break; default: } - sqlCommand.setSql(sql); - return sqlCommand; + dsParam.setSql(sql); } public class H2EngineSql implements EngineSql { - public String getOverSelect(QueryParam queryParam, boolean isOver) { - String aggStr = queryParam.getAggregators().stream().map(f -> { + public String getOverSelect(StructQueryParam structQueryParam, boolean isOver) { + String aggStr = structQueryParam.getAggregators().stream().map(f -> { if (f.getFunc().equals(AggOperatorEnum.RATIO_OVER) || f.getFunc().equals(AggOperatorEnum.RATIO_ROLL)) { return String.format("( (%s-%s_roll)/cast(%s_roll as DOUBLE) ) as %s_%s,%s", @@ -171,43 +127,44 @@ public class CalculateAggConverter implements QueryConverter { return f.getColumn(); } }).collect(Collectors.joining(",")); - return CollectionUtils.isEmpty(queryParam.getGroups()) ? aggStr - : String.join(",", queryParam.getGroups()) + "," + aggStr; + return CollectionUtils.isEmpty(structQueryParam.getGroups()) ? aggStr + : String.join(",", structQueryParam.getGroups()) + "," + aggStr; } - public String getTimeSpan(QueryParam queryParam, boolean isOver, boolean isAdd) { - if (Objects.nonNull(queryParam.getDateInfo())) { + public String getTimeSpan(StructQueryParam structQueryParam, boolean isOver, + boolean isAdd) { + if (Objects.nonNull(structQueryParam.getDateInfo())) { String addStr = isAdd ? "" : "-"; - if (queryParam.getDateInfo().getPeriod().equals(DatePeriodEnum.DAY)) { + if (structQueryParam.getDateInfo().getPeriod().equals(DatePeriodEnum.DAY)) { return "day," + (isOver ? addStr + "7" : addStr + "1"); } - if (queryParam.getDateInfo().getPeriod().equals(DatePeriodEnum.MONTH)) { + if (structQueryParam.getDateInfo().getPeriod().equals(DatePeriodEnum.MONTH)) { return isOver ? "month," + addStr + "1" : "day," + addStr + "7"; } - if (queryParam.getDateInfo().getPeriod().equals(DatePeriodEnum.MONTH.MONTH)) { + if (structQueryParam.getDateInfo().getPeriod().equals(DatePeriodEnum.MONTH.MONTH)) { return isOver ? "year," + addStr + "1" : "month," + addStr + "1"; } } return ""; } - public String getJoinOn(QueryParam queryParam, boolean isOver, String aliasLeft, + public String getJoinOn(StructQueryParam structQueryParam, boolean isOver, String aliasLeft, String aliasRight) { - String timeDim = getTimeDim(queryParam); - String timeSpan = getTimeSpan(queryParam, isOver, true); - String aggStr = queryParam.getAggregators().stream().map(f -> { + String timeDim = getTimeDim(structQueryParam); + String timeSpan = getTimeSpan(structQueryParam, isOver, true); + String aggStr = structQueryParam.getAggregators().stream().map(f -> { if (f.getFunc().equals(AggOperatorEnum.RATIO_OVER) || f.getFunc().equals(AggOperatorEnum.RATIO_ROLL)) { - if (queryParam.getDateInfo().getPeriod().equals(DatePeriodEnum.MONTH)) { + if (structQueryParam.getDateInfo().getPeriod().equals(DatePeriodEnum.MONTH)) { return String.format( "%s is not null and %s = FORMATDATETIME(DATEADD(%s,CONCAT(%s,'-01')),'yyyy-MM') ", aliasRight + timeDim, aliasLeft + timeDim, timeSpan, aliasRight + timeDim); } - if (queryParam.getDateInfo().getPeriod().equals(DatePeriodEnum.WEEK) + if (structQueryParam.getDateInfo().getPeriod().equals(DatePeriodEnum.WEEK) && isOver) { return String.format(" DATE_TRUNC('week',DATEADD(%s,%s) ) = %s ", - getTimeSpan(queryParam, isOver, false), aliasLeft + timeDim, + getTimeSpan(structQueryParam, isOver, false), aliasLeft + timeDim, aliasRight + timeDim); } return String.format("%s = TIMESTAMPADD(%s,%s) ", aliasLeft + timeDim, timeSpan, @@ -217,7 +174,7 @@ public class CalculateAggConverter implements QueryConverter { } }).collect(Collectors.joining(" and ")); List groups = new ArrayList<>(); - for (String group : queryParam.getGroups()) { + for (String group : structQueryParam.getGroups()) { if (group.equalsIgnoreCase(timeDim)) { continue; } @@ -228,35 +185,36 @@ public class CalculateAggConverter implements QueryConverter { } @Override - public String sql(QueryParam queryParam, boolean isOver, boolean asWith, String metricSql) { + public String sql(StructQueryParam structQueryParam, boolean isOver, boolean asWith, + String metricSql) { String sql = String.format( "select %s from ( select %s , %s from %s t0 left join %s t1 on %s ) metric_tb_src %s %s ", - getOverSelect(queryParam, isOver), getAllSelect(queryParam, "t0."), - getAllJoinSelect(queryParam, "t1."), metricSql, metricSql, - getJoinOn(queryParam, isOver, "t0.", "t1."), getOrderBy(queryParam), - getLimit(queryParam)); + getOverSelect(structQueryParam, isOver), getAllSelect(structQueryParam, "t0."), + getAllJoinSelect(structQueryParam, "t1."), metricSql, metricSql, + getJoinOn(structQueryParam, isOver, "t0.", "t1."), getOrderBy(structQueryParam), + getLimit(structQueryParam)); return sql; } } public class CkEngineSql extends MysqlEngineSql { - public String getJoinOn(QueryParam queryParam, boolean isOver, String aliasLeft, + public String getJoinOn(StructQueryParam structQueryParam, boolean isOver, String aliasLeft, String aliasRight) { - String timeDim = getTimeDim(queryParam); - String timeSpan = "INTERVAL " + getTimeSpan(queryParam, isOver, true); - String aggStr = queryParam.getAggregators().stream().map(f -> { + String timeDim = getTimeDim(structQueryParam); + String timeSpan = "INTERVAL " + getTimeSpan(structQueryParam, isOver, true); + String aggStr = structQueryParam.getAggregators().stream().map(f -> { if (f.getFunc().equals(AggOperatorEnum.RATIO_OVER) || f.getFunc().equals(AggOperatorEnum.RATIO_ROLL)) { - if (queryParam.getDateInfo().getPeriod().equals(DatePeriodEnum.MONTH)) { + if (structQueryParam.getDateInfo().getPeriod().equals(DatePeriodEnum.MONTH)) { return String.format( "toDate(CONCAT(%s,'-01')) = date_add(toDate(CONCAT(%s,'-01')),%s) ", aliasLeft + timeDim, aliasRight + timeDim, timeSpan); } - if (queryParam.getDateInfo().getPeriod().equals(DatePeriodEnum.WEEK) + if (structQueryParam.getDateInfo().getPeriod().equals(DatePeriodEnum.WEEK) && isOver) { return String.format("toMonday(date_add(%s ,INTERVAL %s) ) = %s", - aliasLeft + timeDim, getTimeSpan(queryParam, isOver, false), + aliasLeft + timeDim, getTimeSpan(structQueryParam, isOver, false), aliasRight + timeDim); } return String.format("%s = date_add(%s,%s) ", aliasLeft + timeDim, @@ -266,7 +224,7 @@ public class CalculateAggConverter implements QueryConverter { } }).collect(Collectors.joining(" and ")); List groups = new ArrayList<>(); - for (String group : queryParam.getGroups()) { + for (String group : structQueryParam.getGroups()) { if (group.equalsIgnoreCase(timeDim)) { continue; } @@ -277,45 +235,49 @@ public class CalculateAggConverter implements QueryConverter { } @Override - public String sql(QueryParam queryParam, boolean isOver, boolean asWith, String metricSql) { + public String sql(StructQueryParam structQueryParam, boolean isOver, boolean asWith, + String metricSql) { if (!asWith) { return String.format( "select %s from ( select %s , %s from %s t0 left join %s t1 on %s ) metric_tb_src %s %s ", - getOverSelect(queryParam, isOver), getAllSelect(queryParam, "t0."), - getAllJoinSelect(queryParam, "t1."), metricSql, metricSql, - getJoinOn(queryParam, isOver, "t0.", "t1."), getOrderBy(queryParam), - getLimit(queryParam)); + getOverSelect(structQueryParam, isOver), + getAllSelect(structQueryParam, "t0."), + getAllJoinSelect(structQueryParam, "t1."), metricSql, metricSql, + getJoinOn(structQueryParam, isOver, "t0.", "t1."), + getOrderBy(structQueryParam), getLimit(structQueryParam)); } return String.format( ",t0 as (select * from %s),t1 as (select * from %s) select %s from ( select %s , %s " + "from t0 left join t1 on %s ) metric_tb_src %s %s ", - metricSql, metricSql, getOverSelect(queryParam, isOver), - getAllSelect(queryParam, "t0."), getAllJoinSelect(queryParam, "t1."), - getJoinOn(queryParam, isOver, "t0.", "t1."), getOrderBy(queryParam), - getLimit(queryParam)); + metricSql, metricSql, getOverSelect(structQueryParam, isOver), + getAllSelect(structQueryParam, "t0."), + getAllJoinSelect(structQueryParam, "t1."), + getJoinOn(structQueryParam, isOver, "t0.", "t1."), getOrderBy(structQueryParam), + getLimit(structQueryParam)); } } public class MysqlEngineSql implements EngineSql { - public String getTimeSpan(QueryParam queryParam, boolean isOver, boolean isAdd) { - if (Objects.nonNull(queryParam.getDateInfo())) { + public String getTimeSpan(StructQueryParam structQueryParam, boolean isOver, + boolean isAdd) { + if (Objects.nonNull(structQueryParam.getDateInfo())) { String addStr = isAdd ? "" : "-"; - if (queryParam.getDateInfo().getPeriod().equals(DatePeriodEnum.DAY)) { + if (structQueryParam.getDateInfo().getPeriod().equals(DatePeriodEnum.DAY)) { return isOver ? addStr + "7 day" : addStr + "1 day"; } - if (queryParam.getDateInfo().getPeriod().equals(DatePeriodEnum.WEEK)) { + if (structQueryParam.getDateInfo().getPeriod().equals(DatePeriodEnum.WEEK)) { return isOver ? addStr + "1 month" : addStr + "7 day"; } - if (queryParam.getDateInfo().getPeriod().equals(DatePeriodEnum.MONTH)) { + if (structQueryParam.getDateInfo().getPeriod().equals(DatePeriodEnum.MONTH)) { return isOver ? addStr + "1 year" : addStr + "1 month"; } } return ""; } - public String getOverSelect(QueryParam queryParam, boolean isOver) { - String aggStr = queryParam.getAggregators().stream().map(f -> { + public String getOverSelect(StructQueryParam structQueryParam, boolean isOver) { + String aggStr = structQueryParam.getAggregators().stream().map(f -> { if (f.getFunc().equals(AggOperatorEnum.RATIO_OVER) || f.getFunc().equals(AggOperatorEnum.RATIO_ROLL)) { return String.format("if(%s_roll!=0, (%s-%s_roll)/%s_roll , 0) as %s_%s,%s", @@ -325,26 +287,26 @@ public class CalculateAggConverter implements QueryConverter { return f.getColumn(); } }).collect(Collectors.joining(",")); - return CollectionUtils.isEmpty(queryParam.getGroups()) ? aggStr - : String.join(",", queryParam.getGroups()) + "," + aggStr; + return CollectionUtils.isEmpty(structQueryParam.getGroups()) ? aggStr + : String.join(",", structQueryParam.getGroups()) + "," + aggStr; } - public String getJoinOn(QueryParam queryParam, boolean isOver, String aliasLeft, + public String getJoinOn(StructQueryParam structQueryParam, boolean isOver, String aliasLeft, String aliasRight) { - String timeDim = getTimeDim(queryParam); - String timeSpan = "INTERVAL " + getTimeSpan(queryParam, isOver, true); - String aggStr = queryParam.getAggregators().stream().map(f -> { + String timeDim = getTimeDim(structQueryParam); + String timeSpan = "INTERVAL " + getTimeSpan(structQueryParam, isOver, true); + String aggStr = structQueryParam.getAggregators().stream().map(f -> { if (f.getFunc().equals(AggOperatorEnum.RATIO_OVER) || f.getFunc().equals(AggOperatorEnum.RATIO_ROLL)) { - if (queryParam.getDateInfo().getPeriod().equals(DatePeriodEnum.MONTH)) { + if (structQueryParam.getDateInfo().getPeriod().equals(DatePeriodEnum.MONTH)) { return String.format( "%s = DATE_FORMAT(date_add(CONCAT(%s,'-01'), %s),'%%Y-%%m') ", aliasLeft + timeDim, aliasRight + timeDim, timeSpan); } - if (queryParam.getDateInfo().getPeriod().equals(DatePeriodEnum.WEEK) + if (structQueryParam.getDateInfo().getPeriod().equals(DatePeriodEnum.WEEK) && isOver) { return String.format("to_monday(date_add(%s ,INTERVAL %s) ) = %s", - aliasLeft + timeDim, getTimeSpan(queryParam, isOver, false), + aliasLeft + timeDim, getTimeSpan(structQueryParam, isOver, false), aliasRight + timeDim); } return String.format("%s = date_add(%s,%s) ", aliasLeft + timeDim, @@ -354,7 +316,7 @@ public class CalculateAggConverter implements QueryConverter { } }).collect(Collectors.joining(" and ")); List groups = new ArrayList<>(); - for (String group : queryParam.getGroups()) { + for (String group : structQueryParam.getGroups()) { if (group.equalsIgnoreCase(timeDim)) { continue; } @@ -365,51 +327,53 @@ public class CalculateAggConverter implements QueryConverter { } @Override - public String sql(QueryParam queryParam, boolean isOver, boolean asWith, String metricSql) { + public String sql(StructQueryParam structQueryParam, boolean isOver, boolean asWith, + String metricSql) { String sql = String.format( "select %s from ( select %s , %s from %s t0 left join %s t1 on %s ) metric_tb_src %s %s ", - getOverSelect(queryParam, isOver), getAllSelect(queryParam, "t0."), - getAllJoinSelect(queryParam, "t1."), metricSql, metricSql, - getJoinOn(queryParam, isOver, "t0.", "t1."), getOrderBy(queryParam), - getLimit(queryParam)); + getOverSelect(structQueryParam, isOver), getAllSelect(structQueryParam, "t0."), + getAllJoinSelect(structQueryParam, "t1."), metricSql, metricSql, + getJoinOn(structQueryParam, isOver, "t0.", "t1."), getOrderBy(structQueryParam), + getLimit(structQueryParam)); return sql; } } - private String getAllJoinSelect(QueryParam queryParam, String alias) { - String aggStr = queryParam.getAggregators().stream() + private String getAllJoinSelect(StructQueryParam structQueryParam, String alias) { + String aggStr = structQueryParam.getAggregators().stream() .map(f -> getSelectField(f, alias) + " as " + getSelectField(f, "") + "_roll") .collect(Collectors.joining(",")); List groups = new ArrayList<>(); - for (String group : queryParam.getGroups()) { + for (String group : structQueryParam.getGroups()) { groups.add(alias + group + " as " + group + "_roll"); } return CollectionUtils.isEmpty(groups) ? aggStr : String.join(",", groups) + "," + aggStr; } - private String getGroupDimWithOutTime(QueryParam queryParam) { - String timeDim = getTimeDim(queryParam); - return queryParam.getGroups().stream().filter(f -> !f.equalsIgnoreCase(timeDim)) + private String getGroupDimWithOutTime(StructQueryParam structQueryParam) { + String timeDim = getTimeDim(structQueryParam); + return structQueryParam.getGroups().stream().filter(f -> !f.equalsIgnoreCase(timeDim)) .collect(Collectors.joining(",")); } - private static String getTimeDim(QueryParam queryParam) { + private static String getTimeDim(StructQueryParam structQueryParam) { DateModeUtils dateModeUtils = ContextUtils.getContext().getBean(DateModeUtils.class); - return dateModeUtils.getSysDateCol(queryParam.getDateInfo()); + return dateModeUtils.getSysDateCol(structQueryParam.getDateInfo()); } - private static String getLimit(QueryParam queryParam) { - if (queryParam != null && queryParam.getLimit() != null && queryParam.getLimit() > 0) { - return " limit " + String.valueOf(queryParam.getLimit()); + private static String getLimit(StructQueryParam structQueryParam) { + if (structQueryParam != null && structQueryParam.getLimit() != null + && structQueryParam.getLimit() > 0) { + return " limit " + String.valueOf(structQueryParam.getLimit()); } return ""; } - private String getAllSelect(QueryParam queryParam, String alias) { - String aggStr = queryParam.getAggregators().stream().map(f -> getSelectField(f, alias)) - .collect(Collectors.joining(",")); - return CollectionUtils.isEmpty(queryParam.getGroups()) ? aggStr - : alias + String.join("," + alias, queryParam.getGroups()) + "," + aggStr; + private String getAllSelect(StructQueryParam structQueryParam, String alias) { + String aggStr = structQueryParam.getAggregators().stream() + .map(f -> getSelectField(f, alias)).collect(Collectors.joining(",")); + return CollectionUtils.isEmpty(structQueryParam.getGroups()) ? aggStr + : alias + String.join("," + alias, structQueryParam.getGroups()) + "," + aggStr; } private String getSelectField(final Aggregator agg, String alias) { @@ -421,32 +385,32 @@ public class CalculateAggConverter implements QueryConverter { return sqlGenerateUtils.getSelectField(agg); } - private String getGroupBy(QueryParam queryParam) { - if (CollectionUtils.isEmpty(queryParam.getGroups())) { + private String getGroupBy(StructQueryParam structQueryParam) { + if (CollectionUtils.isEmpty(structQueryParam.getGroups())) { return ""; } - return "group by " + String.join(",", queryParam.getGroups()); + return "group by " + String.join(",", structQueryParam.getGroups()); } - private static String getOrderBy(QueryParam queryParam) { - return "order by " + getTimeDim(queryParam) + " desc"; + private static String getOrderBy(StructQueryParam structQueryParam) { + return "order by " + getTimeDim(structQueryParam) + " desc"; } - private boolean isOverRatio(QueryParam queryParam) { - Long overCt = queryParam.getAggregators().stream() + private boolean isOverRatio(StructQueryParam structQueryParam) { + Long overCt = structQueryParam.getAggregators().stream() .filter(f -> f.getFunc().equals(AggOperatorEnum.RATIO_OVER)).count(); return overCt > 0; } - private void check(QueryParam queryParam) throws Exception { - Long ratioOverNum = queryParam.getAggregators().stream() + private void check(StructQueryParam structQueryParam) throws Exception { + Long ratioOverNum = structQueryParam.getAggregators().stream() .filter(f -> f.getFunc().equals(AggOperatorEnum.RATIO_OVER)).count(); - Long ratioRollNum = queryParam.getAggregators().stream() + Long ratioRollNum = structQueryParam.getAggregators().stream() .filter(f -> f.getFunc().equals(AggOperatorEnum.RATIO_ROLL)).count(); if (ratioOverNum > 0 && ratioRollNum > 0) { throw new Exception("not support over ratio and roll ratio together "); } - if (getTimeDim(queryParam).isEmpty()) { + if (getTimeDim(structQueryParam).isEmpty()) { throw new Exception("miss time filter"); } } diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/converter/ParserDefaultConverter.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/converter/ParserDefaultConverter.java deleted file mode 100644 index 12c8dd722..000000000 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/converter/ParserDefaultConverter.java +++ /dev/null @@ -1,74 +0,0 @@ -package com.tencent.supersonic.headless.core.translator.converter; - -import com.tencent.supersonic.common.pojo.ColumnOrder; -import com.tencent.supersonic.common.util.ContextUtils; -import com.tencent.supersonic.headless.api.pojo.QueryParam; -import com.tencent.supersonic.headless.core.pojo.MetricQueryParam; -import com.tencent.supersonic.headless.core.pojo.QueryStatement; -import com.tencent.supersonic.headless.core.translator.calcite.s2sql.DataModel; -import com.tencent.supersonic.headless.core.utils.SqlGenerateUtils; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.BeanUtils; -import org.springframework.stereotype.Component; -import org.springframework.util.CollectionUtils; - -import java.util.Map; -import java.util.Objects; -import java.util.stream.Collectors; - -/** QueryConverter default implement */ -@Component("ParserDefaultConverter") -@Slf4j -public class ParserDefaultConverter implements QueryConverter { - - @Override - public boolean accept(QueryStatement queryStatement) { - if (Objects.isNull(queryStatement.getQueryParam()) || queryStatement.getIsS2SQL()) { - return false; - } - CalculateAggConverter calculateConverterAgg = - ContextUtils.getBean(CalculateAggConverter.class); - return !calculateConverterAgg.accept(queryStatement); - } - - @Override - public void convert(QueryStatement queryStatement) throws Exception { - SqlGenerateUtils sqlGenerateUtils = ContextUtils.getBean(SqlGenerateUtils.class); - QueryParam queryParam = queryStatement.getQueryParam(); - MetricQueryParam metricQueryParam = queryStatement.getMetricQueryParam(); - MetricQueryParam metricReq = - generateSqlCommand(queryStatement.getQueryParam(), queryStatement); - queryStatement.setMinMaxTime(sqlGenerateUtils.getBeginEndTime(queryParam, null)); - BeanUtils.copyProperties(metricReq, metricQueryParam); - } - - public MetricQueryParam generateSqlCommand(QueryParam queryParam, - QueryStatement queryStatement) { - SqlGenerateUtils sqlGenerateUtils = ContextUtils.getBean(SqlGenerateUtils.class); - MetricQueryParam metricQueryParam = new MetricQueryParam(); - metricQueryParam.setMetrics(queryParam.getMetrics()); - metricQueryParam.setDimensions(queryParam.getGroups()); - String where = sqlGenerateUtils.generateWhere(queryParam, null); - log.info("in generateSqlCommend, complete where:{}", where); - - metricQueryParam.setWhere(where); - metricQueryParam.setOrder(queryParam.getOrders().stream() - .map(order -> new ColumnOrder(order.getColumn(), order.getDirection())) - .collect(Collectors.toList())); - metricQueryParam.setLimit(queryParam.getLimit()); - - // support detail query - if (queryParam.getQueryType().isNativeAggQuery() - && CollectionUtils.isEmpty(metricQueryParam.getMetrics())) { - Map modelMap = queryStatement.getOntology().getModelMap(); - for (Long modelId : modelMap.keySet()) { - String modelBizName = modelMap.get(modelId).getName(); - String internalMetricName = - sqlGenerateUtils.generateInternalMetricName(modelBizName); - metricQueryParam.getMetrics().add(internalMetricName); - } - } - - return metricQueryParam; - } -} diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/converter/SqlQueryConverter.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/converter/SqlQueryConverter.java new file mode 100644 index 000000000..47ff61e2a --- /dev/null +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/converter/SqlQueryConverter.java @@ -0,0 +1,288 @@ +package com.tencent.supersonic.headless.core.translator.converter; + +import com.tencent.supersonic.common.jsqlparser.SqlReplaceHelper; +import com.tencent.supersonic.common.jsqlparser.SqlSelectFunctionHelper; +import com.tencent.supersonic.common.jsqlparser.SqlSelectHelper; +import com.tencent.supersonic.common.pojo.Constants; +import com.tencent.supersonic.common.pojo.enums.EngineType; +import com.tencent.supersonic.common.pojo.enums.TimeDimensionEnum; +import com.tencent.supersonic.common.util.ContextUtils; +import com.tencent.supersonic.headless.api.pojo.Measure; +import com.tencent.supersonic.headless.api.pojo.SchemaItem; +import com.tencent.supersonic.headless.api.pojo.enums.AggOption; +import com.tencent.supersonic.headless.api.pojo.enums.MetricType; +import com.tencent.supersonic.headless.api.pojo.response.*; +import com.tencent.supersonic.headless.core.pojo.QueryStatement; +import com.tencent.supersonic.headless.core.pojo.SqlQueryParam; +import com.tencent.supersonic.headless.core.translator.parser.s2sql.OntologyQueryParam; +import com.tencent.supersonic.headless.core.utils.SqlGenerateUtils; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.tuple.Pair; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; + +import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +@Component("SqlQueryConverter") +@Slf4j +public class SqlQueryConverter implements QueryConverter { + + @Override + public boolean accept(QueryStatement queryStatement) { + return Objects.nonNull(queryStatement.getSqlQueryParam()) && queryStatement.getIsS2SQL(); + } + + @Override + public void convert(QueryStatement queryStatement) throws Exception { + convertNameToBizName(queryStatement); + rewriteOrderBy(queryStatement); + + // fill sqlQuery + SemanticSchemaResp semanticSchemaResp = queryStatement.getSemanticSchemaResp(); + SqlQueryParam sqlQueryParam = queryStatement.getSqlQueryParam(); + String tableName = SqlSelectHelper.getTableName(sqlQueryParam.getSql()); + if (StringUtils.isEmpty(tableName)) { + return; + } + sqlQueryParam.setTable(tableName.toLowerCase()); + SqlGenerateUtils sqlGenerateUtils = ContextUtils.getBean(SqlGenerateUtils.class); + if (!sqlGenerateUtils.isSupportWith( + EngineType.fromString(semanticSchemaResp.getDatabaseResp().getType().toUpperCase()), + semanticSchemaResp.getDatabaseResp().getVersion())) { + sqlQueryParam.setSupportWith(false); + sqlQueryParam.setWithAlias(false); + } + + // build ontologyQuery + List allFields = SqlSelectHelper.getAllSelectFields(sqlQueryParam.getSql()); + List metricSchemas = getMetrics(semanticSchemaResp, allFields); + List metrics = + metricSchemas.stream().map(SchemaItem::getBizName).collect(Collectors.toList()); + AggOption aggOption = getAggOption(sqlQueryParam.getSql(), metricSchemas); + Set dimensions = getDimensions(semanticSchemaResp, allFields); + OntologyQueryParam ontologyQueryParam = new OntologyQueryParam(); + ontologyQueryParam.getMetrics().addAll(metrics); + ontologyQueryParam.getDimensions().addAll(dimensions); + ontologyQueryParam.setAggOption(aggOption); + ontologyQueryParam.setNativeQuery(!AggOption.isAgg(aggOption)); + queryStatement.setOntologyQueryParam(ontologyQueryParam); + + generateDerivedMetric(sqlGenerateUtils, queryStatement); + + queryStatement.setSql(sqlQueryParam.getSql()); + log.info("parse sqlQuery [{}] ", sqlQueryParam); + } + + private AggOption getAggOption(String sql, List metricSchemas) { + if (SqlSelectFunctionHelper.hasAggregateFunction(sql)) { + return AggOption.AGGREGATION; + } + + if (!SqlSelectFunctionHelper.hasAggregateFunction(sql) && !SqlSelectHelper.hasGroupBy(sql) + && !SqlSelectHelper.hasWith(sql) && !SqlSelectHelper.hasSubSelect(sql)) { + log.debug("getAggOption simple sql set to DEFAULT"); + return AggOption.NATIVE; + } + + // if there is no group by in S2SQL,set MetricTable's aggOption to "NATIVE" + // if there is count() in S2SQL,set MetricTable's aggOption to "NATIVE" + if (!SqlSelectFunctionHelper.hasAggregateFunction(sql) + || SqlSelectFunctionHelper.hasFunction(sql, "count") + || SqlSelectFunctionHelper.hasFunction(sql, "count_distinct")) { + return AggOption.OUTER; + } + + if (SqlSelectHelper.hasSubSelect(sql) || SqlSelectHelper.hasWith(sql) + || SqlSelectHelper.hasGroupBy(sql)) { + return AggOption.OUTER; + } + long defaultAggNullCnt = metricSchemas.stream().filter( + m -> Objects.isNull(m.getDefaultAgg()) || StringUtils.isBlank(m.getDefaultAgg())) + .count(); + if (defaultAggNullCnt > 0) { + log.debug("getAggOption find null defaultAgg metric set to NATIVE"); + return AggOption.DEFAULT; + } + return AggOption.DEFAULT; + } + + private Set getDimensions(SemanticSchemaResp semanticSchemaResp, + List allFields) { + Map dimensionLowerToNameMap = semanticSchemaResp.getDimensions().stream() + .collect(Collectors.toMap(entry -> entry.getBizName().toLowerCase(), + SchemaItem::getBizName, (k1, k2) -> k1)); + dimensionLowerToNameMap.put(TimeDimensionEnum.DAY.getName(), + TimeDimensionEnum.DAY.getName()); + return allFields.stream() + .filter(entry -> dimensionLowerToNameMap.containsKey(entry.toLowerCase())) + .map(entry -> dimensionLowerToNameMap.get(entry.toLowerCase())) + .collect(Collectors.toSet()); + } + + private List getMetrics(SemanticSchemaResp semanticSchemaResp, + List allFields) { + Map metricLowerToNameMap = + semanticSchemaResp.getMetrics().stream().collect(Collectors + .toMap(entry -> entry.getBizName().toLowerCase(), entry -> entry)); + return allFields.stream() + .filter(entry -> metricLowerToNameMap.containsKey(entry.toLowerCase())) + .map(entry -> metricLowerToNameMap.get(entry.toLowerCase())) + .collect(Collectors.toList()); + } + + + private void generateDerivedMetric(SqlGenerateUtils sqlGenerateUtils, + QueryStatement queryStatement) { + SemanticSchemaResp semanticSchemaResp = queryStatement.getSemanticSchemaResp(); + SqlQueryParam sqlParam = queryStatement.getSqlQueryParam(); + OntologyQueryParam ontologyParam = queryStatement.getOntologyQueryParam(); + String sql = sqlParam.getSql(); + + Set measures = new HashSet<>(); + Map replaces = generateDerivedMetric(sqlGenerateUtils, semanticSchemaResp, + ontologyParam.getAggOption(), ontologyParam.getMetrics(), + ontologyParam.getDimensions(), measures); + + if (!CollectionUtils.isEmpty(replaces)) { + // metricTable sql use measures replace metric + sql = SqlReplaceHelper.replaceSqlByExpression(sql, replaces); + ontologyParam.setAggOption(AggOption.NATIVE); + // metricTable use measures replace metric + if (!CollectionUtils.isEmpty(measures)) { + ontologyParam.getMetrics().addAll(measures); + } else { + // empty measure , fill default + ontologyParam.getMetrics().add(sqlGenerateUtils.generateInternalMetricName( + getDefaultModel(semanticSchemaResp, ontologyParam.getDimensions()))); + } + } + + sqlParam.setSql(sql); + } + + private Map generateDerivedMetric(SqlGenerateUtils sqlGenerateUtils, + SemanticSchemaResp semanticSchemaResp, AggOption aggOption, Set metrics, + Set dimensions, Set measures) { + Map result = new HashMap<>(); + List metricResps = semanticSchemaResp.getMetrics(); + List dimensionResps = semanticSchemaResp.getDimensions(); + + // Check if any metric is derived + boolean hasDerivedMetrics = + metricResps.stream().anyMatch(m -> metrics.contains(m.getBizName()) && MetricType + .isDerived(m.getMetricDefineType(), m.getMetricDefineByMeasureParams())); + if (!hasDerivedMetrics) { + return result; + } + + log.debug("begin to generateDerivedMetric {} [{}]", aggOption, metrics); + + Set allFields = new HashSet<>(); + Map allMeasures = new HashMap<>(); + semanticSchemaResp.getModelResps().forEach(modelResp -> { + allFields.addAll(modelResp.getFieldList()); + if (modelResp.getModelDetail().getMeasures() != null) { + modelResp.getModelDetail().getMeasures() + .forEach(measure -> allMeasures.put(measure.getBizName(), measure)); + } + }); + + Set derivedDimensions = new HashSet<>(); + Set derivedMetrics = new HashSet<>(); + Map visitedMetrics = new HashMap<>(); + + for (MetricResp metricResp : metricResps) { + if (metrics.contains(metricResp.getBizName())) { + boolean isDerived = MetricType.isDerived(metricResp.getMetricDefineType(), + metricResp.getMetricDefineByMeasureParams()); + if (isDerived) { + String expr = sqlGenerateUtils.generateDerivedMetric(metricResps, allFields, + allMeasures, dimensionResps, sqlGenerateUtils.getExpr(metricResp), + metricResp.getMetricDefineType(), aggOption, visitedMetrics, + derivedMetrics, derivedDimensions); + result.put(metricResp.getBizName(), expr); + log.debug("derived metric {}->{}", metricResp.getBizName(), expr); + } else { + measures.add(metricResp.getBizName()); + } + } + } + + measures.addAll(derivedMetrics); + derivedDimensions.stream().filter(dimension -> !dimensions.contains(dimension)) + .forEach(dimensions::add); + + return result; + } + + + private void convertNameToBizName(QueryStatement queryStatement) { + SemanticSchemaResp semanticSchemaResp = queryStatement.getSemanticSchemaResp(); + Map fieldNameToBizNameMap = getFieldNameToBizNameMap(semanticSchemaResp); + String sql = queryStatement.getSqlQueryParam().getSql(); + log.debug("dataSetId:{},convert name to bizName before:{}", queryStatement.getDataSetId(), + sql); + sql = SqlReplaceHelper.replaceFields(sql, fieldNameToBizNameMap, true); + log.debug("dataSetId:{},convert name to bizName after:{}", queryStatement.getDataSetId(), + sql); + sql = SqlReplaceHelper.replaceTable(sql, + Constants.TABLE_PREFIX + queryStatement.getDataSetId()); + log.debug("replaceTableName after:{}", sql); + queryStatement.getSqlQueryParam().setSql(sql); + } + + private void rewriteOrderBy(QueryStatement queryStatement) { + // replace order by field with the select sequence number + String sql = queryStatement.getSqlQueryParam().getSql(); + String newSql = SqlReplaceHelper.replaceAggAliasOrderbyField(sql); + log.debug("replaceOrderAggSameAlias {} -> {}", sql, newSql); + queryStatement.getSqlQueryParam().setSql(newSql); + } + + protected Map getFieldNameToBizNameMap(SemanticSchemaResp semanticSchemaResp) { + // support fieldName and field alias to bizName + Map dimensionResults = semanticSchemaResp.getDimensions().stream().flatMap( + entry -> getPairStream(entry.getAlias(), entry.getName(), entry.getBizName())) + .collect(Collectors.toMap(Pair::getLeft, Pair::getRight, (k1, k2) -> k1)); + + Map metricResults = semanticSchemaResp.getMetrics().stream().flatMap( + entry -> getPairStream(entry.getAlias(), entry.getName(), entry.getBizName())) + .collect(Collectors.toMap(Pair::getLeft, Pair::getRight, (k1, k2) -> k1)); + + dimensionResults.putAll(TimeDimensionEnum.getChNameToNameMap()); + dimensionResults.putAll(TimeDimensionEnum.getNameToNameMap()); + dimensionResults.putAll(metricResults); + return dimensionResults; + } + + private Stream> getPairStream(String aliasStr, String name, + String bizName) { + Set> elements = new HashSet<>(); + elements.add(Pair.of(name, bizName)); + if (StringUtils.isNotBlank(aliasStr)) { + List aliasList = SchemaItem.getAliasList(aliasStr); + for (String alias : aliasList) { + elements.add(Pair.of(alias, bizName)); + } + } + return elements.stream(); + } + + private String getDefaultModel(SemanticSchemaResp semanticSchemaResp, Set dimensions) { + if (!CollectionUtils.isEmpty(dimensions)) { + Map modelMatchCnt = new HashMap<>(); + for (ModelResp modelResp : semanticSchemaResp.getModelResps()) { + modelMatchCnt.put(modelResp.getBizName(), modelResp.getModelDetail().getDimensions() + .stream().filter(d -> dimensions.contains(d.getBizName())).count()); + } + return modelMatchCnt.entrySet().stream() + .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())) + .map(Map.Entry::getKey).findFirst().orElse(""); + } + return semanticSchemaResp.getModelResps().get(0).getBizName(); + } + +} diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/converter/SqlVariableParseConverter.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/converter/SqlVariableConverter.java similarity index 80% rename from headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/converter/SqlVariableParseConverter.java rename to headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/converter/SqlVariableConverter.java index e2c5f9a06..1ef5c2147 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/converter/SqlVariableParseConverter.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/converter/SqlVariableConverter.java @@ -4,7 +4,7 @@ import com.tencent.supersonic.headless.api.pojo.enums.ModelDefineType; import com.tencent.supersonic.headless.api.pojo.response.ModelResp; import com.tencent.supersonic.headless.api.pojo.response.SemanticSchemaResp; import com.tencent.supersonic.headless.core.pojo.QueryStatement; -import com.tencent.supersonic.headless.core.translator.calcite.s2sql.DataModel; +import com.tencent.supersonic.headless.core.translator.parser.s2sql.DataModel; import com.tencent.supersonic.headless.core.utils.SqlVariableParseUtils; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; @@ -14,15 +14,13 @@ import java.util.List; import java.util.Objects; @Slf4j -@Component("SqlVariableParseConverter") -public class SqlVariableParseConverter implements QueryConverter { +@Component("SqlVariableConverter") +public class SqlVariableConverter implements QueryConverter { @Override public boolean accept(QueryStatement queryStatement) { - if (Objects.isNull(queryStatement.getQueryParam())) { - return false; - } - return true; + return Objects.nonNull(queryStatement.getStructQueryParam()) + && !queryStatement.getIsS2SQL(); } @Override @@ -38,7 +36,7 @@ public class SqlVariableParseConverter implements QueryConverter { String sqlParsed = SqlVariableParseUtils.parse(modelResp.getModelDetail().getSqlQuery(), modelResp.getModelDetail().getSqlVariables(), - queryStatement.getQueryParam().getParams()); + queryStatement.getStructQueryParam().getParams()); DataModel dataModel = queryStatement.getOntology().getDataModelMap().get(modelResp.getBizName()); dataModel.setSqlQuery(sqlParsed); diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/converter/StructQueryConverter.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/converter/StructQueryConverter.java new file mode 100644 index 000000000..ef89dce5c --- /dev/null +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/converter/StructQueryConverter.java @@ -0,0 +1,70 @@ +package com.tencent.supersonic.headless.core.translator.converter; + +import com.tencent.supersonic.common.pojo.Aggregator; +import com.tencent.supersonic.common.pojo.ColumnOrder; +import com.tencent.supersonic.common.util.ContextUtils; +import com.tencent.supersonic.headless.api.pojo.enums.AggOption; +import com.tencent.supersonic.headless.core.pojo.Database; +import com.tencent.supersonic.headless.core.pojo.QueryStatement; +import com.tencent.supersonic.headless.core.pojo.SqlQueryParam; +import com.tencent.supersonic.headless.core.pojo.StructQueryParam; +import com.tencent.supersonic.headless.core.translator.parser.s2sql.OntologyQueryParam; +import com.tencent.supersonic.headless.core.utils.SqlGenerateUtils; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import java.util.Objects; +import java.util.stream.Collectors; + +@Component("ParserDefaultConverter") +@Slf4j +public class StructQueryConverter implements QueryConverter { + + @Override + public boolean accept(QueryStatement queryStatement) { + return Objects.nonNull(queryStatement.getStructQueryParam()) + && !queryStatement.getIsS2SQL(); + } + + @Override + public void convert(QueryStatement queryStatement) throws Exception { + SqlGenerateUtils sqlGenerateUtils = ContextUtils.getBean(SqlGenerateUtils.class); + StructQueryParam structQueryParam = queryStatement.getStructQueryParam(); + + String dsTable = "t_1"; + SqlQueryParam sqlParam = new SqlQueryParam(); + sqlParam.setTable(dsTable); + String sql = String.format("select %s from %s %s %s %s", + sqlGenerateUtils.getSelect(structQueryParam), dsTable, + sqlGenerateUtils.getGroupBy(structQueryParam), + sqlGenerateUtils.getOrderBy(structQueryParam), + sqlGenerateUtils.getLimit(structQueryParam)); + Database database = queryStatement.getOntology().getDatabase(); + if (!sqlGenerateUtils.isSupportWith(database.getType(), database.getVersion())) { + sqlParam.setSupportWith(false); + sql = String.format("select %s from %s t0 %s %s %s", + sqlGenerateUtils.getSelect(structQueryParam), dsTable, + sqlGenerateUtils.getGroupBy(structQueryParam), + sqlGenerateUtils.getOrderBy(structQueryParam), + sqlGenerateUtils.getLimit(structQueryParam)); + } + sqlParam.setSql(sql); + queryStatement.setSqlQueryParam(sqlParam); + + OntologyQueryParam ontologyQueryParam = new OntologyQueryParam(); + ontologyQueryParam.getDimensions().addAll(structQueryParam.getGroups()); + ontologyQueryParam.getMetrics().addAll(structQueryParam.getAggregators().stream() + .map(Aggregator::getColumn).collect(Collectors.toList())); + String where = sqlGenerateUtils.generateWhere(structQueryParam, null); + ontologyQueryParam.setWhere(where); + ontologyQueryParam.setAggOption(AggOption.AGGREGATION); + ontologyQueryParam.setNativeQuery(structQueryParam.getQueryType().isNativeAggQuery()); + ontologyQueryParam.setOrder(structQueryParam.getOrders().stream() + .map(order -> new ColumnOrder(order.getColumn(), order.getDirection())) + .collect(Collectors.toList())); + ontologyQueryParam.setLimit(structQueryParam.getLimit()); + queryStatement.setOntologyQueryParam(ontologyQueryParam); + log.info("parse structQuery [{}] ", queryStatement.getSqlQueryParam()); + } + +} diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/optimizer/DbDialectOptimizer.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/optimizer/DbDialectOptimizer.java new file mode 100644 index 000000000..481379e28 --- /dev/null +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/optimizer/DbDialectOptimizer.java @@ -0,0 +1,32 @@ +package com.tencent.supersonic.headless.core.translator.optimizer; + +import com.tencent.supersonic.headless.api.pojo.response.DatabaseResp; +import com.tencent.supersonic.headless.api.pojo.response.SemanticSchemaResp; +import com.tencent.supersonic.headless.core.adaptor.db.DbAdaptor; +import com.tencent.supersonic.headless.core.adaptor.db.DbAdaptorFactory; +import com.tencent.supersonic.headless.core.pojo.QueryStatement; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import java.util.Objects; + +@Slf4j +@Component("DbDialectOptimizer") +public class DbDialectOptimizer implements QueryOptimizer { + + @Override + public void rewrite(QueryStatement queryStatement) { + SemanticSchemaResp semanticSchemaResp = queryStatement.getSemanticSchemaResp(); + DatabaseResp database = semanticSchemaResp.getDatabaseResp(); + String sql = queryStatement.getSql(); + if (Objects.isNull(database) || Objects.isNull(database.getType())) { + return; + } + String type = database.getType(); + DbAdaptor engineAdaptor = DbAdaptorFactory.getEngineAdaptor(type.toLowerCase()); + if (Objects.nonNull(engineAdaptor)) { + String adaptedSql = engineAdaptor.rewriteSql(sql); + queryStatement.setSql(adaptedSql); + } + } +} diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/optimizer/DetailQueryOptimizer.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/optimizer/DetailQueryOptimizer.java new file mode 100644 index 000000000..92836608a --- /dev/null +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/optimizer/DetailQueryOptimizer.java @@ -0,0 +1,40 @@ +package com.tencent.supersonic.headless.core.translator.optimizer; + +import com.tencent.supersonic.headless.core.pojo.QueryStatement; +import com.tencent.supersonic.headless.core.pojo.StructQueryParam; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Component; + +import java.util.Objects; + +/** Remove the default metric added by the system when the query only has dimensions */ +@Slf4j +@Component("DetailQueryOptimizer") +public class DetailQueryOptimizer implements QueryOptimizer { + + @Override + public void rewrite(QueryStatement queryStatement) { + StructQueryParam structQueryParam = queryStatement.getStructQueryParam(); + String sqlRaw = queryStatement.getSql().trim(); + if (StringUtils.isEmpty(sqlRaw)) { + throw new RuntimeException("sql is empty or null"); + } + log.debug("before handleNoMetric, sql:{}", sqlRaw); + // if (isDetailQuery(structQueryParam)) { + // if (!CollectionUtils.isEmpty(structQueryParam.getGroups())) { + // String sqlForm = "select %s from ( %s ) src_no_metric"; + // String sql = String.format(sqlForm, + // structQueryParam.getGroups().stream().collect(Collectors.joining(",")), + // sqlRaw); + // queryStatement.setSql(sql); + // } + // } + log.debug("after handleNoMetric, sql:{}", queryStatement.getSql()); + } + + public boolean isDetailQuery(StructQueryParam structQueryParam) { + return Objects.nonNull(structQueryParam) + && structQueryParam.getQueryType().isNativeAggQuery(); + } +} diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/QueryOptimizer.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/optimizer/QueryOptimizer.java similarity index 81% rename from headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/QueryOptimizer.java rename to headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/optimizer/QueryOptimizer.java index a66bb7f12..baeb626dd 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/QueryOptimizer.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/optimizer/QueryOptimizer.java @@ -1,4 +1,4 @@ -package com.tencent.supersonic.headless.core.translator; +package com.tencent.supersonic.headless.core.translator.optimizer; import com.tencent.supersonic.headless.core.pojo.QueryStatement; diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/optimizer/ResultLimitOptimizer.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/optimizer/ResultLimitOptimizer.java new file mode 100644 index 000000000..3d13d2d0a --- /dev/null +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/optimizer/ResultLimitOptimizer.java @@ -0,0 +1,18 @@ +package com.tencent.supersonic.headless.core.translator.optimizer; + +import com.tencent.supersonic.common.jsqlparser.SqlSelectHelper; +import com.tencent.supersonic.headless.core.pojo.QueryStatement; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +@Slf4j +@Component("ResultLimitOptimizer") +public class ResultLimitOptimizer implements QueryOptimizer { + + @Override + public void rewrite(QueryStatement queryStatement) { + if (!SqlSelectHelper.hasLimit(queryStatement.getSql())) { + queryStatement.setSql(queryStatement.getSql() + " limit " + queryStatement.getLimit()); + } + } +} diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/QueryParser.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/QueryParser.java new file mode 100644 index 000000000..c3a584832 --- /dev/null +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/QueryParser.java @@ -0,0 +1,8 @@ +package com.tencent.supersonic.headless.core.translator.parser; + +import com.tencent.supersonic.headless.core.pojo.QueryStatement; + +/** A query parser generates physical SQL for the QueryStatement. */ +public interface QueryParser { + void parse(QueryStatement queryStatement) throws Exception; +} diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/CalciteQueryParser.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/CalciteQueryParser.java similarity index 58% rename from headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/CalciteQueryParser.java rename to headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/CalciteQueryParser.java index ce0d27a11..c4047b6b5 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/CalciteQueryParser.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/CalciteQueryParser.java @@ -1,12 +1,8 @@ -package com.tencent.supersonic.headless.core.translator.calcite; +package com.tencent.supersonic.headless.core.translator.parser.calcite; -import com.tencent.supersonic.headless.api.pojo.enums.AggOption; import com.tencent.supersonic.headless.core.pojo.QueryStatement; -import com.tencent.supersonic.headless.core.translator.QueryParser; -import com.tencent.supersonic.headless.core.translator.calcite.s2sql.Ontology; -import com.tencent.supersonic.headless.core.translator.calcite.sql.RuntimeOptions; -import com.tencent.supersonic.headless.core.translator.calcite.sql.S2CalciteSchema; -import com.tencent.supersonic.headless.core.translator.calcite.sql.SqlBuilder; +import com.tencent.supersonic.headless.core.translator.parser.QueryParser; +import com.tencent.supersonic.headless.core.translator.parser.s2sql.Ontology; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; @@ -16,7 +12,7 @@ import org.springframework.stereotype.Component; public class CalciteQueryParser implements QueryParser { @Override - public void parse(QueryStatement queryStatement, AggOption isAgg) throws Exception { + public void parse(QueryStatement queryStatement) throws Exception { Ontology ontology = queryStatement.getOntology(); if (ontology == null) { queryStatement.setErrMsg("No ontology could be found"); @@ -29,7 +25,8 @@ public class CalciteQueryParser implements QueryParser { .enableOptimize(queryStatement.getEnableOptimize()).build()) .build(); SqlBuilder sqlBuilder = new SqlBuilder(semanticSchema); - sqlBuilder.build(queryStatement, isAgg); + String sql = sqlBuilder.buildOntologySql(queryStatement); + queryStatement.setSql(sql); } } diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/FilterToGroupScanRule.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/FilterToGroupScanRule.java similarity index 98% rename from headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/FilterToGroupScanRule.java rename to headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/FilterToGroupScanRule.java index 59e163791..3cf783931 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/FilterToGroupScanRule.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/FilterToGroupScanRule.java @@ -1,4 +1,4 @@ -package com.tencent.supersonic.headless.core.translator.calcite.sql; +package com.tencent.supersonic.headless.core.translator.parser.calcite; import org.apache.calcite.plan.RelOptRuleCall; import org.apache.calcite.plan.RelRule; diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/RuntimeOptions.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/RuntimeOptions.java similarity index 76% rename from headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/RuntimeOptions.java rename to headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/RuntimeOptions.java index 9bf681b3e..67663d5b1 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/RuntimeOptions.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/RuntimeOptions.java @@ -1,4 +1,4 @@ -package com.tencent.supersonic.headless.core.translator.calcite.sql; +package com.tencent.supersonic.headless.core.translator.parser.calcite; import lombok.Builder; import lombok.Data; diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/S2CalciteSchema.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/S2CalciteSchema.java similarity index 65% rename from headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/S2CalciteSchema.java rename to headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/S2CalciteSchema.java index e1559809f..e0e0af42c 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/S2CalciteSchema.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/S2CalciteSchema.java @@ -1,10 +1,10 @@ -package com.tencent.supersonic.headless.core.translator.calcite.sql; +package com.tencent.supersonic.headless.core.translator.parser.calcite; -import com.tencent.supersonic.headless.core.translator.calcite.s2sql.DataModel; -import com.tencent.supersonic.headless.core.translator.calcite.s2sql.Dimension; -import com.tencent.supersonic.headless.core.translator.calcite.s2sql.JoinRelation; -import com.tencent.supersonic.headless.core.translator.calcite.s2sql.Metric; -import com.tencent.supersonic.headless.core.translator.calcite.s2sql.Ontology; +import com.tencent.supersonic.headless.core.translator.parser.s2sql.DataModel; +import com.tencent.supersonic.headless.core.translator.parser.s2sql.Dimension; +import com.tencent.supersonic.headless.core.translator.parser.s2sql.JoinRelation; +import com.tencent.supersonic.headless.core.translator.parser.s2sql.Metric; +import com.tencent.supersonic.headless.core.translator.parser.s2sql.Ontology; import lombok.Builder; import lombok.Data; import org.apache.calcite.schema.Schema; diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/S2CalciteTable.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/S2CalciteTable.java similarity index 98% rename from headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/S2CalciteTable.java rename to headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/S2CalciteTable.java index 98a2b08fc..7b6d2b494 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/S2CalciteTable.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/S2CalciteTable.java @@ -1,4 +1,4 @@ -package com.tencent.supersonic.headless.core.translator.calcite.sql; +package com.tencent.supersonic.headless.core.translator.parser.calcite; import org.apache.calcite.DataContext; import org.apache.calcite.linq4j.Enumerable; diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/S2SQLSqlValidatorImpl.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/S2SQLSqlValidatorImpl.java similarity index 88% rename from headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/S2SQLSqlValidatorImpl.java rename to headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/S2SQLSqlValidatorImpl.java index b3c7c0a57..c253c1b0f 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/S2SQLSqlValidatorImpl.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/S2SQLSqlValidatorImpl.java @@ -1,4 +1,4 @@ -package com.tencent.supersonic.headless.core.translator.calcite.sql; +package com.tencent.supersonic.headless.core.translator.parser.calcite; import org.apache.calcite.rel.type.RelDataTypeFactory; import org.apache.calcite.sql.SqlOperatorTable; diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/SchemaBuilder.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/SchemaBuilder.java similarity index 95% rename from headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/SchemaBuilder.java rename to headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/SchemaBuilder.java index 43949e000..e7bcfb3b3 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/SchemaBuilder.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/SchemaBuilder.java @@ -1,4 +1,4 @@ -package com.tencent.supersonic.headless.core.translator.calcite.sql; +package com.tencent.supersonic.headless.core.translator.parser.calcite; import com.tencent.supersonic.common.calcite.Configuration; import com.tencent.supersonic.common.pojo.enums.EngineType; @@ -33,7 +33,7 @@ public class SchemaBuilder { Prepare.CatalogReader catalogReader = new CalciteCatalogReader(rootSchema, Collections.singletonList(schema.getSchemaKey()), Configuration.typeFactory, Configuration.config); - EngineType engineType = EngineType.fromString(schema.getOntology().getDatabase().getType()); + EngineType engineType = schema.getOntology().getDatabase().getType(); S2SQLSqlValidatorImpl s2SQLSqlValidator = new S2SQLSqlValidatorImpl(Configuration.operatorTable, catalogReader, Configuration.typeFactory, Configuration.getValidatorConfig(engineType)); diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/SqlBuilder.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/SqlBuilder.java new file mode 100644 index 000000000..c8e48b352 --- /dev/null +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/SqlBuilder.java @@ -0,0 +1,124 @@ +package com.tencent.supersonic.headless.core.translator.parser.calcite; + +import com.tencent.supersonic.common.calcite.Configuration; +import com.tencent.supersonic.common.pojo.enums.EngineType; +import com.tencent.supersonic.headless.api.pojo.enums.AggOption; +import com.tencent.supersonic.headless.core.pojo.Database; +import com.tencent.supersonic.headless.core.pojo.QueryStatement; +import com.tencent.supersonic.headless.core.translator.parser.calcite.node.DataModelNode; +import com.tencent.supersonic.headless.core.translator.parser.calcite.node.SemanticNode; +import com.tencent.supersonic.headless.core.translator.parser.calcite.render.FilterRender; +import com.tencent.supersonic.headless.core.translator.parser.calcite.render.OutputRender; +import com.tencent.supersonic.headless.core.translator.parser.calcite.render.Renderer; +import com.tencent.supersonic.headless.core.translator.parser.calcite.render.SourceRender; +import com.tencent.supersonic.headless.core.translator.parser.s2sql.Constants; +import com.tencent.supersonic.headless.core.translator.parser.s2sql.DataModel; +import com.tencent.supersonic.headless.core.translator.parser.s2sql.OntologyQueryParam; +import lombok.extern.slf4j.Slf4j; +import org.apache.calcite.sql.SqlNode; +import org.apache.calcite.sql.parser.SqlParser; +import org.apache.calcite.sql.validate.SqlValidatorScope; + +import java.util.*; + +@Slf4j +public class SqlBuilder { + + private final S2CalciteSchema schema; + private OntologyQueryParam ontologyQueryParam; + private SqlValidatorScope scope; + private SqlNode parserNode; + private boolean isAgg = false; + private AggOption aggOption = AggOption.DEFAULT; + + public SqlBuilder(S2CalciteSchema schema) { + this.schema = schema; + } + + public String buildOntologySql(QueryStatement queryStatement) throws Exception { + this.ontologyQueryParam = queryStatement.getOntologyQueryParam(); + if (ontologyQueryParam.getLimit() == null) { + ontologyQueryParam.setLimit(0L); + } + this.aggOption = ontologyQueryParam.getAggOption(); + + buildParseNode(); + Database database = queryStatement.getOntology().getDatabase(); + optimizeParseNode(database.getType()); + return getSql(database.getType()); + } + + private void buildParseNode() throws Exception { + // find relevant data models + scope = SchemaBuilder.getScope(schema); + List dataModels = + DataModelNode.getQueryDataModels(scope, schema, ontologyQueryParam); + if (dataModels == null || dataModels.isEmpty()) { + throw new Exception("data model not found"); + } + isAgg = getAgg(dataModels.get(0)); + + // build level by level + LinkedList builders = new LinkedList<>(); + builders.add(new SourceRender()); + builders.add(new FilterRender()); + builders.add(new OutputRender()); + ListIterator it = builders.listIterator(); + int i = 0; + Renderer previous = null; + while (it.hasNext()) { + Renderer renderer = it.next(); + if (previous != null) { + previous.render(ontologyQueryParam, dataModels, scope, schema, !isAgg); + renderer.setTable(previous + .builderAs(DataModelNode.getNames(dataModels) + "_" + String.valueOf(i))); + i++; + } + previous = renderer; + } + builders.getLast().render(ontologyQueryParam, dataModels, scope, schema, !isAgg); + parserNode = builders.getLast().builder(); + } + + private boolean getAgg(DataModel dataModel) { + if (!AggOption.DEFAULT.equals(aggOption)) { + return AggOption.isAgg(aggOption); + } + // default by dataModel time aggregation + if (Objects.nonNull(dataModel.getAggTime()) && !dataModel.getAggTime() + .equalsIgnoreCase(Constants.DIMENSION_TYPE_TIME_GRANULARITY_NONE)) { + if (!ontologyQueryParam.isNativeQuery()) { + return true; + } + } + return isAgg; + } + + public String getSql(EngineType engineType) { + return SemanticNode.getSql(parserNode, engineType); + } + + private void optimizeParseNode(EngineType engineType) { + if (Objects.isNull(schema.getRuntimeOptions()) + || Objects.isNull(schema.getRuntimeOptions().getEnableOptimize()) + || !schema.getRuntimeOptions().getEnableOptimize()) { + return; + } + + SqlNode optimizeNode = null; + try { + SqlNode sqlNode = SqlParser.create(SemanticNode.getSql(parserNode, engineType), + Configuration.getParserConfig(engineType)).parseStmt(); + if (Objects.nonNull(sqlNode)) { + optimizeNode = SemanticNode.optimize(scope, schema, sqlNode, engineType); + } + } catch (Exception e) { + log.error("optimize error {}", e); + } + + if (Objects.nonNull(optimizeNode)) { + parserNode = optimizeNode; + } + } + +} diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/TableView.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/TableView.java similarity index 92% rename from headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/TableView.java rename to headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/TableView.java index 74828fbc2..5974ce419 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/TableView.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/TableView.java @@ -1,6 +1,6 @@ -package com.tencent.supersonic.headless.core.translator.calcite.sql; +package com.tencent.supersonic.headless.core.translator.parser.calcite; -import com.tencent.supersonic.headless.core.translator.calcite.s2sql.DataModel; +import com.tencent.supersonic.headless.core.translator.parser.s2sql.DataModel; import lombok.Data; import org.apache.calcite.sql.SqlBasicCall; import org.apache.calcite.sql.SqlKind; diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/node/AggFunctionNode.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/node/AggFunctionNode.java similarity index 92% rename from headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/node/AggFunctionNode.java rename to headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/node/AggFunctionNode.java index 54d0b7981..75fc1cf65 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/node/AggFunctionNode.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/node/AggFunctionNode.java @@ -1,4 +1,4 @@ -package com.tencent.supersonic.headless.core.translator.calcite.sql.node; +package com.tencent.supersonic.headless.core.translator.parser.calcite.node; import com.tencent.supersonic.common.pojo.enums.EngineType; import org.apache.calcite.sql.SqlNode; diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/node/DataModelNode.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/node/DataModelNode.java similarity index 55% rename from headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/node/DataModelNode.java rename to headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/node/DataModelNode.java index 73c5c422e..66113ab9b 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/node/DataModelNode.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/node/DataModelNode.java @@ -1,39 +1,20 @@ -package com.tencent.supersonic.headless.core.translator.calcite.sql.node; +package com.tencent.supersonic.headless.core.translator.parser.calcite.node; import com.google.common.collect.Lists; import com.tencent.supersonic.common.calcite.Configuration; import com.tencent.supersonic.common.jsqlparser.SqlSelectHelper; import com.tencent.supersonic.common.pojo.enums.EngineType; -import com.tencent.supersonic.headless.core.pojo.MetricQueryParam; -import com.tencent.supersonic.headless.core.translator.calcite.s2sql.Constants; -import com.tencent.supersonic.headless.core.translator.calcite.s2sql.DataModel; -import com.tencent.supersonic.headless.core.translator.calcite.s2sql.Dimension; -import com.tencent.supersonic.headless.core.translator.calcite.s2sql.Identify; -import com.tencent.supersonic.headless.core.translator.calcite.s2sql.JoinRelation; -import com.tencent.supersonic.headless.core.translator.calcite.s2sql.Measure; -import com.tencent.supersonic.headless.core.translator.calcite.sql.S2CalciteSchema; -import com.tencent.supersonic.headless.core.translator.calcite.sql.SchemaBuilder; +import com.tencent.supersonic.headless.core.translator.parser.calcite.S2CalciteSchema; +import com.tencent.supersonic.headless.core.translator.parser.calcite.SchemaBuilder; +import com.tencent.supersonic.headless.core.translator.parser.s2sql.*; import lombok.extern.slf4j.Slf4j; -import org.apache.calcite.sql.SqlBasicCall; -import org.apache.calcite.sql.SqlDataTypeSpec; -import org.apache.calcite.sql.SqlNode; -import org.apache.calcite.sql.SqlNodeList; -import org.apache.calcite.sql.SqlUserDefinedTypeNameSpec; +import org.apache.calcite.sql.*; import org.apache.calcite.sql.parser.SqlParser; import org.apache.calcite.sql.parser.SqlParserPos; import org.apache.calcite.sql.validate.SqlValidatorScope; import org.springframework.util.CollectionUtils; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Comparator; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; -import java.util.Set; +import java.util.*; import java.util.stream.Collectors; @Slf4j @@ -53,7 +34,7 @@ public class DataModelNode extends SemanticNode { } } if (sqlTable.isEmpty()) { - throw new Exception("DatasourceNode build error [tableSqlNode not found]"); + throw new Exception("DataModelNode build error [tableSqlNode not found]"); } SqlNode source = getTable(sqlTable, scope, EngineType.fromString(dataModel.getType())); addSchema(scope, dataModel, sqlTable); @@ -149,168 +130,171 @@ public class DataModelNode extends SemanticNode { return dataModelList.stream().map(d -> d.getName()).collect(Collectors.joining("_")); } - public static void getQueryDimensionMeasure(S2CalciteSchema schema, - MetricQueryParam metricCommand, Set queryDimension, List measures) { - queryDimension.addAll(metricCommand.getDimensions().stream() + public static void getQueryDimensionMeasure(Ontology ontology, OntologyQueryParam queryParam, + Set queryDimensions, Set queryMeasures) { + queryDimensions.addAll(queryParam.getDimensions().stream() .map(d -> d.contains(Constants.DIMENSION_IDENTIFY) ? d.split(Constants.DIMENSION_IDENTIFY)[1] : d) .collect(Collectors.toSet())); Set schemaMetricName = - schema.getMetrics().stream().map(m -> m.getName()).collect(Collectors.toSet()); - schema.getMetrics().stream().filter(m -> metricCommand.getMetrics().contains(m.getName())) + ontology.getMetrics().stream().map(m -> m.getName()).collect(Collectors.toSet()); + ontology.getMetrics().stream().filter(m -> queryParam.getMetrics().contains(m.getName())) .forEach(m -> m.getMetricTypeParams().getMeasures().stream() - .forEach(mm -> measures.add(mm.getName()))); - metricCommand.getMetrics().stream().filter(m -> !schemaMetricName.contains(m)) - .forEach(m -> measures.add(m)); + .forEach(mm -> queryMeasures.add(mm.getName()))); + queryParam.getMetrics().stream().filter(m -> !schemaMetricName.contains(m)) + .forEach(m -> queryMeasures.add(m)); } - public static void mergeQueryFilterDimensionMeasure(S2CalciteSchema schema, - MetricQueryParam metricCommand, Set queryDimension, List measures, + public static void mergeQueryFilterDimensionMeasure(Ontology ontology, + OntologyQueryParam queryParam, Set dimensions, Set measures, SqlValidatorScope scope) throws Exception { - EngineType engineType = EngineType.fromString(schema.getOntology().getDatabase().getType()); - if (Objects.nonNull(metricCommand.getWhere()) && !metricCommand.getWhere().isEmpty()) { + EngineType engineType = ontology.getDatabase().getType(); + if (Objects.nonNull(queryParam.getWhere()) && !queryParam.getWhere().isEmpty()) { Set filterConditions = new HashSet<>(); - FilterNode.getFilterField(parse(metricCommand.getWhere(), scope, engineType), + FilterNode.getFilterField(parse(queryParam.getWhere(), scope, engineType), filterConditions); Set queryMeasures = new HashSet<>(measures); - Set schemaMetricName = - schema.getMetrics().stream().map(m -> m.getName()).collect(Collectors.toSet()); + Set schemaMetricName = ontology.getMetrics().stream().map(m -> m.getName()) + .collect(Collectors.toSet()); for (String filterCondition : filterConditions) { if (schemaMetricName.contains(filterCondition)) { - schema.getMetrics().stream() + ontology.getMetrics().stream() .filter(m -> m.getName().equalsIgnoreCase(filterCondition)) .forEach(m -> m.getMetricTypeParams().getMeasures().stream() .forEach(mm -> queryMeasures.add(mm.getName()))); continue; } - queryDimension.add(filterCondition); + dimensions.add(filterCondition); } measures.clear(); measures.addAll(queryMeasures); } } - public static List getRelatedDataModels(SqlValidatorScope scope, - S2CalciteSchema schema, MetricQueryParam metricCommand) throws Exception { - List dataModels = new ArrayList<>(); + public static List getQueryDataModels(SqlValidatorScope scope, + S2CalciteSchema schema, OntologyQueryParam queryParam) throws Exception { + Ontology ontology = schema.getOntology(); + // get query measures and dimensions + Set queryMeasures = new HashSet<>(); + Set queryDimensions = new HashSet<>(); + getQueryDimensionMeasure(ontology, queryParam, queryDimensions, queryMeasures); + mergeQueryFilterDimensionMeasure(ontology, queryParam, queryDimensions, queryMeasures, + scope); - // check by metric - List measures = new ArrayList<>(); - Set queryDimension = new HashSet<>(); - getQueryDimensionMeasure(schema, metricCommand, queryDimension, measures); - DataModel baseDataModel = null; - // one , match measure count - Map dataSourceMeasures = new HashMap<>(); - for (Map.Entry entry : schema.getDataModels().entrySet()) { - Set sourceMeasure = entry.getValue().getMeasures().stream() - .map(mm -> mm.getName()).collect(Collectors.toSet()); - sourceMeasure.retainAll(measures); - dataSourceMeasures.put(entry.getKey(), sourceMeasure.size()); + // first, find the base model + DataModel baseDataModel = findBaseModel(ontology, queryMeasures, queryDimensions); + if (Objects.isNull(baseDataModel)) { + throw new RuntimeException( + String.format("could not find matching dataModel, dimensions:%s, measures:%s", + queryDimensions, queryMeasures)); } - log.info("dataSourceMeasures [{}]", dataSourceMeasures); - Optional> base = dataSourceMeasures.entrySet().stream() - .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())).findFirst(); - if (base.isPresent()) { - baseDataModel = schema.getDataModels().get(base.get().getKey()); - dataModels.add(baseDataModel); - } - // second , check match all dimension and metric - if (baseDataModel != null) { - Set filterMeasure = new HashSet<>(); - Set sourceMeasure = baseDataModel.getMeasures().stream().map(mm -> mm.getName()) - .collect(Collectors.toSet()); - Set dimension = baseDataModel.getDimensions().stream().map(dd -> dd.getName()) - .collect(Collectors.toSet()); - baseDataModel.getIdentifiers().stream().forEach(i -> dimension.add(i.getName())); - if (schema.getDimensions().containsKey(baseDataModel.getName())) { - schema.getDimensions().get(baseDataModel.getName()).stream() - .forEach(d -> dimension.add(d.getName())); - } - filterMeasure.addAll(sourceMeasure); - filterMeasure.addAll(dimension); - EngineType engineType = - EngineType.fromString(schema.getOntology().getDatabase().getType()); - mergeQueryFilterDimensionMeasure(schema, metricCommand, queryDimension, measures, - scope); - boolean isAllMatch = checkMatch(sourceMeasure, queryDimension, measures, dimension, - metricCommand, scope, engineType); - if (isAllMatch) { - log.debug("baseDataModel match all "); - return dataModels; - } - // find all dataSource has the same identifiers - List linkDataModels = getLinkDataSourcesByJoinRelation(queryDimension, - measures, baseDataModel, schema); - if (CollectionUtils.isEmpty(linkDataModels)) { - log.debug("baseDataModel get by identifiers "); - Set baseIdentifiers = baseDataModel.getIdentifiers().stream() - .map(i -> i.getName()).collect(Collectors.toSet()); - if (baseIdentifiers.isEmpty()) { - throw new Exception( - "datasource error : " + baseDataModel.getName() + " miss identifier"); - } - linkDataModels = getLinkDataSources(baseIdentifiers, queryDimension, measures, - baseDataModel, schema); - if (linkDataModels.isEmpty()) { - throw new Exception(String.format( - "not find the match datasource : dimension[%s],measure[%s]", - queryDimension, measures)); - } - } - log.debug("linkDataModels {}", linkDataModels); - return linkDataModels; - // dataModels.addAll(linkDataModels); + // if the base model matches all queried measures and dimensions, just return + if (checkMatch(baseDataModel, queryMeasures, queryDimensions)) { + log.debug("baseDataModel match all measures and dimensions"); + return Collections.singletonList(baseDataModel); } - return dataModels; + // second, traverse the ontology to find other related dataModels + List relatedDataModels = findRelatedModelsByRelation(ontology, baseDataModel, + queryDimensions, queryMeasures); + if (CollectionUtils.isEmpty(relatedDataModels)) { + relatedDataModels = findRelatedModelsByIdentifier(ontology, baseDataModel, + queryDimensions, queryMeasures); + } + if (CollectionUtils.isEmpty(relatedDataModels)) { + relatedDataModels = Collections.singletonList(baseDataModel); + } + + log.debug("relatedDataModels {}", relatedDataModels); + return relatedDataModels; } - private static boolean checkMatch(Set sourceMeasure, Set queryDimension, - List measures, Set dimension, MetricQueryParam metricCommand, - SqlValidatorScope scope, EngineType engineType) throws Exception { - boolean isAllMatch = true; - sourceMeasure.retainAll(measures); - if (sourceMeasure.size() < measures.size()) { - log.info("baseDataSource measures not match all measure"); - // check dimension again - Set dimensionMeasures = new HashSet<>(); - dimensionMeasures.addAll(dimension); - dimensionMeasures.retainAll(measures); - if (sourceMeasure.size() + dimensionMeasures.size() < measures.size()) { - log.info("baseDataSource not match all measure"); - isAllMatch = false; + private static DataModel findBaseModel(Ontology ontology, Set queryMeasures, + Set queryDimensions) { + DataModel dataModel = null; + // first, try to find the model with the most matching measures + Map dataModelMeasuresCount = new HashMap<>(); + for (Map.Entry entry : ontology.getDataModelMap().entrySet()) { + Set sourceMeasure = entry.getValue().getMeasures().stream() + .map(Measure::getName).collect(Collectors.toSet()); + sourceMeasure.retainAll(queryMeasures); + dataModelMeasuresCount.put(entry.getKey(), sourceMeasure.size()); + } + log.info("dataModelMeasureCount: [{}]", dataModelMeasuresCount); + Optional> base = + dataModelMeasuresCount.entrySet().stream().filter(e -> e.getValue() > 0) + .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())).findFirst(); + + if (base.isPresent()) { + dataModel = ontology.getDataModelMap().get(base.get().getKey()); + } else { + // second, try to find the model with the most matching dimensions + Map dataModelDimCount = new HashMap<>(); + for (Map.Entry> entry : ontology.getDimensionMap().entrySet()) { + Set modelDimensions = entry.getValue().stream().map(Dimension::getName) + .collect(Collectors.toSet()); + modelDimensions.retainAll(queryDimensions); + dataModelDimCount.put(entry.getKey(), modelDimensions.size()); + } + log.info("dataModelDimCount: [{}]", dataModelDimCount); + base = dataModelDimCount.entrySet().stream().filter(e -> e.getValue() > 0) + .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())).findFirst(); + if (base.isPresent()) { + dataModel = ontology.getDataModelMap().get(base.get().getKey()); } } - measures.removeAll(sourceMeasure); - dimension.retainAll(queryDimension); - if (dimension.size() < queryDimension.size()) { - log.debug("baseDataSource not match all dimension"); + return dataModel; + } + + private static boolean checkMatch(DataModel baseDataModel, Set queryMeasures, + Set queryDimension) { + boolean isAllMatch = true; + Set baseMeasures = baseDataModel.getMeasures().stream().map(Measure::getName) + .collect(Collectors.toSet()); + Set baseDimensions = baseDataModel.getDimensions().stream().map(Dimension::getName) + .collect(Collectors.toSet()); + baseDataModel.getIdentifiers().stream().forEach(i -> baseDimensions.add(i.getName())); + + baseMeasures.retainAll(queryMeasures); + if (baseMeasures.size() < queryMeasures.size()) { + // check dimension again + Set dimensionMeasures = new HashSet<>(); + dimensionMeasures.addAll(baseDimensions); + dimensionMeasures.retainAll(queryMeasures); + if (baseMeasures.size() + dimensionMeasures.size() < queryMeasures.size()) { + log.info("baseDataModel not match all measures"); + isAllMatch = false; + } + queryMeasures.removeAll(dimensionMeasures); + } + queryMeasures.removeAll(baseMeasures); + + baseDimensions.retainAll(queryDimension); + if (baseDimensions.size() < queryDimension.size()) { + log.debug("baseDataModel not match all dimensions"); isAllMatch = false; } - queryDimension.removeAll(dimension); + queryDimension.removeAll(baseDimensions); - if (metricCommand.getWhere() != null && !metricCommand.getWhere().isEmpty()) { - Set whereFields = new HashSet<>(); - SqlNode sqlNode = parse(metricCommand.getWhere(), scope, engineType); - FilterNode.getFilterField(sqlNode, whereFields); - } return isAllMatch; } - private static List getLinkDataSourcesByJoinRelation(Set queryDimension, - List measures, DataModel baseDataModel, S2CalciteSchema schema) { - Set linkDataSourceName = new HashSet<>(); - List linkDataModels = new ArrayList<>(); + private static List findRelatedModelsByRelation(Ontology ontology, + DataModel baseDataModel, Set queryDimensions, Set queryMeasures) { + Set joinDataModelNames = new HashSet<>(); + List joinDataModels = new ArrayList<>(); Set before = new HashSet<>(); before.add(baseDataModel.getName()); - if (!CollectionUtils.isEmpty(schema.getJoinRelations())) { + + if (!CollectionUtils.isEmpty(ontology.getJoinRelations())) { Set visitJoinRelations = new HashSet<>(); List sortedJoinRelation = new ArrayList<>(); - sortJoinRelation(schema.getJoinRelations(), baseDataModel.getName(), visitJoinRelations, - sortedJoinRelation); - schema.getJoinRelations().stream().filter(j -> !visitJoinRelations.contains(j.getId())) + sortJoinRelation(ontology.getJoinRelations(), baseDataModel.getName(), + visitJoinRelations, sortedJoinRelation); + ontology.getJoinRelations().stream() + .filter(j -> !visitJoinRelations.contains(j.getId())) .forEach(j -> sortedJoinRelation.add(j)); for (JoinRelation joinRelation : sortedJoinRelation) { if (!before.contains(joinRelation.getLeft()) @@ -319,53 +303,54 @@ public class DataModelNode extends SemanticNode { } boolean isMatch = false; boolean isRight = before.contains(joinRelation.getLeft()); - DataModel other = isRight ? schema.getDataModels().get(joinRelation.getRight()) - : schema.getDataModels().get(joinRelation.getLeft()); - if (!queryDimension.isEmpty()) { + DataModel other = isRight ? ontology.getDataModelMap().get(joinRelation.getRight()) + : ontology.getDataModelMap().get(joinRelation.getLeft()); + if (!queryDimensions.isEmpty()) { Set linkDimension = other.getDimensions().stream() .map(dd -> dd.getName()).collect(Collectors.toSet()); other.getIdentifiers().stream().forEach(i -> linkDimension.add(i.getName())); - linkDimension.retainAll(queryDimension); + linkDimension.retainAll(queryDimensions); if (!linkDimension.isEmpty()) { isMatch = true; } } - Set linkMeasure = other.getMeasures().stream().map(mm -> mm.getName()) + Set linkMeasure = other.getMeasures().stream().map(Measure::getName) .collect(Collectors.toSet()); - linkMeasure.retainAll(measures); + linkMeasure.retainAll(queryMeasures); if (!linkMeasure.isEmpty()) { isMatch = true; } - if (!isMatch && schema.getDimensions().containsKey(other.getName())) { - Set linkDimension = schema.getDimensions().get(other.getName()).stream() - .map(dd -> dd.getName()).collect(Collectors.toSet()); - linkDimension.retainAll(queryDimension); + if (!isMatch && ontology.getDimensionMap().containsKey(other.getName())) { + Set linkDimension = ontology.getDimensionMap().get(other.getName()) + .stream().map(dd -> dd.getName()).collect(Collectors.toSet()); + linkDimension.retainAll(queryDimensions); if (!linkDimension.isEmpty()) { isMatch = true; } } if (isMatch) { - linkDataSourceName.add(other.getName()); + joinDataModelNames.add(other.getName()); before.add(other.getName()); } } } - if (!CollectionUtils.isEmpty(linkDataSourceName)) { + if (!CollectionUtils.isEmpty(joinDataModelNames)) { Map orders = new HashMap<>(); - linkDataSourceName.add(baseDataModel.getName()); + joinDataModelNames.add(baseDataModel.getName()); orders.put(baseDataModel.getName(), 0L); - for (JoinRelation joinRelation : schema.getJoinRelations()) { - if (linkDataSourceName.contains(joinRelation.getLeft()) - && linkDataSourceName.contains(joinRelation.getRight())) { + for (JoinRelation joinRelation : ontology.getJoinRelations()) { + if (joinDataModelNames.contains(joinRelation.getLeft()) + && joinDataModelNames.contains(joinRelation.getRight())) { orders.put(joinRelation.getLeft(), 0L); orders.put(joinRelation.getRight(), 1L); } } orders.entrySet().stream().sorted(Map.Entry.comparingByValue()).forEach(d -> { - linkDataModels.add(schema.getDataModels().get(d.getKey())); + joinDataModels.add(ontology.getDataModelMap().get(d.getKey())); }); } - return linkDataModels; + + return joinDataModels; } private static void sortJoinRelation(List joinRelations, String next, @@ -383,12 +368,17 @@ public class DataModelNode extends SemanticNode { } } - private static List getLinkDataSources(Set baseIdentifiers, - Set queryDimension, List measures, DataModel baseDataModel, - S2CalciteSchema schema) { + private static List findRelatedModelsByIdentifier(Ontology ontology, + DataModel baseDataModel, Set queryDimension, Set measures) { + Set baseIdentifiers = baseDataModel.getIdentifiers().stream().map(Identify::getName) + .collect(Collectors.toSet()); + if (baseIdentifiers.isEmpty()) { + return Collections.EMPTY_LIST; + } + Set linkDataSourceName = new HashSet<>(); List linkDataModels = new ArrayList<>(); - for (Map.Entry entry : schema.getDataModels().entrySet()) { + for (Map.Entry entry : ontology.getDataModelMap().entrySet()) { if (entry.getKey().equalsIgnoreCase(baseDataModel.getName())) { continue; } @@ -419,9 +409,9 @@ public class DataModelNode extends SemanticNode { } } } - for (Map.Entry> entry : schema.getDimensions().entrySet()) { + for (Map.Entry> entry : ontology.getDimensionMap().entrySet()) { if (!queryDimension.isEmpty()) { - Set linkDimension = entry.getValue().stream().map(dd -> dd.getName()) + Set linkDimension = entry.getValue().stream().map(Dimension::getName) .collect(Collectors.toSet()); linkDimension.retainAll(queryDimension); if (!linkDimension.isEmpty()) { @@ -430,7 +420,7 @@ public class DataModelNode extends SemanticNode { } } for (String linkName : linkDataSourceName) { - linkDataModels.add(schema.getDataModels().get(linkName)); + linkDataModels.add(ontology.getDataModelMap().get(linkName)); } if (!CollectionUtils.isEmpty(linkDataModels)) { List all = new ArrayList<>(); @@ -440,4 +430,5 @@ public class DataModelNode extends SemanticNode { } return Lists.newArrayList(); } + } diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/node/DimensionNode.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/node/DimensionNode.java similarity index 90% rename from headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/node/DimensionNode.java rename to headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/node/DimensionNode.java index 6119e33ba..0328917f6 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/node/DimensionNode.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/node/DimensionNode.java @@ -1,8 +1,8 @@ -package com.tencent.supersonic.headless.core.translator.calcite.sql.node; +package com.tencent.supersonic.headless.core.translator.parser.calcite.node; import com.tencent.supersonic.common.pojo.enums.EngineType; -import com.tencent.supersonic.headless.core.translator.calcite.s2sql.Constants; -import com.tencent.supersonic.headless.core.translator.calcite.s2sql.Dimension; +import com.tencent.supersonic.headless.core.translator.parser.s2sql.Constants; +import com.tencent.supersonic.headless.core.translator.parser.s2sql.Dimension; import org.apache.calcite.sql.SqlNode; import org.apache.calcite.sql.validate.SqlValidatorScope; diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/node/ExtendNode.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/node/ExtendNode.java similarity index 94% rename from headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/node/ExtendNode.java rename to headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/node/ExtendNode.java index d0a6b6e47..f5ff9ca7d 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/node/ExtendNode.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/node/ExtendNode.java @@ -1,4 +1,4 @@ -package com.tencent.supersonic.headless.core.translator.calcite.sql.node; +package com.tencent.supersonic.headless.core.translator.parser.calcite.node; import org.apache.calcite.sql.SqlCall; import org.apache.calcite.sql.SqlInternalOperator; diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/node/FilterNode.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/node/FilterNode.java similarity index 91% rename from headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/node/FilterNode.java rename to headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/node/FilterNode.java index ba8993de1..4528a3751 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/node/FilterNode.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/node/FilterNode.java @@ -1,4 +1,4 @@ -package com.tencent.supersonic.headless.core.translator.calcite.sql.node; +package com.tencent.supersonic.headless.core.translator.parser.calcite.node; import org.apache.calcite.sql.SqlBasicCall; import org.apache.calcite.sql.SqlIdentifier; diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/node/IdentifyNode.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/node/IdentifyNode.java similarity index 90% rename from headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/node/IdentifyNode.java rename to headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/node/IdentifyNode.java index d42ef4948..f2b7a03cb 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/node/IdentifyNode.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/node/IdentifyNode.java @@ -1,7 +1,7 @@ -package com.tencent.supersonic.headless.core.translator.calcite.sql.node; +package com.tencent.supersonic.headless.core.translator.parser.calcite.node; import com.tencent.supersonic.common.pojo.enums.EngineType; -import com.tencent.supersonic.headless.core.translator.calcite.s2sql.Identify; +import com.tencent.supersonic.headless.core.translator.parser.s2sql.Identify; import org.apache.calcite.sql.SqlNode; import org.apache.calcite.sql.validate.SqlValidatorScope; diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/node/LateralViewExplodeNode.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/node/LateralViewExplodeNode.java similarity index 97% rename from headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/node/LateralViewExplodeNode.java rename to headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/node/LateralViewExplodeNode.java index 920bd9a1c..5a2db5a72 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/node/LateralViewExplodeNode.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/node/LateralViewExplodeNode.java @@ -1,4 +1,4 @@ -package com.tencent.supersonic.headless.core.translator.calcite.sql.node; +package com.tencent.supersonic.headless.core.translator.parser.calcite.node; import org.apache.calcite.linq4j.Ord; import org.apache.calcite.sql.SqlCall; diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/node/MeasureNode.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/node/MeasureNode.java similarity index 89% rename from headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/node/MeasureNode.java rename to headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/node/MeasureNode.java index 41638d097..1dd815fdd 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/node/MeasureNode.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/node/MeasureNode.java @@ -1,7 +1,7 @@ -package com.tencent.supersonic.headless.core.translator.calcite.sql.node; +package com.tencent.supersonic.headless.core.translator.parser.calcite.node; import com.tencent.supersonic.common.pojo.enums.EngineType; -import com.tencent.supersonic.headless.core.translator.calcite.s2sql.Measure; +import com.tencent.supersonic.headless.core.translator.parser.s2sql.Measure; import org.apache.calcite.sql.SqlNode; import org.apache.calcite.sql.validate.SqlValidatorScope; diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/node/MetricNode.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/node/MetricNode.java similarity index 86% rename from headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/node/MetricNode.java rename to headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/node/MetricNode.java index fe4ac64d5..34bc55c31 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/node/MetricNode.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/node/MetricNode.java @@ -1,8 +1,8 @@ -package com.tencent.supersonic.headless.core.translator.calcite.sql.node; +package com.tencent.supersonic.headless.core.translator.parser.calcite.node; import com.tencent.supersonic.common.pojo.enums.EngineType; -import com.tencent.supersonic.headless.core.translator.calcite.s2sql.Metric; -import com.tencent.supersonic.headless.core.translator.calcite.sql.S2CalciteSchema; +import com.tencent.supersonic.headless.core.translator.parser.calcite.S2CalciteSchema; +import com.tencent.supersonic.headless.core.translator.parser.s2sql.Metric; import lombok.Data; import org.apache.calcite.sql.SqlNode; import org.apache.calcite.sql.validate.SqlValidatorScope; diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/node/SemanticNode.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/node/SemanticNode.java similarity index 98% rename from headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/node/SemanticNode.java rename to headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/node/SemanticNode.java index 4f3849e2b..88f2a7d80 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/node/SemanticNode.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/node/SemanticNode.java @@ -1,12 +1,12 @@ -package com.tencent.supersonic.headless.core.translator.calcite.sql.node; +package com.tencent.supersonic.headless.core.translator.parser.calcite.node; import com.tencent.supersonic.common.calcite.Configuration; import com.tencent.supersonic.common.calcite.SemanticSqlDialect; import com.tencent.supersonic.common.calcite.SqlDialectFactory; import com.tencent.supersonic.common.pojo.enums.EngineType; -import com.tencent.supersonic.headless.core.translator.calcite.s2sql.Constants; -import com.tencent.supersonic.headless.core.translator.calcite.sql.FilterToGroupScanRule; -import com.tencent.supersonic.headless.core.translator.calcite.sql.S2CalciteSchema; +import com.tencent.supersonic.headless.core.translator.parser.calcite.FilterToGroupScanRule; +import com.tencent.supersonic.headless.core.translator.parser.calcite.S2CalciteSchema; +import com.tencent.supersonic.headless.core.translator.parser.s2sql.Constants; import lombok.extern.slf4j.Slf4j; import org.apache.calcite.plan.RelOptPlanner; import org.apache.calcite.plan.hep.HepPlanner; diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/render/FilterRender.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/render/FilterRender.java similarity index 75% rename from headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/render/FilterRender.java rename to headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/render/FilterRender.java index fd058739a..58993f49c 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/render/FilterRender.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/render/FilterRender.java @@ -1,15 +1,15 @@ -package com.tencent.supersonic.headless.core.translator.calcite.sql.render; +package com.tencent.supersonic.headless.core.translator.parser.calcite.render; import com.tencent.supersonic.common.pojo.enums.EngineType; -import com.tencent.supersonic.headless.core.pojo.MetricQueryParam; -import com.tencent.supersonic.headless.core.translator.calcite.s2sql.Constants; -import com.tencent.supersonic.headless.core.translator.calcite.s2sql.DataModel; -import com.tencent.supersonic.headless.core.translator.calcite.s2sql.Metric; -import com.tencent.supersonic.headless.core.translator.calcite.sql.S2CalciteSchema; -import com.tencent.supersonic.headless.core.translator.calcite.sql.TableView; -import com.tencent.supersonic.headless.core.translator.calcite.sql.node.FilterNode; -import com.tencent.supersonic.headless.core.translator.calcite.sql.node.MetricNode; -import com.tencent.supersonic.headless.core.translator.calcite.sql.node.SemanticNode; +import com.tencent.supersonic.headless.core.translator.parser.calcite.S2CalciteSchema; +import com.tencent.supersonic.headless.core.translator.parser.calcite.TableView; +import com.tencent.supersonic.headless.core.translator.parser.calcite.node.FilterNode; +import com.tencent.supersonic.headless.core.translator.parser.calcite.node.MetricNode; +import com.tencent.supersonic.headless.core.translator.parser.calcite.node.SemanticNode; +import com.tencent.supersonic.headless.core.translator.parser.s2sql.Constants; +import com.tencent.supersonic.headless.core.translator.parser.s2sql.DataModel; +import com.tencent.supersonic.headless.core.translator.parser.s2sql.Metric; +import com.tencent.supersonic.headless.core.translator.parser.s2sql.OntologyQueryParam; import org.apache.calcite.sql.SqlIdentifier; import org.apache.calcite.sql.SqlNode; import org.apache.calcite.sql.parser.SqlParserPos; @@ -26,13 +26,13 @@ import java.util.stream.Collectors; public class FilterRender extends Renderer { @Override - public void render(MetricQueryParam metricCommand, List dataModels, + public void render(OntologyQueryParam metricCommand, List dataModels, SqlValidatorScope scope, S2CalciteSchema schema, boolean nonAgg) throws Exception { TableView tableView = super.tableView; SqlNode filterNode = null; List queryMetrics = new ArrayList<>(metricCommand.getMetrics()); List queryDimensions = new ArrayList<>(metricCommand.getDimensions()); - EngineType engineType = EngineType.fromString(schema.getOntology().getDatabase().getType()); + EngineType engineType = schema.getOntology().getDatabase().getType(); if (metricCommand.getWhere() != null && !metricCommand.getWhere().isEmpty()) { filterNode = SemanticNode.parse(metricCommand.getWhere(), scope, engineType); diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/render/JoinRender.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/render/JoinRender.java similarity index 89% rename from headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/render/JoinRender.java rename to headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/render/JoinRender.java index a74b85934..ba63fc91b 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/render/JoinRender.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/render/JoinRender.java @@ -1,22 +1,22 @@ -package com.tencent.supersonic.headless.core.translator.calcite.sql.render; +package com.tencent.supersonic.headless.core.translator.parser.calcite.render; import com.tencent.supersonic.common.pojo.enums.EngineType; -import com.tencent.supersonic.headless.core.pojo.MetricQueryParam; -import com.tencent.supersonic.headless.core.translator.calcite.s2sql.Constants; -import com.tencent.supersonic.headless.core.translator.calcite.s2sql.DataModel; -import com.tencent.supersonic.headless.core.translator.calcite.s2sql.Dimension; -import com.tencent.supersonic.headless.core.translator.calcite.s2sql.Identify; -import com.tencent.supersonic.headless.core.translator.calcite.s2sql.JoinRelation; -import com.tencent.supersonic.headless.core.translator.calcite.s2sql.Materialization; -import com.tencent.supersonic.headless.core.translator.calcite.s2sql.Metric; -import com.tencent.supersonic.headless.core.translator.calcite.sql.S2CalciteSchema; -import com.tencent.supersonic.headless.core.translator.calcite.sql.TableView; -import com.tencent.supersonic.headless.core.translator.calcite.sql.node.AggFunctionNode; -import com.tencent.supersonic.headless.core.translator.calcite.sql.node.DataModelNode; -import com.tencent.supersonic.headless.core.translator.calcite.sql.node.FilterNode; -import com.tencent.supersonic.headless.core.translator.calcite.sql.node.IdentifyNode; -import com.tencent.supersonic.headless.core.translator.calcite.sql.node.MetricNode; -import com.tencent.supersonic.headless.core.translator.calcite.sql.node.SemanticNode; +import com.tencent.supersonic.headless.core.translator.parser.calcite.S2CalciteSchema; +import com.tencent.supersonic.headless.core.translator.parser.calcite.TableView; +import com.tencent.supersonic.headless.core.translator.parser.calcite.node.AggFunctionNode; +import com.tencent.supersonic.headless.core.translator.parser.calcite.node.DataModelNode; +import com.tencent.supersonic.headless.core.translator.parser.calcite.node.FilterNode; +import com.tencent.supersonic.headless.core.translator.parser.calcite.node.IdentifyNode; +import com.tencent.supersonic.headless.core.translator.parser.calcite.node.MetricNode; +import com.tencent.supersonic.headless.core.translator.parser.calcite.node.SemanticNode; +import com.tencent.supersonic.headless.core.translator.parser.s2sql.Constants; +import com.tencent.supersonic.headless.core.translator.parser.s2sql.DataModel; +import com.tencent.supersonic.headless.core.translator.parser.s2sql.Dimension; +import com.tencent.supersonic.headless.core.translator.parser.s2sql.Identify; +import com.tencent.supersonic.headless.core.translator.parser.s2sql.JoinRelation; +import com.tencent.supersonic.headless.core.translator.parser.s2sql.Materialization; +import com.tencent.supersonic.headless.core.translator.parser.s2sql.Metric; +import com.tencent.supersonic.headless.core.translator.parser.s2sql.OntologyQueryParam; import lombok.extern.slf4j.Slf4j; import org.apache.calcite.sql.JoinConditionType; import org.apache.calcite.sql.SqlBasicCall; @@ -47,10 +47,10 @@ import java.util.stream.Collectors; public class JoinRender extends Renderer { @Override - public void render(MetricQueryParam metricCommand, List dataModels, + public void render(OntologyQueryParam metricCommand, List dataModels, SqlValidatorScope scope, S2CalciteSchema schema, boolean nonAgg) throws Exception { String queryWhere = metricCommand.getWhere(); - EngineType engineType = EngineType.fromString(schema.getOntology().getDatabase().getType()); + EngineType engineType = schema.getOntology().getDatabase().getType(); Set whereFields = new HashSet<>(); List fieldWhere = new ArrayList<>(); if (queryWhere != null && !queryWhere.isEmpty()) { @@ -59,8 +59,9 @@ public class JoinRender extends Renderer { fieldWhere = whereFields.stream().collect(Collectors.toList()); } Set queryAllDimension = new HashSet<>(); - List measures = new ArrayList<>(); - DataModelNode.getQueryDimensionMeasure(schema, metricCommand, queryAllDimension, measures); + Set measures = new HashSet<>(); + DataModelNode.getQueryDimensionMeasure(schema.getOntology(), metricCommand, + queryAllDimension, measures); SqlNode left = null; TableView leftTable = null; TableView innerView = new TableView(); @@ -73,8 +74,8 @@ public class JoinRender extends Renderer { final DataModel dataModel = dataModels.get(i); final Set filterDimensions = new HashSet<>(); final Set filterMetrics = new HashSet<>(); - final List queryDimension = new ArrayList<>(); - final List queryMetrics = new ArrayList<>(); + final Set queryDimension = new HashSet<>(); + final Set queryMetrics = new HashSet<>(); SourceRender.whereDimMetric(fieldWhere, queryMetrics, queryDimension, dataModel, schema, filterDimensions, filterMetrics); List reqMetric = new ArrayList<>(metricCommand.getMetrics()); @@ -142,11 +143,11 @@ public class JoinRender extends Renderer { } private void doMetric(Map innerSelect, TableView filterView, - List queryMetrics, List reqMetrics, DataModel dataModel, + Set queryMetrics, List reqMetrics, DataModel dataModel, Set sourceMeasure, SqlValidatorScope scope, S2CalciteSchema schema, boolean nonAgg) throws Exception { String alias = Constants.JOIN_TABLE_PREFIX + dataModel.getName(); - EngineType engineType = EngineType.fromString(schema.getOntology().getDatabase().getType()); + EngineType engineType = schema.getOntology().getDatabase().getType(); for (String m : reqMetrics) { if (getMatchMetric(schema, sourceMeasure, m, queryMetrics)) { MetricNode metricNode = buildMetricNode(m, dataModel, scope, schema, nonAgg, alias); @@ -177,11 +178,11 @@ public class JoinRender extends Renderer { } private void doDimension(Map innerSelect, Set filterDimension, - List queryDimension, List reqDimensions, DataModel dataModel, + Set queryDimension, List reqDimensions, DataModel dataModel, Set dimension, SqlValidatorScope scope, S2CalciteSchema schema) throws Exception { String alias = Constants.JOIN_TABLE_PREFIX + dataModel.getName(); - EngineType engineType = EngineType.fromString(schema.getOntology().getDatabase().getType()); + EngineType engineType = schema.getOntology().getDatabase().getType(); for (String d : reqDimensions) { if (getMatchDimension(schema, dimension, dataModel, d, queryDimension)) { if (d.contains(Constants.DIMENSION_IDENTIFY)) { @@ -205,7 +206,7 @@ public class JoinRender extends Renderer { } private boolean getMatchMetric(S2CalciteSchema schema, Set sourceMeasure, String m, - List queryMetrics) { + Set queryMetrics) { Optional metric = schema.getMetrics().stream() .filter(mm -> mm.getName().equalsIgnoreCase(m)).findFirst(); boolean isAdd = false; @@ -226,7 +227,7 @@ public class JoinRender extends Renderer { } private boolean getMatchDimension(S2CalciteSchema schema, Set sourceDimension, - DataModel dataModel, String d, List queryDimension) { + DataModel dataModel, String d, Set queryDimension) { String oriDimension = d; boolean isAdd = false; if (d.contains(Constants.DIMENSION_IDENTIFY)) { @@ -261,7 +262,7 @@ public class JoinRender extends Renderer { private SqlNode buildJoin(SqlNode left, TableView leftTable, TableView tableView, Map before, DataModel dataModel, S2CalciteSchema schema, SqlValidatorScope scope) throws Exception { - EngineType engineType = EngineType.fromString(schema.getOntology().getDatabase().getType()); + EngineType engineType = schema.getOntology().getDatabase().getType(); SqlNode condition = getCondition(leftTable, tableView, dataModel, schema, scope, engineType); SqlLiteral sqlLiteral = SemanticNode.getJoinSqlLiteral(""); @@ -454,8 +455,7 @@ public class JoinRender extends Renderer { endTime = zipper.getAlias() + "." + endTimeOp.get().getName(); dateTime = partMetric.getAlias() + "." + partTime.get().getName(); } - EngineType engineType = - EngineType.fromString(schema.getOntology().getDatabase().getType()); + EngineType engineType = schema.getOntology().getDatabase().getType(); ArrayList operandList = new ArrayList<>(Arrays.asList(SemanticNode.parse(endTime, scope, engineType), SemanticNode.parse(dateTime, scope, engineType))); diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/render/OutputRender.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/render/OutputRender.java similarity index 74% rename from headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/render/OutputRender.java rename to headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/render/OutputRender.java index ef20426f9..abee245bd 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/render/OutputRender.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/render/OutputRender.java @@ -1,13 +1,13 @@ -package com.tencent.supersonic.headless.core.translator.calcite.sql.render; +package com.tencent.supersonic.headless.core.translator.parser.calcite.render; import com.tencent.supersonic.common.pojo.ColumnOrder; import com.tencent.supersonic.common.pojo.enums.EngineType; -import com.tencent.supersonic.headless.core.pojo.MetricQueryParam; -import com.tencent.supersonic.headless.core.translator.calcite.s2sql.DataModel; -import com.tencent.supersonic.headless.core.translator.calcite.sql.S2CalciteSchema; -import com.tencent.supersonic.headless.core.translator.calcite.sql.TableView; -import com.tencent.supersonic.headless.core.translator.calcite.sql.node.MetricNode; -import com.tencent.supersonic.headless.core.translator.calcite.sql.node.SemanticNode; +import com.tencent.supersonic.headless.core.translator.parser.calcite.S2CalciteSchema; +import com.tencent.supersonic.headless.core.translator.parser.calcite.TableView; +import com.tencent.supersonic.headless.core.translator.parser.calcite.node.MetricNode; +import com.tencent.supersonic.headless.core.translator.parser.calcite.node.SemanticNode; +import com.tencent.supersonic.headless.core.translator.parser.s2sql.DataModel; +import com.tencent.supersonic.headless.core.translator.parser.s2sql.OntologyQueryParam; import org.apache.calcite.sql.SqlNode; import org.apache.calcite.sql.SqlNodeList; import org.apache.calcite.sql.fun.SqlStdOperatorTable; @@ -22,10 +22,10 @@ import java.util.List; public class OutputRender extends Renderer { @Override - public void render(MetricQueryParam metricCommand, List dataModels, + public void render(OntologyQueryParam metricCommand, List dataModels, SqlValidatorScope scope, S2CalciteSchema schema, boolean nonAgg) throws Exception { TableView selectDataSet = super.tableView; - EngineType engineType = EngineType.fromString(schema.getOntology().getDatabase().getType()); + EngineType engineType = schema.getOntology().getDatabase().getType(); for (String dimension : metricCommand.getDimensions()) { selectDataSet.getMeasure().add(SemanticNode.parse(dimension, scope, engineType)); } diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/render/Renderer.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/render/Renderer.java similarity index 81% rename from headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/render/Renderer.java rename to headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/render/Renderer.java index d4322a411..dfcac8916 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/render/Renderer.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/render/Renderer.java @@ -1,17 +1,17 @@ -package com.tencent.supersonic.headless.core.translator.calcite.sql.render; +package com.tencent.supersonic.headless.core.translator.parser.calcite.render; import com.tencent.supersonic.common.pojo.enums.EngineType; -import com.tencent.supersonic.headless.core.pojo.MetricQueryParam; -import com.tencent.supersonic.headless.core.translator.calcite.s2sql.DataModel; -import com.tencent.supersonic.headless.core.translator.calcite.s2sql.Dimension; -import com.tencent.supersonic.headless.core.translator.calcite.s2sql.Identify; -import com.tencent.supersonic.headless.core.translator.calcite.s2sql.Measure; -import com.tencent.supersonic.headless.core.translator.calcite.s2sql.Metric; -import com.tencent.supersonic.headless.core.translator.calcite.sql.S2CalciteSchema; -import com.tencent.supersonic.headless.core.translator.calcite.sql.TableView; -import com.tencent.supersonic.headless.core.translator.calcite.sql.node.MeasureNode; -import com.tencent.supersonic.headless.core.translator.calcite.sql.node.MetricNode; -import com.tencent.supersonic.headless.core.translator.calcite.sql.node.SemanticNode; +import com.tencent.supersonic.headless.core.translator.parser.calcite.S2CalciteSchema; +import com.tencent.supersonic.headless.core.translator.parser.calcite.TableView; +import com.tencent.supersonic.headless.core.translator.parser.calcite.node.MeasureNode; +import com.tencent.supersonic.headless.core.translator.parser.calcite.node.MetricNode; +import com.tencent.supersonic.headless.core.translator.parser.calcite.node.SemanticNode; +import com.tencent.supersonic.headless.core.translator.parser.s2sql.DataModel; +import com.tencent.supersonic.headless.core.translator.parser.s2sql.Dimension; +import com.tencent.supersonic.headless.core.translator.parser.s2sql.Identify; +import com.tencent.supersonic.headless.core.translator.parser.s2sql.Measure; +import com.tencent.supersonic.headless.core.translator.parser.s2sql.Metric; +import com.tencent.supersonic.headless.core.translator.parser.s2sql.OntologyQueryParam; import lombok.Data; import org.apache.calcite.sql.SqlNode; import org.apache.calcite.sql.validate.SqlValidatorScope; @@ -114,6 +114,6 @@ public abstract class Renderer { return SemanticNode.buildAs(alias, tableView.build()); } - public abstract void render(MetricQueryParam metricCommand, List dataModels, + public abstract void render(OntologyQueryParam metricCommand, List dataModels, SqlValidatorScope scope, S2CalciteSchema schema, boolean nonAgg) throws Exception; } diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/render/SourceRender.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/render/SourceRender.java similarity index 82% rename from headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/render/SourceRender.java rename to headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/render/SourceRender.java index c4eb0d24c..8ac3e0678 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/sql/render/SourceRender.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/calcite/render/SourceRender.java @@ -1,22 +1,22 @@ -package com.tencent.supersonic.headless.core.translator.calcite.sql.render; +package com.tencent.supersonic.headless.core.translator.parser.calcite.render; import com.tencent.supersonic.common.pojo.enums.EngineType; -import com.tencent.supersonic.headless.core.pojo.MetricQueryParam; -import com.tencent.supersonic.headless.core.translator.calcite.s2sql.Constants; -import com.tencent.supersonic.headless.core.translator.calcite.s2sql.DataModel; -import com.tencent.supersonic.headless.core.translator.calcite.s2sql.Dimension; -import com.tencent.supersonic.headless.core.translator.calcite.s2sql.Identify; -import com.tencent.supersonic.headless.core.translator.calcite.s2sql.Materialization; -import com.tencent.supersonic.headless.core.translator.calcite.s2sql.Measure; -import com.tencent.supersonic.headless.core.translator.calcite.s2sql.Metric; -import com.tencent.supersonic.headless.core.translator.calcite.sql.S2CalciteSchema; -import com.tencent.supersonic.headless.core.translator.calcite.sql.TableView; -import com.tencent.supersonic.headless.core.translator.calcite.sql.node.DataModelNode; -import com.tencent.supersonic.headless.core.translator.calcite.sql.node.DimensionNode; -import com.tencent.supersonic.headless.core.translator.calcite.sql.node.FilterNode; -import com.tencent.supersonic.headless.core.translator.calcite.sql.node.IdentifyNode; -import com.tencent.supersonic.headless.core.translator.calcite.sql.node.MetricNode; -import com.tencent.supersonic.headless.core.translator.calcite.sql.node.SemanticNode; +import com.tencent.supersonic.headless.core.translator.parser.calcite.S2CalciteSchema; +import com.tencent.supersonic.headless.core.translator.parser.calcite.TableView; +import com.tencent.supersonic.headless.core.translator.parser.calcite.node.DataModelNode; +import com.tencent.supersonic.headless.core.translator.parser.calcite.node.DimensionNode; +import com.tencent.supersonic.headless.core.translator.parser.calcite.node.FilterNode; +import com.tencent.supersonic.headless.core.translator.parser.calcite.node.IdentifyNode; +import com.tencent.supersonic.headless.core.translator.parser.calcite.node.MetricNode; +import com.tencent.supersonic.headless.core.translator.parser.calcite.node.SemanticNode; +import com.tencent.supersonic.headless.core.translator.parser.s2sql.Constants; +import com.tencent.supersonic.headless.core.translator.parser.s2sql.DataModel; +import com.tencent.supersonic.headless.core.translator.parser.s2sql.Dimension; +import com.tencent.supersonic.headless.core.translator.parser.s2sql.Identify; +import com.tencent.supersonic.headless.core.translator.parser.s2sql.Materialization; +import com.tencent.supersonic.headless.core.translator.parser.s2sql.Measure; +import com.tencent.supersonic.headless.core.translator.parser.s2sql.Metric; +import com.tencent.supersonic.headless.core.translator.parser.s2sql.OntologyQueryParam; import lombok.extern.slf4j.Slf4j; import org.apache.calcite.sql.SqlNode; import org.apache.calcite.sql.validate.SqlValidatorScope; @@ -34,21 +34,21 @@ import java.util.Set; import java.util.UUID; import java.util.stream.Collectors; -import static com.tencent.supersonic.headless.core.translator.calcite.s2sql.Constants.DIMENSION_DELIMITER; +import static com.tencent.supersonic.headless.core.translator.parser.s2sql.Constants.DIMENSION_DELIMITER; /** process the table dataSet from the defined data model schema */ @Slf4j public class SourceRender extends Renderer { public static TableView renderOne(String alias, List fieldWheres, - List reqMetrics, List reqDimensions, String queryWhere, + Set reqMetrics, Set reqDimensions, String queryWhere, DataModel datasource, SqlValidatorScope scope, S2CalciteSchema schema, boolean nonAgg) throws Exception { TableView dataSet = new TableView(); TableView output = new TableView(); - List queryMetrics = new ArrayList<>(reqMetrics); - List queryDimensions = new ArrayList<>(reqDimensions); + Set queryMetrics = new HashSet<>(reqMetrics); + Set queryDimensions = new HashSet<>(reqDimensions); List fieldWhere = new ArrayList<>(fieldWheres); Map extendFields = new HashMap<>(); if (!fieldWhere.isEmpty()) { @@ -57,9 +57,7 @@ public class SourceRender extends Renderer { whereDimMetric(fieldWhere, queryMetrics, queryDimensions, datasource, schema, dimensions, metrics); queryMetrics.addAll(metrics); - queryMetrics = uniqList(queryMetrics); queryDimensions.addAll(dimensions); - queryDimensions = uniqList(queryDimensions); mergeWhere(fieldWhere, dataSet, output, queryMetrics, queryDimensions, extendFields, datasource, scope, schema, nonAgg); } @@ -109,7 +107,7 @@ public class SourceRender extends Renderer { S2CalciteSchema schema, boolean nonAgg, Map extendFields, TableView dataSet, TableView output, SqlValidatorScope scope) throws Exception { List dimensionList = schema.getDimensions().get(datasource.getName()); - EngineType engineType = EngineType.fromString(schema.getOntology().getDatabase().getType()); + EngineType engineType = schema.getOntology().getDatabase().getType(); boolean isAdd = false; if (!CollectionUtils.isEmpty(dimensionList)) { for (Dimension dim : dimensionList) { @@ -182,12 +180,12 @@ public class SourceRender extends Renderer { } } - private static List getWhereMeasure(List fields, List queryMetrics, - List queryDimensions, Map extendFields, DataModel datasource, + private static List getWhereMeasure(List fields, Set queryMetrics, + Set queryDimensions, Map extendFields, DataModel datasource, SqlValidatorScope scope, S2CalciteSchema schema, boolean nonAgg) throws Exception { Iterator iterator = fields.iterator(); List whereNode = new ArrayList<>(); - EngineType engineType = EngineType.fromString(schema.getOntology().getDatabase().getType()); + EngineType engineType = schema.getOntology().getDatabase().getType(); while (iterator.hasNext()) { String cur = iterator.next(); if (queryDimensions.contains(cur) || queryMetrics.contains(cur)) { @@ -224,17 +222,17 @@ public class SourceRender extends Renderer { } private static void mergeWhere(List fields, TableView dataSet, TableView outputSet, - List queryMetrics, List queryDimensions, - Map extendFields, DataModel datasource, SqlValidatorScope scope, - S2CalciteSchema schema, boolean nonAgg) throws Exception { + Set queryMetrics, Set queryDimensions, Map extendFields, + DataModel datasource, SqlValidatorScope scope, S2CalciteSchema schema, boolean nonAgg) + throws Exception { List whereNode = getWhereMeasure(fields, queryMetrics, queryDimensions, extendFields, datasource, scope, schema, nonAgg); dataSet.getMeasure().addAll(whereNode); // getWhere(outputSet,fields,queryMetrics,queryDimensions,datasource,scope,schema); } - public static void whereDimMetric(List fields, List queryMetrics, - List queryDimensions, DataModel datasource, S2CalciteSchema schema, + public static void whereDimMetric(List fields, Set queryMetrics, + Set queryDimensions, DataModel datasource, S2CalciteSchema schema, Set dimensions, Set metrics) { for (String field : fields) { if (queryDimensions.contains(field) || queryMetrics.contains(field)) { @@ -310,7 +308,7 @@ public class SourceRender extends Renderer { return false; } - private static void addTimeDimension(DataModel dataModel, List queryDimension) { + private static void addTimeDimension(DataModel dataModel, Set queryDimension) { if (Materialization.TimePartType.ZIPPER.equals(dataModel.getTimePartType())) { Optional startTimeOp = dataModel.getDimensions().stream() .filter(d -> Constants.DIMENSION_TYPE_TIME.equalsIgnoreCase(d.getType())) @@ -336,12 +334,12 @@ public class SourceRender extends Renderer { } } - public void render(MetricQueryParam metricQueryParam, List dataModels, + public void render(OntologyQueryParam ontologyQueryParam, List dataModels, SqlValidatorScope scope, S2CalciteSchema schema, boolean nonAgg) throws Exception { - String queryWhere = metricQueryParam.getWhere(); + String queryWhere = ontologyQueryParam.getWhere(); Set whereFields = new HashSet<>(); List fieldWhere = new ArrayList<>(); - EngineType engineType = EngineType.fromString(schema.getOntology().getDatabase().getType()); + EngineType engineType = schema.getOntology().getDatabase().getType(); if (queryWhere != null && !queryWhere.isEmpty()) { SqlNode sqlNode = SemanticNode.parse(queryWhere, scope, engineType); FilterNode.getFilterField(sqlNode, whereFields); @@ -349,13 +347,13 @@ public class SourceRender extends Renderer { } if (dataModels.size() == 1) { DataModel dataModel = dataModels.get(0); - super.tableView = renderOne("", fieldWhere, metricQueryParam.getMetrics(), - metricQueryParam.getDimensions(), metricQueryParam.getWhere(), dataModel, scope, - schema, nonAgg); + super.tableView = renderOne("", fieldWhere, ontologyQueryParam.getMetrics(), + ontologyQueryParam.getDimensions(), ontologyQueryParam.getWhere(), dataModel, + scope, schema, nonAgg); return; } JoinRender joinRender = new JoinRender(); - joinRender.render(metricQueryParam, dataModels, scope, schema, nonAgg); + joinRender.render(ontologyQueryParam, dataModels, scope, schema, nonAgg); super.tableView = joinRender.getTableView(); } } diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/s2sql/Constants.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/s2sql/Constants.java similarity index 93% rename from headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/s2sql/Constants.java rename to headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/s2sql/Constants.java index e2b38952a..0ad7b9d0f 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/s2sql/Constants.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/s2sql/Constants.java @@ -1,4 +1,4 @@ -package com.tencent.supersonic.headless.core.translator.calcite.s2sql; +package com.tencent.supersonic.headless.core.translator.parser.s2sql; public class Constants { diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/s2sql/DataModel.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/s2sql/DataModel.java similarity index 87% rename from headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/s2sql/DataModel.java rename to headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/s2sql/DataModel.java index 1de81b929..ab95cbeea 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/s2sql/DataModel.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/s2sql/DataModel.java @@ -1,4 +1,4 @@ -package com.tencent.supersonic.headless.core.translator.calcite.s2sql; +package com.tencent.supersonic.headless.core.translator.parser.s2sql; import lombok.Builder; import lombok.Data; diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/s2sql/DataType.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/s2sql/DataType.java similarity index 92% rename from headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/s2sql/DataType.java rename to headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/s2sql/DataType.java index f14e7b737..e8e5ab633 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/s2sql/DataType.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/s2sql/DataType.java @@ -1,4 +1,4 @@ -package com.tencent.supersonic.headless.core.translator.calcite.s2sql; +package com.tencent.supersonic.headless.core.translator.parser.s2sql; import java.util.Arrays; diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/s2sql/Dimension.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/s2sql/Dimension.java similarity index 88% rename from headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/s2sql/Dimension.java rename to headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/s2sql/Dimension.java index 559444f32..7fcc6aaba 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/s2sql/Dimension.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/s2sql/Dimension.java @@ -1,4 +1,4 @@ -package com.tencent.supersonic.headless.core.translator.calcite.s2sql; +package com.tencent.supersonic.headless.core.translator.parser.s2sql; import lombok.Builder; import lombok.Data; diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/s2sql/DimensionTimeTypeParams.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/s2sql/DimensionTimeTypeParams.java similarity index 65% rename from headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/s2sql/DimensionTimeTypeParams.java rename to headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/s2sql/DimensionTimeTypeParams.java index 396a60528..d1d1bbdba 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/s2sql/DimensionTimeTypeParams.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/s2sql/DimensionTimeTypeParams.java @@ -1,4 +1,4 @@ -package com.tencent.supersonic.headless.core.translator.calcite.s2sql; +package com.tencent.supersonic.headless.core.translator.parser.s2sql; import lombok.Data; diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/s2sql/Identify.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/s2sql/Identify.java similarity index 80% rename from headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/s2sql/Identify.java rename to headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/s2sql/Identify.java index c8909003d..c9a5fa380 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/s2sql/Identify.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/s2sql/Identify.java @@ -1,4 +1,4 @@ -package com.tencent.supersonic.headless.core.translator.calcite.s2sql; +package com.tencent.supersonic.headless.core.translator.parser.s2sql; import lombok.AllArgsConstructor; import lombok.Data; diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/s2sql/JoinRelation.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/s2sql/JoinRelation.java similarity index 82% rename from headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/s2sql/JoinRelation.java rename to headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/s2sql/JoinRelation.java index 80ef7b71c..ebf7b828f 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/s2sql/JoinRelation.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/s2sql/JoinRelation.java @@ -1,4 +1,4 @@ -package com.tencent.supersonic.headless.core.translator.calcite.s2sql; +package com.tencent.supersonic.headless.core.translator.parser.s2sql; import lombok.Builder; import lombok.Data; diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/s2sql/Materialization.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/s2sql/Materialization.java similarity index 94% rename from headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/s2sql/Materialization.java rename to headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/s2sql/Materialization.java index d4166e862..c882ed1d7 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/s2sql/Materialization.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/s2sql/Materialization.java @@ -1,4 +1,4 @@ -package com.tencent.supersonic.headless.core.translator.calcite.s2sql; +package com.tencent.supersonic.headless.core.translator.parser.s2sql; import lombok.Builder; import lombok.Data; diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/s2sql/MaterializationElement.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/s2sql/MaterializationElement.java similarity index 73% rename from headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/s2sql/MaterializationElement.java rename to headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/s2sql/MaterializationElement.java index 89175e5da..620b0d767 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/s2sql/MaterializationElement.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/s2sql/MaterializationElement.java @@ -1,4 +1,4 @@ -package com.tencent.supersonic.headless.core.translator.calcite.s2sql; +package com.tencent.supersonic.headless.core.translator.parser.s2sql; import lombok.Builder; import lombok.Data; diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/s2sql/Measure.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/s2sql/Measure.java similarity index 84% rename from headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/s2sql/Measure.java rename to headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/s2sql/Measure.java index 20be0f30c..76b15f08a 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/s2sql/Measure.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/s2sql/Measure.java @@ -1,4 +1,4 @@ -package com.tencent.supersonic.headless.core.translator.calcite.s2sql; +package com.tencent.supersonic.headless.core.translator.parser.s2sql; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/s2sql/Metric.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/s2sql/Metric.java similarity index 81% rename from headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/s2sql/Metric.java rename to headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/s2sql/Metric.java index d58328ec3..da334b2df 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/s2sql/Metric.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/s2sql/Metric.java @@ -1,4 +1,4 @@ -package com.tencent.supersonic.headless.core.translator.calcite.s2sql; +package com.tencent.supersonic.headless.core.translator.parser.s2sql; import lombok.Data; diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/s2sql/MetricTypeParams.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/s2sql/MetricTypeParams.java similarity index 78% rename from headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/s2sql/MetricTypeParams.java rename to headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/s2sql/MetricTypeParams.java index a3386526e..105b7bc00 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/s2sql/MetricTypeParams.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/s2sql/MetricTypeParams.java @@ -1,4 +1,4 @@ -package com.tencent.supersonic.headless.core.translator.calcite.s2sql; +package com.tencent.supersonic.headless.core.translator.parser.s2sql; import lombok.Data; diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/s2sql/Ontology.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/s2sql/Ontology.java similarity index 75% rename from headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/s2sql/Ontology.java rename to headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/s2sql/Ontology.java index da2e21698..64d802d51 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/s2sql/Ontology.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/s2sql/Ontology.java @@ -1,4 +1,4 @@ -package com.tencent.supersonic.headless.core.translator.calcite.s2sql; +package com.tencent.supersonic.headless.core.translator.parser.s2sql; import com.tencent.supersonic.headless.core.pojo.Database; import lombok.Data; @@ -25,8 +25,4 @@ public class Ontology { .collect(Collectors.toList()); } - public Map getModelMap() { - return dataModelMap.values().stream() - .collect(Collectors.toMap(DataModel::getId, dataSource -> dataSource)); - } } diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/s2sql/OntologyQueryParam.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/s2sql/OntologyQueryParam.java new file mode 100644 index 000000000..10aea58c5 --- /dev/null +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/s2sql/OntologyQueryParam.java @@ -0,0 +1,20 @@ +package com.tencent.supersonic.headless.core.translator.parser.s2sql; + +import com.google.common.collect.Sets; +import com.tencent.supersonic.common.pojo.ColumnOrder; +import com.tencent.supersonic.headless.api.pojo.enums.AggOption; +import lombok.Data; + +import java.util.List; +import java.util.Set; + +@Data +public class OntologyQueryParam { + private Set metrics = Sets.newHashSet(); + private Set dimensions = Sets.newHashSet(); + private String where; + private Long limit; + private List order; + private boolean nativeQuery = false; + private AggOption aggOption = AggOption.DEFAULT; +} diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/s2sql/SemanticItem.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/s2sql/SemanticItem.java similarity index 52% rename from headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/s2sql/SemanticItem.java rename to headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/s2sql/SemanticItem.java index be239b1d7..b1ee0e403 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/s2sql/SemanticItem.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/s2sql/SemanticItem.java @@ -1,4 +1,4 @@ -package com.tencent.supersonic.headless.core.translator.calcite.s2sql; +package com.tencent.supersonic.headless.core.translator.parser.s2sql; public interface SemanticItem { String getName(); diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/s2sql/TimeRange.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/s2sql/TimeRange.java similarity index 65% rename from headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/s2sql/TimeRange.java rename to headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/s2sql/TimeRange.java index 70e759035..742c7df36 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/calcite/s2sql/TimeRange.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/translator/parser/s2sql/TimeRange.java @@ -1,4 +1,4 @@ -package com.tencent.supersonic.headless.core.translator.calcite.s2sql; +package com.tencent.supersonic.headless.core.translator.parser.s2sql; import lombok.Builder; import lombok.Data; diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/utils/ComponentFactory.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/utils/ComponentFactory.java index 37305db94..b6e573e6d 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/utils/ComponentFactory.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/utils/ComponentFactory.java @@ -4,9 +4,9 @@ import com.tencent.supersonic.common.util.ContextUtils; import com.tencent.supersonic.headless.core.cache.QueryCache; import com.tencent.supersonic.headless.core.executor.QueryAccelerator; import com.tencent.supersonic.headless.core.executor.QueryExecutor; -import com.tencent.supersonic.headless.core.translator.QueryOptimizer; -import com.tencent.supersonic.headless.core.translator.QueryParser; import com.tencent.supersonic.headless.core.translator.converter.QueryConverter; +import com.tencent.supersonic.headless.core.translator.optimizer.QueryOptimizer; +import com.tencent.supersonic.headless.core.translator.parser.QueryParser; import lombok.extern.slf4j.Slf4j; import org.springframework.core.io.support.SpringFactoriesLoader; diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/utils/SqlGenerateUtils.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/utils/SqlGenerateUtils.java index 60f4097d8..8adf84d3e 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/utils/SqlGenerateUtils.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/utils/SqlGenerateUtils.java @@ -12,7 +12,6 @@ import com.tencent.supersonic.common.util.DateModeUtils; import com.tencent.supersonic.common.util.SqlFilterUtils; import com.tencent.supersonic.common.util.StringUtil; import com.tencent.supersonic.headless.api.pojo.Measure; -import com.tencent.supersonic.headless.api.pojo.QueryParam; import com.tencent.supersonic.headless.api.pojo.enums.AggOption; import com.tencent.supersonic.headless.api.pojo.enums.MetricDefineType; import com.tencent.supersonic.headless.api.pojo.request.QueryStructReq; @@ -20,6 +19,7 @@ import com.tencent.supersonic.headless.api.pojo.response.DimSchemaResp; import com.tencent.supersonic.headless.api.pojo.response.MetricResp; import com.tencent.supersonic.headless.api.pojo.response.MetricSchemaResp; import com.tencent.supersonic.headless.core.config.ExecutorConfig; +import com.tencent.supersonic.headless.core.pojo.StructQueryParam; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.ImmutablePair; @@ -85,25 +85,26 @@ public class SqlGenerateUtils { return selectSql; } - public String getLimit(QueryParam queryParam) { - if (queryParam != null && queryParam.getLimit() != null && queryParam.getLimit() > 0) { - return " limit " + queryParam.getLimit(); + public String getLimit(StructQueryParam structQueryParam) { + if (structQueryParam != null && structQueryParam.getLimit() != null + && structQueryParam.getLimit() > 0) { + return " limit " + structQueryParam.getLimit(); } return ""; } - public String getSelect(QueryParam queryParam) { - String aggStr = queryParam.getAggregators().stream().map(this::getSelectField) + public String getSelect(StructQueryParam structQueryParam) { + String aggStr = structQueryParam.getAggregators().stream().map(this::getSelectField) .collect(Collectors.joining(",")); - return CollectionUtils.isEmpty(queryParam.getGroups()) ? aggStr - : String.join(",", queryParam.getGroups()) + "," + aggStr; + return CollectionUtils.isEmpty(structQueryParam.getGroups()) ? aggStr + : String.join(",", structQueryParam.getGroups()) + "," + aggStr; } - public String getSelect(QueryParam queryParam, Map deriveMetrics) { - String aggStr = queryParam.getAggregators().stream() + public String getSelect(StructQueryParam structQueryParam, Map deriveMetrics) { + String aggStr = structQueryParam.getAggregators().stream() .map(a -> getSelectField(a, deriveMetrics)).collect(Collectors.joining(",")); - return CollectionUtils.isEmpty(queryParam.getGroups()) ? aggStr - : String.join(",", queryParam.getGroups()) + "," + aggStr; + return CollectionUtils.isEmpty(structQueryParam.getGroups()) ? aggStr + : String.join(",", structQueryParam.getGroups()) + "," + aggStr; } public String getSelectField(final Aggregator agg) { @@ -128,46 +129,46 @@ public class SqlGenerateUtils { return deriveMetrics.get(agg.getColumn()); } - public String getGroupBy(QueryParam queryParam) { - if (CollectionUtils.isEmpty(queryParam.getGroups())) { + public String getGroupBy(StructQueryParam structQueryParam) { + if (CollectionUtils.isEmpty(structQueryParam.getGroups())) { return ""; } - return "group by " + String.join(",", queryParam.getGroups()); + return "group by " + String.join(",", structQueryParam.getGroups()); } - public String getOrderBy(QueryParam queryParam) { - if (CollectionUtils.isEmpty(queryParam.getOrders())) { + public String getOrderBy(StructQueryParam structQueryParam) { + if (CollectionUtils.isEmpty(structQueryParam.getOrders())) { return ""; } - return "order by " + queryParam.getOrders().stream() + return "order by " + structQueryParam.getOrders().stream() .map(order -> " " + order.getColumn() + " " + order.getDirection() + " ") .collect(Collectors.joining(",")); } - public String getOrderBy(QueryParam queryParam, Map deriveMetrics) { - if (CollectionUtils.isEmpty(queryParam.getOrders())) { + public String getOrderBy(StructQueryParam structQueryParam, Map deriveMetrics) { + if (CollectionUtils.isEmpty(structQueryParam.getOrders())) { return ""; } - if (!queryParam.getOrders().stream() + if (!structQueryParam.getOrders().stream() .anyMatch(o -> deriveMetrics.containsKey(o.getColumn()))) { - return getOrderBy(queryParam); + return getOrderBy(structQueryParam); } - return "order by " + queryParam.getOrders().stream() + return "order by " + structQueryParam.getOrders().stream() .map(order -> " " + (deriveMetrics.containsKey(order.getColumn()) ? deriveMetrics.get(order.getColumn()) : order.getColumn()) + " " + order.getDirection() + " ") .collect(Collectors.joining(",")); } - public String generateWhere(QueryParam queryParam, ItemDateResp itemDateResp) { + public String generateWhere(StructQueryParam structQueryParam, ItemDateResp itemDateResp) { String whereClauseFromFilter = - sqlFilterUtils.getWhereClause(queryParam.getDimensionFilters()); - String whereFromDate = getDateWhereClause(queryParam.getDateInfo(), itemDateResp); - return mergeDateWhereClause(queryParam, whereClauseFromFilter, whereFromDate); + sqlFilterUtils.getWhereClause(structQueryParam.getDimensionFilters()); + String whereFromDate = getDateWhereClause(structQueryParam.getDateInfo(), itemDateResp); + return mergeDateWhereClause(structQueryParam, whereClauseFromFilter, whereFromDate); } - private String mergeDateWhereClause(QueryParam queryParam, String whereClauseFromFilter, - String whereFromDate) { + private String mergeDateWhereClause(StructQueryParam structQueryParam, + String whereClauseFromFilter, String whereFromDate) { if (StringUtils.isNotEmpty(whereFromDate) && StringUtils.isNotEmpty(whereClauseFromFilter)) { return String.format("%s AND (%s)", whereFromDate, whereClauseFromFilter); @@ -179,7 +180,7 @@ public class SqlGenerateUtils { return whereFromDate; } else if (Objects.isNull(whereFromDate) && StringUtils.isEmpty(whereClauseFromFilter)) { log.debug("the current date information is empty, enter the date initialization logic"); - return dateModeUtils.defaultRecentDateInfo(queryParam.getDateInfo()); + return dateModeUtils.defaultRecentDateInfo(structQueryParam.getDateInfo()); } return whereClauseFromFilter; } @@ -203,12 +204,12 @@ public class SqlGenerateUtils { return dateModeUtils.getDateWhereStr(dateInfo, dateDate); } - public Triple getBeginEndTime(QueryParam queryParam, + public Triple getBeginEndTime(StructQueryParam structQueryParam, ItemDateResp dataDate) { - if (Objects.isNull(queryParam.getDateInfo())) { + if (Objects.isNull(structQueryParam.getDateInfo())) { return Triple.of("", "", ""); } - DateConf dateConf = queryParam.getDateInfo(); + DateConf dateConf = structQueryParam.getDateInfo(); String dateInfo = dateModeUtils.getSysDateCol(dateConf); if (dateInfo.isEmpty()) { return Triple.of("", "", ""); diff --git a/headless/core/src/main/java/com/tencent/supersonic/headless/core/utils/SqlUtils.java b/headless/core/src/main/java/com/tencent/supersonic/headless/core/utils/SqlUtils.java index 04cf92616..339586bf0 100644 --- a/headless/core/src/main/java/com/tencent/supersonic/headless/core/utils/SqlUtils.java +++ b/headless/core/src/main/java/com/tencent/supersonic/headless/core/utils/SqlUtils.java @@ -3,6 +3,7 @@ package com.tencent.supersonic.headless.core.utils; import javax.sql.DataSource; import com.tencent.supersonic.common.pojo.QueryColumn; +import com.tencent.supersonic.common.pojo.enums.EngineType; import com.tencent.supersonic.common.util.DateUtils; import com.tencent.supersonic.headless.api.pojo.enums.DataType; import com.tencent.supersonic.headless.api.pojo.response.SemanticQueryResp; @@ -64,7 +65,7 @@ public class SqlUtils { public SqlUtils init(Database database) { return SqlUtilsBuilder.getBuilder() .withName(database.getId() + AT_SYMBOL + database.getName()) - .withType(database.getType()).withJdbcUrl(database.getUrl()) + .withType(database.getType().getName()).withJdbcUrl(database.getUrl()) .withUsername(database.getUsername()).withPassword(database.getPassword()) .withJdbcDataSource(this.jdbcDataSource).withResultLimit(this.resultLimit) .withIsQueryLogEnable(this.isQueryLogEnable).build(); @@ -224,7 +225,8 @@ public class SqlUtils { } public SqlUtils build() { - Database database = Database.builder().name(this.name).type(this.type).url(this.jdbcUrl) + Database database = Database.builder().name(this.name) + .type(EngineType.fromString(this.type.toUpperCase())).url(this.jdbcUrl) .username(this.username).password(this.password).build(); SqlUtils sqlUtils = new SqlUtils(database); diff --git a/headless/core/src/test/java/com/tencent/supersonic/chat/core/parser/aggregate/CalciteSqlParserTest.java b/headless/core/src/test/java/com/tencent/supersonic/chat/core/parser/aggregate/CalciteSqlParserTest.java index 5a3124bf8..c85fe7141 100644 --- a/headless/core/src/test/java/com/tencent/supersonic/chat/core/parser/aggregate/CalciteSqlParserTest.java +++ b/headless/core/src/test/java/com/tencent/supersonic/chat/core/parser/aggregate/CalciteSqlParserTest.java @@ -1,9 +1,8 @@ package com.tencent.supersonic.chat.core.parser.aggregate; import com.alibaba.fastjson.JSON; -import com.tencent.supersonic.headless.api.pojo.enums.AggOption; import com.tencent.supersonic.headless.core.pojo.QueryStatement; -import com.tencent.supersonic.headless.core.translator.calcite.CalciteQueryParser; +import com.tencent.supersonic.headless.core.translator.parser.calcite.CalciteQueryParser; import org.junit.jupiter.api.Test; import org.testng.Assert; @@ -318,7 +317,7 @@ public class CalciteSqlParserTest { + " \"updatedAt\": 1711367511146\n" + " }\n" + " }\n" + "}"; QueryStatement queryStatement = JSON.parseObject(json, QueryStatement.class); CalciteQueryParser calciteSqlParser = new CalciteQueryParser(); - calciteSqlParser.parse(queryStatement, AggOption.DEFAULT); + calciteSqlParser.parse(queryStatement); Assert.assertEquals(queryStatement.getSql().trim().replaceAll("\\s+", ""), "SELECT`imp_date`AS`sys_imp_date`,SUM(1)AS`pv`" + "FROM" + "`s2_pv_uv_statis`" + "GROUPBY`imp_date`,`imp_date`"); diff --git a/headless/server/src/main/java/com/tencent/supersonic/headless/server/facade/rest/SqlQueryApiController.java b/headless/server/src/main/java/com/tencent/supersonic/headless/server/facade/rest/SqlQueryApiController.java index c82b540ad..f8e2af71a 100644 --- a/headless/server/src/main/java/com/tencent/supersonic/headless/server/facade/rest/SqlQueryApiController.java +++ b/headless/server/src/main/java/com/tencent/supersonic/headless/server/facade/rest/SqlQueryApiController.java @@ -6,6 +6,7 @@ import javax.servlet.http.HttpServletResponse; import com.tencent.supersonic.auth.api.authentication.utils.UserHolder; import com.tencent.supersonic.common.pojo.User; import com.tencent.supersonic.common.util.StringUtil; +import com.tencent.supersonic.headless.api.pojo.SqlEvaluation; import com.tencent.supersonic.headless.api.pojo.request.QuerySqlReq; import com.tencent.supersonic.headless.api.pojo.request.QuerySqlsReq; import com.tencent.supersonic.headless.api.pojo.request.SemanticQueryReq; @@ -102,4 +103,28 @@ public class SqlQueryApiController { querySqlReq.setSql(StringUtil.replaceBackticks(sql)); return chatLayerService.validate(querySqlReq, user); } + + @PostMapping("/validateAndQuery") + public Object validateAndQuery(@RequestBody QuerySqlsReq querySqlsReq, + HttpServletRequest request, HttpServletResponse response) throws Exception { + User user = UserHolder.findUser(request, response); + List convert = convert(querySqlsReq); + for (QuerySqlReq querySqlReq : convert) { + SqlEvaluation validate = chatLayerService.validate(querySqlReq, user); + if (!validate.getIsValidated()) { + throw new Exception(validate.getValidateMsg()); + } + } + return queryBySqls(querySqlsReq, request, response); + } + + private List convert(QuerySqlsReq querySqlsReq) { + return querySqlsReq.getSqls().stream().map(sql -> { + QuerySqlReq querySqlReq = new QuerySqlReq(); + BeanUtils.copyProperties(querySqlsReq, querySqlReq); + querySqlReq.setSql(StringUtil.replaceBackticks(sql)); + return querySqlReq; + }).collect(Collectors.toList()); + } + } diff --git a/headless/server/src/main/java/com/tencent/supersonic/headless/server/facade/service/impl/S2SemanticLayerService.java b/headless/server/src/main/java/com/tencent/supersonic/headless/server/facade/service/impl/S2SemanticLayerService.java index c26b66c44..306ac693a 100644 --- a/headless/server/src/main/java/com/tencent/supersonic/headless/server/facade/service/impl/S2SemanticLayerService.java +++ b/headless/server/src/main/java/com/tencent/supersonic/headless/server/facade/service/impl/S2SemanticLayerService.java @@ -6,24 +6,10 @@ import com.tencent.supersonic.common.pojo.QueryColumn; import com.tencent.supersonic.common.pojo.User; import com.tencent.supersonic.common.pojo.enums.TaskStatusEnum; import com.tencent.supersonic.common.pojo.enums.TimeDimensionEnum; -import com.tencent.supersonic.headless.api.pojo.DataSetSchema; -import com.tencent.supersonic.headless.api.pojo.Dim; -import com.tencent.supersonic.headless.api.pojo.MetaFilter; -import com.tencent.supersonic.headless.api.pojo.QueryParam; +import com.tencent.supersonic.headless.api.pojo.*; import com.tencent.supersonic.headless.api.pojo.enums.SemanticType; -import com.tencent.supersonic.headless.api.pojo.request.DimensionValueReq; -import com.tencent.supersonic.headless.api.pojo.request.QueryMultiStructReq; -import com.tencent.supersonic.headless.api.pojo.request.QuerySqlReq; -import com.tencent.supersonic.headless.api.pojo.request.QueryStructReq; -import com.tencent.supersonic.headless.api.pojo.request.SchemaFilterReq; -import com.tencent.supersonic.headless.api.pojo.request.SemanticQueryReq; -import com.tencent.supersonic.headless.api.pojo.response.DimensionResp; -import com.tencent.supersonic.headless.api.pojo.response.ItemResp; -import com.tencent.supersonic.headless.api.pojo.response.MetricResp; -import com.tencent.supersonic.headless.api.pojo.response.ModelResp; -import com.tencent.supersonic.headless.api.pojo.response.SemanticQueryResp; -import com.tencent.supersonic.headless.api.pojo.response.SemanticSchemaResp; -import com.tencent.supersonic.headless.api.pojo.response.SemanticTranslateResp; +import com.tencent.supersonic.headless.api.pojo.request.*; +import com.tencent.supersonic.headless.api.pojo.response.*; import com.tencent.supersonic.headless.chat.knowledge.HanlpMapResult; import com.tencent.supersonic.headless.chat.knowledge.KnowledgeBaseService; import com.tencent.supersonic.headless.chat.knowledge.MapResult; @@ -33,6 +19,8 @@ import com.tencent.supersonic.headless.chat.knowledge.helper.NatureHelper; import com.tencent.supersonic.headless.core.cache.QueryCache; import com.tencent.supersonic.headless.core.executor.QueryExecutor; import com.tencent.supersonic.headless.core.pojo.QueryStatement; +import com.tencent.supersonic.headless.core.pojo.SqlQueryParam; +import com.tencent.supersonic.headless.core.pojo.StructQueryParam; import com.tencent.supersonic.headless.core.translator.SemanticTranslator; import com.tencent.supersonic.headless.core.utils.ComponentFactory; import com.tencent.supersonic.headless.server.annotation.S2DataPermission; @@ -52,12 +40,7 @@ import org.apache.commons.lang3.StringUtils; import org.springframework.beans.BeanUtils; import org.springframework.stereotype.Service; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Set; +import java.util.*; import java.util.stream.Collectors; @Service @@ -307,30 +290,13 @@ public class S2SemanticLayerService implements SemanticLayerService { return queryStatement; } - private QueryStatement buildSqlQueryStatement(QuerySqlReq querySqlReq, User user) { - // If dataSetId or DataSetName is empty, parse dataSetId from the SQL - if (querySqlReq.needGetDataSetId()) { - Long dataSetId = dataSetService.getDataSetIdFromSql(querySqlReq.getSql(), user); - querySqlReq.setDataSetId(dataSetId); - } - - QueryStatement queryStatement = buildStructQueryStatement(querySqlReq); - queryStatement.setIsS2SQL(true); - queryStatement.setSql(querySqlReq.getSql()); - return queryStatement; - } - - private QueryStatement buildStructQueryStatement(SemanticQueryReq queryReq) { + private QueryStatement buildQueryStatement(SemanticQueryReq queryReq) { SchemaFilterReq schemaFilterReq = new SchemaFilterReq(); schemaFilterReq.setDataSetId(queryReq.getDataSetId()); schemaFilterReq.setModelIds(queryReq.getModelIds()); SemanticSchemaResp semanticSchemaResp = schemaService.fetchSemanticSchema(schemaFilterReq); QueryStatement queryStatement = new QueryStatement(); - QueryParam queryParam = new QueryParam(); - BeanUtils.copyProperties(queryReq, queryParam); - queryStatement.setQueryParam(queryParam); - queryStatement.setModelIds(queryReq.getModelIds()); queryStatement.setEnableOptimize(queryUtils.enableOptimize()); queryStatement.setDataSetId(queryReq.getDataSetId()); queryStatement.setSemanticSchemaResp(semanticSchemaResp); @@ -338,6 +304,31 @@ public class S2SemanticLayerService implements SemanticLayerService { return queryStatement; } + private QueryStatement buildSqlQueryStatement(QuerySqlReq querySqlReq, User user) { + QueryStatement queryStatement = buildQueryStatement(querySqlReq); + queryStatement.setIsS2SQL(true); + + SqlQueryParam sqlQueryParam = new SqlQueryParam(); + sqlQueryParam.setSql(querySqlReq.getSql()); + queryStatement.setSqlQueryParam(sqlQueryParam); + + // If dataSetId or DataSetName is empty, parse dataSetId from the SQL + if (querySqlReq.needGetDataSetId()) { + Long dataSetId = dataSetService.getDataSetIdFromSql(querySqlReq.getSql(), user); + querySqlReq.setDataSetId(dataSetId); + } + return queryStatement; + } + + private QueryStatement buildStructQueryStatement(SemanticQueryReq queryReq) { + QueryStatement queryStatement = buildQueryStatement(queryReq); + StructQueryParam structQueryParam = new StructQueryParam(); + BeanUtils.copyProperties(queryReq, structQueryParam); + queryStatement.setStructQueryParam(structQueryParam); + queryStatement.setIsS2SQL(false); + return queryStatement; + } + private QueryStatement buildMultiStructQueryStatement(QueryMultiStructReq queryMultiStructReq) { List queryStatements = new ArrayList<>(); for (QueryStructReq queryStructReq : queryMultiStructReq.getQueryStructReqs()) { diff --git a/headless/server/src/main/java/com/tencent/supersonic/headless/server/manager/ModelYamlManager.java b/headless/server/src/main/java/com/tencent/supersonic/headless/server/manager/ModelYamlManager.java index 3a96b718f..44b2fb6bd 100644 --- a/headless/server/src/main/java/com/tencent/supersonic/headless/server/manager/ModelYamlManager.java +++ b/headless/server/src/main/java/com/tencent/supersonic/headless/server/manager/ModelYamlManager.java @@ -33,7 +33,6 @@ public class ModelYamlManager { ModelDetail modelDetail = modelResp.getModelDetail(); DbAdaptor engineAdaptor = DbAdaptorFactory.getEngineAdaptor(databaseResp.getType()); SysTimeDimensionBuilder.addSysTimeDimension(modelDetail.getDimensions(), engineAdaptor); - addInterCntMetric(modelResp.getBizName(), modelDetail); DataModelYamlTpl dataModelYamlTpl = new DataModelYamlTpl(); dataModelYamlTpl.setType(databaseResp.getType()); BeanUtils.copyProperties(modelDetail, dataModelYamlTpl); diff --git a/headless/server/src/main/java/com/tencent/supersonic/headless/server/manager/SemanticSchemaManager.java b/headless/server/src/main/java/com/tencent/supersonic/headless/server/manager/SemanticSchemaManager.java index 7e5eff936..d1b99f0b2 100644 --- a/headless/server/src/main/java/com/tencent/supersonic/headless/server/manager/SemanticSchemaManager.java +++ b/headless/server/src/main/java/com/tencent/supersonic/headless/server/manager/SemanticSchemaManager.java @@ -2,33 +2,12 @@ package com.tencent.supersonic.headless.server.manager; import com.tencent.supersonic.common.pojo.ModelRela; import com.tencent.supersonic.common.pojo.enums.FilterOperatorEnum; -import com.tencent.supersonic.headless.api.pojo.Field; -import com.tencent.supersonic.headless.api.pojo.enums.TagDefineType; import com.tencent.supersonic.headless.api.pojo.response.DatabaseResp; import com.tencent.supersonic.headless.api.pojo.response.SemanticSchemaResp; -import com.tencent.supersonic.headless.api.pojo.response.TagResp; -import com.tencent.supersonic.headless.core.translator.calcite.s2sql.Constants; -import com.tencent.supersonic.headless.core.translator.calcite.s2sql.DataModel; -import com.tencent.supersonic.headless.core.translator.calcite.s2sql.DataType; -import com.tencent.supersonic.headless.core.translator.calcite.s2sql.Dimension; -import com.tencent.supersonic.headless.core.translator.calcite.s2sql.DimensionTimeTypeParams; -import com.tencent.supersonic.headless.core.translator.calcite.s2sql.Identify; -import com.tencent.supersonic.headless.core.translator.calcite.s2sql.JoinRelation; -import com.tencent.supersonic.headless.core.translator.calcite.s2sql.Materialization.TimePartType; -import com.tencent.supersonic.headless.core.translator.calcite.s2sql.Measure; -import com.tencent.supersonic.headless.core.translator.calcite.s2sql.Metric; -import com.tencent.supersonic.headless.core.translator.calcite.s2sql.MetricTypeParams; -import com.tencent.supersonic.headless.core.translator.calcite.s2sql.Ontology; -import com.tencent.supersonic.headless.core.translator.calcite.sql.S2CalciteSchema; -import com.tencent.supersonic.headless.server.pojo.yaml.DataModelYamlTpl; -import com.tencent.supersonic.headless.server.pojo.yaml.DimensionTimeTypeParamsTpl; -import com.tencent.supersonic.headless.server.pojo.yaml.DimensionYamlTpl; -import com.tencent.supersonic.headless.server.pojo.yaml.FieldParamYamlTpl; -import com.tencent.supersonic.headless.server.pojo.yaml.IdentifyYamlTpl; -import com.tencent.supersonic.headless.server.pojo.yaml.MeasureYamlTpl; -import com.tencent.supersonic.headless.server.pojo.yaml.MetricParamYamlTpl; -import com.tencent.supersonic.headless.server.pojo.yaml.MetricTypeParamsYamlTpl; -import com.tencent.supersonic.headless.server.pojo.yaml.MetricYamlTpl; +import com.tencent.supersonic.headless.core.translator.parser.calcite.S2CalciteSchema; +import com.tencent.supersonic.headless.core.translator.parser.s2sql.*; +import com.tencent.supersonic.headless.core.translator.parser.s2sql.Materialization.TimePartType; +import com.tencent.supersonic.headless.server.pojo.yaml.*; import com.tencent.supersonic.headless.server.service.SchemaService; import com.tencent.supersonic.headless.server.utils.DatabaseConverter; import lombok.extern.slf4j.Slf4j; @@ -36,15 +15,8 @@ import org.apache.commons.lang3.tuple.Triple; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.Map.Entry; -import java.util.Objects; -import java.util.Optional; -import java.util.Set; import java.util.stream.Collectors; @Slf4j @@ -90,82 +62,6 @@ public class SemanticSchemaManager { return ontology; } - public Ontology getTagSemanticModel(SemanticSchemaResp semanticSchemaResp) throws Exception { - if (CollectionUtils.isEmpty(semanticSchemaResp.getTags())) { - throw new Exception("semanticSchemaResp tag is empty"); - } - Ontology ontology = buildOntology(semanticSchemaResp); - // Map> dimensions = new HashMap<>(); - Map> tagMap = new HashMap<>(); - for (TagResp tagResp : semanticSchemaResp.getTags()) { - if (!tagMap.containsKey(tagResp.getModelId())) { - tagMap.put(tagResp.getModelId(), new ArrayList<>()); - } - tagMap.get(tagResp.getModelId()).add(tagResp); - } - if (Objects.nonNull(ontology.getDataModelMap()) && !ontology.getDataModelMap().isEmpty()) { - for (Map.Entry entry : ontology.getDataModelMap().entrySet()) { - List modelDimensions = new ArrayList<>(); - if (!ontology.getDimensionMap().containsKey(entry.getKey())) { - ontology.getDimensionMap().put(entry.getKey(), modelDimensions); - } else { - modelDimensions = ontology.getDimensionMap().get(entry.getKey()); - } - if (tagMap.containsKey(entry.getValue().getId())) { - for (TagResp tagResp : tagMap.get(entry.getValue().getId())) { - addTagModel(tagResp, modelDimensions, ontology.getMetrics()); - } - } - } - } - - return ontology; - } - - private void addTagModel(TagResp tagResp, List modelDimensions, - List modelMetrics) throws Exception { - TagDefineType tagDefineType = TagDefineType.valueOf(tagResp.getTagDefineType()); - switch (tagDefineType) { - case FIELD: - case DIMENSION: - if (TagDefineType.DIMENSION.equals(tagResp.getTagDefineType())) { - Optional modelDimension = modelDimensions.stream() - // .filter(d -> d.getBizName().equals(tagResp.getExpr())) - .findFirst(); - if (modelDimension.isPresent()) { - modelDimension.get().setName(tagResp.getBizName()); - return; - } - } - Dimension dimension = Dimension.builder().build(); - dimension.setType(""); - // dimension.setExpr(tagResp.getExpr()); - dimension.setName(tagResp.getBizName()); - dimension.setOwners(""); - dimension.setBizName(tagResp.getBizName()); - if (Objects.isNull(dimension.getDataType())) { - dimension.setDataType(DataType.UNKNOWN); - } - - DimensionTimeTypeParams dimensionTimeTypeParams = new DimensionTimeTypeParams(); - dimension.setDimensionTimeTypeParams(dimensionTimeTypeParams); - modelDimensions.add(dimension); - return; - case METRIC: - Optional modelMetric = modelMetrics.stream() - // .filter(m -> m.getName().equalsIgnoreCase(tagResp.getExpr())) - .findFirst(); - if (modelMetric.isPresent()) { - modelMetric.get().setName(tagResp.getBizName()); - } else { - throw new Exception( - String.format("tag [{}] cant find the metric", tagResp.getBizName())); - } - return; - default: - } - } - public static List getMetrics(final List t) { return getMetricsByMetricYamlTpl(t); } @@ -184,16 +80,6 @@ public class SemanticSchemaManager { if (Objects.nonNull(d.getModelSourceTypeEnum())) { dataModel.setTimePartType(TimePartType.of(d.getModelSourceTypeEnum().name())); } - if (Objects.nonNull(d.getFields()) && !CollectionUtils.isEmpty(d.getFields())) { - Set measures = dataModel.getMeasures().stream().map(mm -> mm.getName()) - .collect(Collectors.toSet()); - for (Field f : d.getFields()) { - if (!measures.contains(f.getFieldName())) { - dataModel.getMeasures().add(Measure.builder().expr(f.getFieldName()) - .name(f.getFieldName()).agg("").build()); - } - } - } return dataModel; } diff --git a/headless/server/src/main/java/com/tencent/supersonic/headless/server/persistence/repository/DictRepository.java b/headless/server/src/main/java/com/tencent/supersonic/headless/server/persistence/repository/DictRepository.java index 37008166c..66adedbb0 100644 --- a/headless/server/src/main/java/com/tencent/supersonic/headless/server/persistence/repository/DictRepository.java +++ b/headless/server/src/main/java/com/tencent/supersonic/headless/server/persistence/repository/DictRepository.java @@ -2,6 +2,7 @@ package com.tencent.supersonic.headless.server.persistence.repository; import com.tencent.supersonic.headless.api.pojo.request.DictItemFilter; import com.tencent.supersonic.headless.api.pojo.request.DictSingleTaskReq; +import com.tencent.supersonic.headless.api.pojo.request.ValueTaskQueryReq; import com.tencent.supersonic.headless.api.pojo.response.DictItemResp; import com.tencent.supersonic.headless.api.pojo.response.DictTaskResp; import com.tencent.supersonic.headless.server.persistence.dataobject.DictConfDO; @@ -26,4 +27,6 @@ public interface DictRepository { DictTaskDO queryDictTaskById(Long id); DictTaskResp queryLatestDictTask(DictSingleTaskReq taskReq); + + List queryAllDictTask(ValueTaskQueryReq taskQueryReq); } diff --git a/headless/server/src/main/java/com/tencent/supersonic/headless/server/persistence/repository/impl/DictRepositoryImpl.java b/headless/server/src/main/java/com/tencent/supersonic/headless/server/persistence/repository/impl/DictRepositoryImpl.java index 1abaa39eb..55ffe1d11 100644 --- a/headless/server/src/main/java/com/tencent/supersonic/headless/server/persistence/repository/impl/DictRepositoryImpl.java +++ b/headless/server/src/main/java/com/tencent/supersonic/headless/server/persistence/repository/impl/DictRepositoryImpl.java @@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.tencent.supersonic.common.pojo.enums.TypeEnums; import com.tencent.supersonic.headless.api.pojo.request.DictItemFilter; import com.tencent.supersonic.headless.api.pojo.request.DictSingleTaskReq; +import com.tencent.supersonic.headless.api.pojo.request.ValueTaskQueryReq; import com.tencent.supersonic.headless.api.pojo.response.DictItemResp; import com.tencent.supersonic.headless.api.pojo.response.DictTaskResp; import com.tencent.supersonic.headless.api.pojo.response.DimensionResp; @@ -14,11 +15,14 @@ import com.tencent.supersonic.headless.server.persistence.mapper.DictTaskMapper; import com.tencent.supersonic.headless.server.persistence.repository.DictRepository; import com.tencent.supersonic.headless.server.service.DimensionService; import com.tencent.supersonic.headless.server.utils.DictUtils; +import com.xkzhangsan.time.utils.CollectionUtil; import lombok.extern.slf4j.Slf4j; +import org.codehaus.plexus.util.StringUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Repository; import org.springframework.util.CollectionUtils; +import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Objects; @@ -100,6 +104,23 @@ public class DictRepositoryImpl implements DictRepository { return taskResp; } + @Override + public List queryAllDictTask(ValueTaskQueryReq taskQueryReq) { + QueryWrapper wrapper = new QueryWrapper<>(); + if (Objects.nonNull(taskQueryReq.getItemId())) { + wrapper.lambda().eq(DictTaskDO::getItemId, taskQueryReq.getItemId()); + } + if (CollectionUtil.isNotEmpty(taskQueryReq.getTaskStatusList())) { + wrapper.lambda().in(DictTaskDO::getStatus, taskQueryReq.getTaskStatusList()); + } + if (StringUtils.isNotEmpty(taskQueryReq.getKey())) { + String key = taskQueryReq.getKey(); + wrapper.lambda().and(qw -> qw.like(DictTaskDO::getName, key).or() + .like(DictTaskDO::getDescription, key).or().like(DictTaskDO::getConfig, key)); + } + return dictTaskMapper.selectList(wrapper); + } + @Override public Long addDictConf(DictConfDO dictConfDO) { dictConfMapper.insert(dictConfDO); diff --git a/headless/server/src/main/java/com/tencent/supersonic/headless/server/rest/KnowledgeController.java b/headless/server/src/main/java/com/tencent/supersonic/headless/server/rest/KnowledgeController.java index 7ce9e6d4c..e813e496b 100644 --- a/headless/server/src/main/java/com/tencent/supersonic/headless/server/rest/KnowledgeController.java +++ b/headless/server/src/main/java/com/tencent/supersonic/headless/server/rest/KnowledgeController.java @@ -13,6 +13,7 @@ import com.tencent.supersonic.headless.api.pojo.request.DictItemFilter; import com.tencent.supersonic.headless.api.pojo.request.DictItemReq; import com.tencent.supersonic.headless.api.pojo.request.DictSingleTaskReq; import com.tencent.supersonic.headless.api.pojo.request.DictValueReq; +import com.tencent.supersonic.headless.api.pojo.request.ValueTaskQueryReq; import com.tencent.supersonic.headless.api.pojo.response.DictItemResp; import com.tencent.supersonic.headless.api.pojo.response.DictTaskResp; import com.tencent.supersonic.headless.api.pojo.response.DictValueDimResp; @@ -132,6 +133,18 @@ public class KnowledgeController { return taskService.queryLatestDictTask(taskReq, user); } + /** + * queryDictTask-分页返回维度的字典任务列表 + * + * @param taskQueryReq + */ + @PostMapping("/task/search/page") + public PageInfo queryDictTask(@RequestBody ValueTaskQueryReq taskQueryReq, + HttpServletRequest request, HttpServletResponse response) { + User user = UserHolder.findUser(request, response); + return taskService.queryDictTask(taskQueryReq, user); + } + @GetMapping("/embedding/reload") public Object reloadEmbedding() { metaEmbeddingTask.reloadMetaEmbedding(); diff --git a/headless/server/src/main/java/com/tencent/supersonic/headless/server/service/DictTaskService.java b/headless/server/src/main/java/com/tencent/supersonic/headless/server/service/DictTaskService.java index 9e2bee6cb..6e66641ac 100644 --- a/headless/server/src/main/java/com/tencent/supersonic/headless/server/service/DictTaskService.java +++ b/headless/server/src/main/java/com/tencent/supersonic/headless/server/service/DictTaskService.java @@ -4,6 +4,7 @@ import com.github.pagehelper.PageInfo; import com.tencent.supersonic.common.pojo.User; import com.tencent.supersonic.headless.api.pojo.request.DictSingleTaskReq; import com.tencent.supersonic.headless.api.pojo.request.DictValueReq; +import com.tencent.supersonic.headless.api.pojo.request.ValueTaskQueryReq; import com.tencent.supersonic.headless.api.pojo.response.DictTaskResp; import com.tencent.supersonic.headless.api.pojo.response.DictValueDimResp; @@ -17,6 +18,8 @@ public interface DictTaskService { DictTaskResp queryLatestDictTask(DictSingleTaskReq taskReq, User user); + PageInfo queryDictTask(ValueTaskQueryReq taskQueryReq, User user); + PageInfo queryDictValue(DictValueReq dictValueReq, User user); String queryDictFilePath(DictValueReq dictValueReq, User user); diff --git a/headless/server/src/main/java/com/tencent/supersonic/headless/server/service/SchemaService.java b/headless/server/src/main/java/com/tencent/supersonic/headless/server/service/SchemaService.java index f7d978bcc..f240bcf66 100644 --- a/headless/server/src/main/java/com/tencent/supersonic/headless/server/service/SchemaService.java +++ b/headless/server/src/main/java/com/tencent/supersonic/headless/server/service/SchemaService.java @@ -9,15 +9,7 @@ import com.tencent.supersonic.headless.api.pojo.MetaFilter; import com.tencent.supersonic.headless.api.pojo.SemanticSchema; import com.tencent.supersonic.headless.api.pojo.request.ItemUseReq; import com.tencent.supersonic.headless.api.pojo.request.SchemaFilterReq; -import com.tencent.supersonic.headless.api.pojo.response.DatabaseResp; -import com.tencent.supersonic.headless.api.pojo.response.DimensionResp; -import com.tencent.supersonic.headless.api.pojo.response.DomainResp; -import com.tencent.supersonic.headless.api.pojo.response.ItemResp; -import com.tencent.supersonic.headless.api.pojo.response.ItemUseResp; -import com.tencent.supersonic.headless.api.pojo.response.MetricResp; -import com.tencent.supersonic.headless.api.pojo.response.ModelResp; -import com.tencent.supersonic.headless.api.pojo.response.ModelSchemaResp; -import com.tencent.supersonic.headless.api.pojo.response.SemanticSchemaResp; +import com.tencent.supersonic.headless.api.pojo.response.*; import com.tencent.supersonic.headless.server.pojo.yaml.DataModelYamlTpl; import com.tencent.supersonic.headless.server.pojo.yaml.DimensionYamlTpl; import com.tencent.supersonic.headless.server.pojo.yaml.MetricYamlTpl; @@ -64,5 +56,4 @@ public interface SchemaService { ItemDateResp getItemDate(ItemDateFilter dimension, ItemDateFilter metric); - DatabaseResp getDatabase(Long id); } diff --git a/headless/server/src/main/java/com/tencent/supersonic/headless/server/service/impl/DictTaskServiceImpl.java b/headless/server/src/main/java/com/tencent/supersonic/headless/server/service/impl/DictTaskServiceImpl.java index d83e8e2de..da70b7de0 100644 --- a/headless/server/src/main/java/com/tencent/supersonic/headless/server/service/impl/DictTaskServiceImpl.java +++ b/headless/server/src/main/java/com/tencent/supersonic/headless/server/service/impl/DictTaskServiceImpl.java @@ -1,15 +1,18 @@ package com.tencent.supersonic.headless.server.service.impl; +import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import com.tencent.supersonic.common.pojo.Constants; import com.tencent.supersonic.common.pojo.User; import com.tencent.supersonic.common.pojo.enums.StatusEnum; import com.tencent.supersonic.common.pojo.enums.TaskStatusEnum; import com.tencent.supersonic.common.util.BeanMapper; +import com.tencent.supersonic.common.util.DateUtils; import com.tencent.supersonic.headless.api.pojo.DimValueMap; import com.tencent.supersonic.headless.api.pojo.request.DictItemFilter; import com.tencent.supersonic.headless.api.pojo.request.DictSingleTaskReq; import com.tencent.supersonic.headless.api.pojo.request.DictValueReq; +import com.tencent.supersonic.headless.api.pojo.request.ValueTaskQueryReq; import com.tencent.supersonic.headless.api.pojo.response.DictItemResp; import com.tencent.supersonic.headless.api.pojo.response.DictTaskResp; import com.tencent.supersonic.headless.api.pojo.response.DictValueDimResp; @@ -116,14 +119,17 @@ public class DictTaskServiceImpl implements DictTaskService { fileHandler.writeFile(data, fileName, false); // 3.Change in-memory dictionary data in real time + String status = TaskStatusEnum.SUCCESS.getStatus(); try { dictWordService.loadDictWord(); - - dictTaskDO.setStatus(TaskStatusEnum.SUCCESS.getStatus()); - dictRepository.editDictTask(dictTaskDO); } catch (Exception e) { log.error("reloadCustomDictionary error", e); + status = TaskStatusEnum.ERROR.getStatus(); + dictTaskDO.setDescription(e.toString()); } + dictTaskDO.setStatus(status); + dictTaskDO.setElapsedMs(DateUtils.calculateDiffMs(dictTaskDO.getCreatedAt())); + dictRepository.editDictTask(dictTaskDO); } @Override @@ -164,6 +170,17 @@ public class DictTaskServiceImpl implements DictTaskService { return dictRepository.queryLatestDictTask(taskReq); } + @Override + public PageInfo queryDictTask(ValueTaskQueryReq taskQueryReq, User user) { + PageInfo dictTaskDOPageInfo = + PageHelper.startPage(taskQueryReq.getCurrent(), taskQueryReq.getPageSize()) + .doSelectPageInfo(() -> dictRepository.queryAllDictTask(taskQueryReq)); + PageInfo dictTaskRespPageInfo = new PageInfo<>(); + BeanMapper.mapper(dictTaskDOPageInfo, dictTaskRespPageInfo); + dictTaskRespPageInfo.setList(dictConverter.taskDO2Resp(dictTaskDOPageInfo.getList())); + return dictTaskRespPageInfo; + } + @Override public PageInfo queryDictValue(DictValueReq dictValueReq, User user) { // todo 优化读取内存结构 diff --git a/headless/server/src/main/java/com/tencent/supersonic/headless/server/service/impl/SchemaServiceImpl.java b/headless/server/src/main/java/com/tencent/supersonic/headless/server/service/impl/SchemaServiceImpl.java index 2c4a62bd5..950db495e 100644 --- a/headless/server/src/main/java/com/tencent/supersonic/headless/server/service/impl/SchemaServiceImpl.java +++ b/headless/server/src/main/java/com/tencent/supersonic/headless/server/service/impl/SchemaServiceImpl.java @@ -536,8 +536,4 @@ public class SchemaServiceImpl implements SchemaService { return modelService.getItemDate(dimension, metric); } - @Override - public DatabaseResp getDatabase(Long id) { - return databaseService.getDatabase(id); - } } diff --git a/headless/server/src/main/java/com/tencent/supersonic/headless/server/utils/DatabaseConverter.java b/headless/server/src/main/java/com/tencent/supersonic/headless/server/utils/DatabaseConverter.java index 95acf699f..e7e9551f1 100644 --- a/headless/server/src/main/java/com/tencent/supersonic/headless/server/utils/DatabaseConverter.java +++ b/headless/server/src/main/java/com/tencent/supersonic/headless/server/utils/DatabaseConverter.java @@ -1,6 +1,7 @@ package com.tencent.supersonic.headless.server.utils; import com.alibaba.fastjson.JSONObject; +import com.tencent.supersonic.common.pojo.enums.EngineType; import com.tencent.supersonic.headless.api.pojo.request.DatabaseReq; import com.tencent.supersonic.headless.api.pojo.response.DatabaseResp; import com.tencent.supersonic.headless.core.pojo.ConnectInfo; @@ -16,6 +17,7 @@ public class DatabaseConverter { public static Database convert(DatabaseResp databaseResp) { Database database = new Database(); BeanUtils.copyProperties(databaseResp, database); + database.setType(EngineType.fromString(databaseResp.getType().toUpperCase())); return database; } diff --git a/headless/server/src/main/java/com/tencent/supersonic/headless/server/utils/DictUtils.java b/headless/server/src/main/java/com/tencent/supersonic/headless/server/utils/DictUtils.java index aa3fb47bd..e3d76bf97 100644 --- a/headless/server/src/main/java/com/tencent/supersonic/headless/server/utils/DictUtils.java +++ b/headless/server/src/main/java/com/tencent/supersonic/headless/server/utils/DictUtils.java @@ -34,6 +34,7 @@ import com.tencent.supersonic.headless.server.service.DimensionService; import com.tencent.supersonic.headless.server.service.MetricService; import com.tencent.supersonic.headless.server.service.ModelService; import com.tencent.supersonic.headless.server.service.TagMetaService; +import com.xkzhangsan.time.utils.CollectionUtil; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.BeanUtils; @@ -533,4 +534,12 @@ public class DictUtils { resp.setConfig(JsonUtil.toObject(dictTaskDO.getConfig(), ItemValueConfig.class)); return resp; } + + public List taskDO2Resp(List dictTaskDOList) { + List dictTaskRespList = new ArrayList<>(); + if (CollectionUtil.isNotEmpty(dictTaskDOList)) { + dictTaskDOList.stream().forEach(taskDO -> dictTaskRespList.add(taskDO2Resp(taskDO))); + } + return dictTaskRespList; + } } diff --git a/headless/server/src/main/java/com/tencent/supersonic/headless/server/utils/MetricDrillDownChecker.java b/headless/server/src/main/java/com/tencent/supersonic/headless/server/utils/MetricDrillDownChecker.java index 12caf5b77..5c6de4df9 100644 --- a/headless/server/src/main/java/com/tencent/supersonic/headless/server/utils/MetricDrillDownChecker.java +++ b/headless/server/src/main/java/com/tencent/supersonic/headless/server/utils/MetricDrillDownChecker.java @@ -67,7 +67,8 @@ public class MetricDrillDownChecker { List metricResps = getMetrics(metricFields, semanticSchemaResp); if (!checkDrillDownDimension(dimensionBizName, metricResps, semanticSchemaResp)) { DimSchemaResp dimSchemaResp = semanticSchemaResp.getDimension(dimensionBizName); - if (Objects.nonNull(dimSchemaResp) && dimSchemaResp.isPartitionTime()) { + if (Objects.isNull(dimSchemaResp) + || (Objects.nonNull(dimSchemaResp) && dimSchemaResp.isPartitionTime())) { continue; } String errMsg = diff --git a/headless/server/src/test/java/com/tencent/supersonic/headless/server/calcite/HeadlessParserServiceTest.java b/headless/server/src/test/java/com/tencent/supersonic/headless/server/calcite/HeadlessParserServiceTest.java index 656ccd081..dc69e6d70 100644 --- a/headless/server/src/test/java/com/tencent/supersonic/headless/server/calcite/HeadlessParserServiceTest.java +++ b/headless/server/src/test/java/com/tencent/supersonic/headless/server/calcite/HeadlessParserServiceTest.java @@ -2,31 +2,25 @@ package com.tencent.supersonic.headless.server.calcite; import com.tencent.supersonic.common.pojo.ColumnOrder; import com.tencent.supersonic.common.pojo.enums.EngineType; -import com.tencent.supersonic.headless.api.pojo.enums.AggOption; import com.tencent.supersonic.headless.api.pojo.response.SqlParserResp; -import com.tencent.supersonic.headless.core.pojo.MetricQueryParam; import com.tencent.supersonic.headless.core.pojo.QueryStatement; -import com.tencent.supersonic.headless.core.translator.calcite.sql.S2CalciteSchema; -import com.tencent.supersonic.headless.core.translator.calcite.sql.SqlBuilder; +import com.tencent.supersonic.headless.core.translator.parser.calcite.S2CalciteSchema; +import com.tencent.supersonic.headless.core.translator.parser.calcite.SqlBuilder; +import com.tencent.supersonic.headless.core.translator.parser.s2sql.OntologyQueryParam; import com.tencent.supersonic.headless.server.manager.SemanticSchemaManager; -import com.tencent.supersonic.headless.server.pojo.yaml.DataModelYamlTpl; -import com.tencent.supersonic.headless.server.pojo.yaml.DimensionTimeTypeParamsTpl; -import com.tencent.supersonic.headless.server.pojo.yaml.DimensionYamlTpl; -import com.tencent.supersonic.headless.server.pojo.yaml.IdentifyYamlTpl; -import com.tencent.supersonic.headless.server.pojo.yaml.MeasureYamlTpl; -import com.tencent.supersonic.headless.server.pojo.yaml.MetricTypeParamsYamlTpl; -import com.tencent.supersonic.headless.server.pojo.yaml.MetricYamlTpl; +import com.tencent.supersonic.headless.server.pojo.yaml.*; import lombok.extern.slf4j.Slf4j; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashSet; import java.util.List; @Slf4j class HeadlessParserServiceTest { public static SqlParserResp parser(S2CalciteSchema semanticSchema, - MetricQueryParam metricQueryParam, boolean isAgg) { + OntologyQueryParam ontologyQueryParam, boolean isAgg) { SqlParserResp sqlParser = new SqlParserResp(); try { if (semanticSchema == null) { @@ -35,14 +29,14 @@ class HeadlessParserServiceTest { } SqlBuilder aggBuilder = new SqlBuilder(semanticSchema); QueryStatement queryStatement = new QueryStatement(); - queryStatement.setMetricQueryParam(metricQueryParam); - aggBuilder.build(queryStatement, AggOption.getAggregation(!isAgg)); - EngineType engineType = - EngineType.fromString(semanticSchema.getOntology().getDatabase().getType()); + queryStatement.setOntologyQueryParam(ontologyQueryParam); + String sql = aggBuilder.buildOntologySql(queryStatement); + queryStatement.setSql(sql); + EngineType engineType = semanticSchema.getOntology().getDatabase().getType(); sqlParser.setSql(aggBuilder.getSql(engineType)); } catch (Exception e) { sqlParser.setErrMsg(e.getMessage()); - log.error("parser error metricQueryReq[{}] error [{}]", metricQueryParam, e); + log.error("parser error metricQueryReq[{}] error [{}]", ontologyQueryParam, e); } return sqlParser; } @@ -161,9 +155,9 @@ class HeadlessParserServiceTest { // HeadlessSchemaManager.update(headlessSchema, HeadlessSchemaManager.getMetrics(metric)); - MetricQueryParam metricCommand = new MetricQueryParam(); - metricCommand.setDimensions(new ArrayList<>(Arrays.asList("sys_imp_date"))); - metricCommand.setMetrics(new ArrayList<>(Arrays.asList("pv"))); + OntologyQueryParam metricCommand = new OntologyQueryParam(); + metricCommand.setDimensions(new HashSet<>(Arrays.asList("sys_imp_date"))); + metricCommand.setMetrics(new HashSet<>(Arrays.asList("pv"))); metricCommand.setWhere( "user_name = 'ab' and (sys_imp_date >= '2023-02-28' and sys_imp_date <= '2023-05-28') "); metricCommand.setLimit(1000L); @@ -174,10 +168,10 @@ class HeadlessParserServiceTest { addDepartment(semanticSchema); - MetricQueryParam metricCommand2 = new MetricQueryParam(); - metricCommand2.setDimensions(new ArrayList<>(Arrays.asList("sys_imp_date", + OntologyQueryParam metricCommand2 = new OntologyQueryParam(); + metricCommand2.setDimensions(new HashSet<>(Arrays.asList("sys_imp_date", "user_name__department", "user_name", "user_name__page"))); - metricCommand2.setMetrics(new ArrayList<>(Arrays.asList("pv"))); + metricCommand2.setMetrics(new HashSet<>(Arrays.asList("pv"))); metricCommand2.setWhere( "user_name = 'ab' and (sys_imp_date >= '2023-02-28' and sys_imp_date <= '2023-05-28') "); metricCommand2.setLimit(1000L); diff --git a/headless/server/src/test/java/com/tencent/supersonic/headless/server/utils/QueryNLReqBuilderTest.java b/headless/server/src/test/java/com/tencent/supersonic/headless/server/utils/QueryNLReqBuilderTest.java index 7cec555f9..63fa85ed9 100644 --- a/headless/server/src/test/java/com/tencent/supersonic/headless/server/utils/QueryNLReqBuilderTest.java +++ b/headless/server/src/test/java/com/tencent/supersonic/headless/server/utils/QueryNLReqBuilderTest.java @@ -68,8 +68,5 @@ class QueryNLReqBuilderTest { DateModeUtils dateModeUtils = new DateModeUtils(); mockContextUtils.when(() -> ContextUtils.getBean(DateModeUtils.class)) .thenReturn(dateModeUtils); - dateModeUtils.setSysDateCol("sys_imp_date"); - dateModeUtils.setSysDateWeekCol("sys_imp_week"); - dateModeUtils.setSysDateMonthCol("sys_imp_month"); } } diff --git a/launchers/headless/src/main/resources/META-INF/spring.factories b/launchers/headless/src/main/resources/META-INF/spring.factories index 82b9e8397..918a0baf4 100644 --- a/launchers/headless/src/main/resources/META-INF/spring.factories +++ b/launchers/headless/src/main/resources/META-INF/spring.factories @@ -26,15 +26,18 @@ com.tencent.supersonic.headless.chat.parser.llm.DataSetResolver=\ com.tencent.supersonic.headless.core.translator.converter.QueryConverter=\ com.tencent.supersonic.headless.core.translator.converter.DefaultDimValueConverter,\ - com.tencent.supersonic.headless.core.translator.converter.SqlVariableParseConverter,\ - com.tencent.supersonic.headless.core.translator.converter.CalculateAggConverter,\ - com.tencent.supersonic.headless.core.translator.converter.ParserDefaultConverter + com.tencent.supersonic.headless.core.translator.converter.SqlVariableConverter,\ + com.tencent.supersonic.headless.core.translator.converter.MetricRatioConverter,\ + com.tencent.supersonic.headless.core.translator.converter.SqlQueryConverter,\ + com.tencent.supersonic.headless.core.translator.converter.StructQueryConverter -com.tencent.supersonic.headless.core.translator.QueryOptimizer=\ - com.tencent.supersonic.headless.core.translator.DetailQueryOptimizer +com.tencent.supersonic.headless.core.translator.optimizer.QueryOptimizer=\ + com.tencent.supersonic.headless.core.translator.optimizer.DetailQueryOptimizer,\ + com.tencent.supersonic.headless.core.translator.optimizer.DbDialectOptimizer,\ + com.tencent.supersonic.headless.core.translator.optimizer.ResultLimitOptimizer -com.tencent.supersonic.headless.core.translator.QueryParser=\ - com.tencent.supersonic.headless.core.translator.calcite.CalciteQueryParser +com.tencent.supersonic.headless.core.translator.parser.QueryParser=\ + com.tencent.supersonic.headless.core.translator.parser.calcite.CalciteQueryParser com.tencent.supersonic.headless.core.executor.QueryExecutor=\ com.tencent.supersonic.headless.core.executor.JdbcExecutor @@ -46,4 +49,5 @@ com.tencent.supersonic.headless.core.cache.QueryCache=\ ### headless-server SPIs com.tencent.supersonic.headless.server.modeller.SemanticModeller=\ - com.tencent.supersonic.headless.server.modeller.RuleSemanticModeller \ No newline at end of file + com.tencent.supersonic.headless.server.modeller.RuleSemanticModeller, \ + com.tencent.supersonic.headless.server.modeller.LLMSemanticModeller \ No newline at end of file diff --git a/launchers/standalone/pom.xml b/launchers/standalone/pom.xml index 20a3a8b0a..885bbe67d 100644 --- a/launchers/standalone/pom.xml +++ b/launchers/standalone/pom.xml @@ -83,6 +83,12 @@ junit test + + org.junit-pioneer + junit-pioneer + 1.6.0 + test + org.springframework.boot spring-boot-starter-test diff --git a/launchers/standalone/src/main/java/com/tencent/supersonic/demo/S2BaseDemo.java b/launchers/standalone/src/main/java/com/tencent/supersonic/demo/S2BaseDemo.java index bf69e5a4f..fc71bd5b2 100644 --- a/launchers/standalone/src/main/java/com/tencent/supersonic/demo/S2BaseDemo.java +++ b/launchers/standalone/src/main/java/com/tencent/supersonic/demo/S2BaseDemo.java @@ -108,9 +108,9 @@ public abstract class S2BaseDemo implements CommandLineRunner { } } - abstract void doRun(); + protected abstract void doRun(); - abstract boolean checkNeedToRun(); + protected abstract boolean checkNeedToRun(); protected DatabaseResp addDatabaseIfNotExist() { List databaseList = databaseService.getDatabaseList(defaultUser); @@ -119,8 +119,8 @@ public abstract class S2BaseDemo implements CommandLineRunner { } String url = dataSourceProperties.getUrl(); DatabaseReq databaseReq = new DatabaseReq(); - databaseReq.setName("H2数据库DEMO"); - databaseReq.setDescription("样例数据库实例仅用于体验,正式使用请切换持久化数据库"); + databaseReq.setName("S2数据库DEMO"); + databaseReq.setDescription("样例数据库实例仅用于体验"); if (StringUtils.isNotBlank(url) && url.toLowerCase().contains(DataType.MYSQL.getFeature().toLowerCase())) { databaseReq.setType(DataType.MYSQL.getFeature()); diff --git a/launchers/standalone/src/main/java/com/tencent/supersonic/demo/S2CompanyDemo.java b/launchers/standalone/src/main/java/com/tencent/supersonic/demo/S2CompanyDemo.java index 030eb0ad3..388017106 100644 --- a/launchers/standalone/src/main/java/com/tencent/supersonic/demo/S2CompanyDemo.java +++ b/launchers/standalone/src/main/java/com/tencent/supersonic/demo/S2CompanyDemo.java @@ -7,26 +7,12 @@ import com.tencent.supersonic.chat.server.agent.Agent; import com.tencent.supersonic.chat.server.agent.AgentToolType; import com.tencent.supersonic.chat.server.agent.DatasetTool; import com.tencent.supersonic.chat.server.agent.ToolConfig; -import com.tencent.supersonic.chat.server.processor.execute.DataInterpretProcessor; import com.tencent.supersonic.common.pojo.ChatApp; import com.tencent.supersonic.common.pojo.JoinCondition; import com.tencent.supersonic.common.pojo.ModelRela; -import com.tencent.supersonic.common.pojo.enums.AggOperatorEnum; -import com.tencent.supersonic.common.pojo.enums.AppModule; -import com.tencent.supersonic.common.pojo.enums.FilterOperatorEnum; -import com.tencent.supersonic.common.pojo.enums.TimeMode; -import com.tencent.supersonic.common.pojo.enums.TypeEnums; +import com.tencent.supersonic.common.pojo.enums.*; import com.tencent.supersonic.common.util.ChatAppManager; -import com.tencent.supersonic.headless.api.pojo.AggregateTypeDefaultConfig; -import com.tencent.supersonic.headless.api.pojo.DataSetDetail; -import com.tencent.supersonic.headless.api.pojo.DataSetModelConfig; -import com.tencent.supersonic.headless.api.pojo.Dim; -import com.tencent.supersonic.headless.api.pojo.DimensionTimeTypeParams; -import com.tencent.supersonic.headless.api.pojo.Identify; -import com.tencent.supersonic.headless.api.pojo.Measure; -import com.tencent.supersonic.headless.api.pojo.ModelDetail; -import com.tencent.supersonic.headless.api.pojo.QueryConfig; -import com.tencent.supersonic.headless.api.pojo.TimeDefaultConfig; +import com.tencent.supersonic.headless.api.pojo.*; import com.tencent.supersonic.headless.api.pojo.enums.DimensionType; import com.tencent.supersonic.headless.api.pojo.enums.IdentifyType; import com.tencent.supersonic.headless.api.pojo.request.DataSetReq; @@ -40,11 +26,7 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Map; +import java.util.*; @Component @Slf4j @@ -59,8 +41,8 @@ public class S2CompanyDemo extends S2BaseDemo { ModelResp model_brand = addModel_2(domain, demoDatabase); ModelResp model_brand_revenue = addModel_3(domain, demoDatabase); - addModelRela(domain, model_company, model_brand, "company_id"); - addModelRela(domain, model_brand, model_brand_revenue, "brand_id"); + addModelRela(domain, model_brand, model_company, "company_id"); + addModelRela(domain, model_brand_revenue, model_brand, "brand_id"); DataSetResp dataset = addDataSet(domain); addAgent(dataset.getId()); @@ -70,7 +52,7 @@ public class S2CompanyDemo extends S2BaseDemo { } @Override - boolean checkNeedToRun() { + protected boolean checkNeedToRun() { List domainList = domainService.getDomainList(); for (DomainResp domainResp : domainList) { if (domainResp.getBizName().equalsIgnoreCase("corporate")) { @@ -124,8 +106,7 @@ public class S2CompanyDemo extends S2BaseDemo { modelDetail.setMeasures(measures); modelDetail.setQueryType("sql_query"); - modelDetail.setSqlQuery("SELECT company_id,company_name,headquarter_address," - + "company_established_time,founder,ceo,annual_turnover,employee_count FROM company"); + modelDetail.setSqlQuery("SELECT * FROM company"); modelReq.setModelDetail(modelDetail); ModelResp companyModel = modelService.createModel(modelReq, defaultUser); @@ -164,8 +145,7 @@ public class S2CompanyDemo extends S2BaseDemo { modelDetail.setMeasures(measures); modelDetail.setQueryType("sql_query"); - modelDetail.setSqlQuery("SELECT brand_id,brand_name,brand_established_time," - + "company_id,legal_representative,registered_capital FROM brand"); + modelDetail.setSqlQuery("SELECT * FROM brand"); modelReq.setModelDetail(modelDetail); ModelResp brandModel = modelService.createModel(modelReq, defaultUser); @@ -205,8 +185,7 @@ public class S2CompanyDemo extends S2BaseDemo { modelDetail.setMeasures(measures); modelDetail.setQueryType("sql_query"); - modelDetail.setSqlQuery("SELECT year_time,brand_id,revenue,profit," - + "revenue_growth_year_on_year,profit_growth_year_on_year FROM brand_revenue"); + modelDetail.setSqlQuery("SELECT * FROM brand_revenue"); modelReq.setModelDetail(modelDetail); return modelService.createModel(modelReq, defaultUser); } @@ -245,7 +224,7 @@ public class S2CompanyDemo extends S2BaseDemo { modelRelaReq.setDomainId(domain.getId()); modelRelaReq.setFromModelId(fromModel.getId()); modelRelaReq.setToModelId(toModel.getId()); - modelRelaReq.setJoinType("left join"); + modelRelaReq.setJoinType("inner join"); modelRelaReq.setJoinConditions(joinConditions); modelRelaService.save(modelRelaReq, defaultUser); } @@ -272,7 +251,6 @@ public class S2CompanyDemo extends S2BaseDemo { Map chatAppConfig = Maps.newHashMap(ChatAppManager.getAllApps(AppModule.CHAT)); chatAppConfig.values().forEach(app -> app.setChatModelId(demoChatModel.getId())); - chatAppConfig.get(DataInterpretProcessor.APP_KEY).setEnable(true); agent.setChatAppConfig(chatAppConfig); agentService.createAgent(agent, defaultUser); diff --git a/launchers/standalone/src/main/java/com/tencent/supersonic/demo/S2SingerDemo.java b/launchers/standalone/src/main/java/com/tencent/supersonic/demo/S2SingerDemo.java index 1b40be2d5..68ad3150c 100644 --- a/launchers/standalone/src/main/java/com/tencent/supersonic/demo/S2SingerDemo.java +++ b/launchers/standalone/src/main/java/com/tencent/supersonic/demo/S2SingerDemo.java @@ -57,7 +57,7 @@ public class S2SingerDemo extends S2BaseDemo { } @Override - boolean checkNeedToRun() { + protected boolean checkNeedToRun() { List domainList = domainService.getDomainList(); for (DomainResp domainResp : domainList) { if (domainResp.getBizName().equalsIgnoreCase("singer")) { diff --git a/launchers/standalone/src/main/java/com/tencent/supersonic/demo/S2SmallTalkDemo.java b/launchers/standalone/src/main/java/com/tencent/supersonic/demo/S2SmallTalkDemo.java index 7964d0bf8..43ed610c2 100644 --- a/launchers/standalone/src/main/java/com/tencent/supersonic/demo/S2SmallTalkDemo.java +++ b/launchers/standalone/src/main/java/com/tencent/supersonic/demo/S2SmallTalkDemo.java @@ -46,9 +46,10 @@ public class S2SmallTalkDemo extends S2BaseDemo { } @Override - boolean checkNeedToRun() { + protected boolean checkNeedToRun() { List agentNames = agentService.getAgents().stream().map(Agent::getName).collect(Collectors.toList()); - return !agentNames.contains("来闲聊"); + return !agentNames.contains("闲聊助手"); } + } diff --git a/launchers/standalone/src/main/java/com/tencent/supersonic/demo/S2VisitsDemo.java b/launchers/standalone/src/main/java/com/tencent/supersonic/demo/S2VisitsDemo.java index 7f7cb56b4..69e04f2ae 100644 --- a/launchers/standalone/src/main/java/com/tencent/supersonic/demo/S2VisitsDemo.java +++ b/launchers/standalone/src/main/java/com/tencent/supersonic/demo/S2VisitsDemo.java @@ -79,8 +79,8 @@ public class S2VisitsDemo extends S2BaseDemo { ModelResp userModel = addModel_1(s2Domain, demoDatabase); ModelResp pvUvModel = addModel_2(s2Domain, demoDatabase); ModelResp stayTimeModel = addModel_3(s2Domain, demoDatabase); - addModelRela(s2Domain, userModel, pvUvModel, "user_name"); - addModelRela(s2Domain, userModel, stayTimeModel, "user_name"); + addModelRela(s2Domain, pvUvModel, userModel, "user_name"); + addModelRela(s2Domain, stayTimeModel, userModel, "user_name"); // create metrics and dimensions DimensionResp departmentDimension = getDimension("department", userModel); @@ -146,7 +146,8 @@ public class S2VisitsDemo extends S2BaseDemo { agent.setStatus(1); agent.setEnableSearch(1); agent.setExamples(Lists.newArrayList("近15天超音数访问次数汇总", "按部门统计超音数的访问人数", "对比alice和lucy的停留时长", - "过去30天访问次数最高的部门top3", "近1个月总访问次数超过100次的部门有几个", "过去半个月每个核心用户的总停留时长")); + "过去30天访问次数最高的部门top3", "近1个月总访问次数超过100次的部门有几个", "过去半个月每个核心用户的总停留时长", + "今年以来访问次数最高的一天是哪一天")); // configure tools ToolConfig toolConfig = new ToolConfig(); @@ -198,6 +199,7 @@ public class S2VisitsDemo extends S2BaseDemo { List dimensions = new ArrayList<>(); dimensions.add(new Dim("部门", "department", DimensionType.categorical, 1)); + // dimensions.add(new Dim("用户", "user_name", DimensionType.categorical, 1)); modelDetail.setDimensions(dimensions); List fields = Lists.newArrayList(); fields.add(Field.builder().fieldName("user_name").dataType("Varchar").build()); @@ -382,9 +384,9 @@ public class S2VisitsDemo extends S2BaseDemo { metricReq.setDescription("访问的用户个数"); metricReq.setAlias("UV,访问人数"); MetricDefineByFieldParams metricTypeParams = new MetricDefineByFieldParams(); - metricTypeParams.setExpr("count(distinct user_id)"); + metricTypeParams.setExpr("count(distinct user_name)"); List fieldParams = new ArrayList<>(); - fieldParams.add(new FieldParam("user_id")); + fieldParams.add(new FieldParam("user_name")); metricTypeParams.setFields(fieldParams); metricReq.setMetricDefineByFieldParams(metricTypeParams); metricReq.setMetricDefineType(MetricDefineType.FIELD); diff --git a/launchers/standalone/src/main/resources/META-INF/spring.factories b/launchers/standalone/src/main/resources/META-INF/spring.factories index 0a989e182..40943382a 100644 --- a/launchers/standalone/src/main/resources/META-INF/spring.factories +++ b/launchers/standalone/src/main/resources/META-INF/spring.factories @@ -26,15 +26,18 @@ com.tencent.supersonic.headless.chat.parser.llm.DataSetResolver=\ com.tencent.supersonic.headless.core.translator.converter.QueryConverter=\ com.tencent.supersonic.headless.core.translator.converter.DefaultDimValueConverter,\ - com.tencent.supersonic.headless.core.translator.converter.SqlVariableParseConverter,\ - com.tencent.supersonic.headless.core.translator.converter.CalculateAggConverter,\ - com.tencent.supersonic.headless.core.translator.converter.ParserDefaultConverter + com.tencent.supersonic.headless.core.translator.converter.SqlVariableConverter,\ + com.tencent.supersonic.headless.core.translator.converter.MetricRatioConverter,\ + com.tencent.supersonic.headless.core.translator.converter.SqlQueryConverter,\ + com.tencent.supersonic.headless.core.translator.converter.StructQueryConverter -com.tencent.supersonic.headless.core.translator.QueryOptimizer=\ - com.tencent.supersonic.headless.core.translator.DetailQueryOptimizer +com.tencent.supersonic.headless.core.translator.optimizer.QueryOptimizer=\ + com.tencent.supersonic.headless.core.translator.optimizer.DetailQueryOptimizer,\ + com.tencent.supersonic.headless.core.translator.optimizer.DbDialectOptimizer,\ + com.tencent.supersonic.headless.core.translator.optimizer.ResultLimitOptimizer -com.tencent.supersonic.headless.core.translator.QueryParser=\ - com.tencent.supersonic.headless.core.translator.calcite.CalciteQueryParser +com.tencent.supersonic.headless.core.translator.parser.QueryParser=\ + com.tencent.supersonic.headless.core.translator.parser.calcite.CalciteQueryParser com.tencent.supersonic.headless.core.executor.QueryExecutor=\ com.tencent.supersonic.headless.core.executor.JdbcExecutor diff --git a/launchers/standalone/src/main/resources/application-local.yaml b/launchers/standalone/src/main/resources/application-local.yaml index 7c2737f4a..a9fa2a589 100644 --- a/launchers/standalone/src/main/resources/application-local.yaml +++ b/launchers/standalone/src/main/resources/application-local.yaml @@ -11,4 +11,24 @@ spring: h2: console: path: /h2-console/semantic - enabled: true \ No newline at end of file + enabled: true + +### Comment out following lines if using MySQL +#spring: +# datasource: +# driver-class-name: com.mysql.cj.jdbc.Driver +# url: jdbc:mysql://localhost:3306/s2_database?user=root +# username: root +# password: +# sql: +# enabled: true +# mode: always +# username: root +# password: +# init: +# schema-locations: classpath:db/schema-mysql.sql,classpath:db/schema-mysql-demo.sql +# data-locations: classpath:db/data-mysql.sql,classpath:db/data-mysql-demo.sql +# h2: +# console: +# path: /h2-console/semantic +# enabled: true \ No newline at end of file diff --git a/launchers/standalone/src/main/resources/config.update/sql-update.sql b/launchers/standalone/src/main/resources/config.update/sql-update.sql index 17c43e127..c9e6c84f9 100644 --- a/launchers/standalone/src/main/resources/config.update/sql-update.sql +++ b/launchers/standalone/src/main/resources/config.update/sql-update.sql @@ -396,5 +396,5 @@ ALTER TABLE s2_agent DROP COLUMN `enable_memory_review`; alter table s2_agent add column `enable_feedback` tinyint DEFAULT 1; --20241116 -alter table s2_agent add column `admin` varchar(1000); -alter table s2_agent add column `viewer` varchar(1000); \ No newline at end of file +alter table s2_agent add column `admin` varchar(1000) COLLATE utf8_unicode_ci DEFAULT NULL; +alter table s2_agent add column `viewer` varchar(1000) COLLATE utf8_unicode_ci DEFAULT NULL; \ No newline at end of file diff --git a/launchers/standalone/src/main/resources/db/data-mysql-demo.sql b/launchers/standalone/src/main/resources/db/data-mysql-demo.sql index d438213fe..b4d29935d 100644 --- a/launchers/standalone/src/main/resources/db/data-mysql-demo.sql +++ b/launchers/standalone/src/main/resources/db/data-mysql-demo.sql @@ -1,4 +1,4 @@ --------S2VisitsDemo +-- S2VisitsDemo insert into s2_user_department (user_name, department) values ('jack','HR'); insert into s2_user_department (user_name, department) values ('tom','sales'); insert into s2_user_department (user_name, department) values ('lucy','marketing'); @@ -1019,7 +1019,7 @@ INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES ( INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATE_SUB(CURRENT_DATE(), INTERVAL 15 DAY), 'lucy', '0.8124302447925607', 'p4'); INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATE_SUB(CURRENT_DATE(), INTERVAL 8 DAY), 'lucy', '0.039935860913407284', 'p2'); --------S2ArtistDemo +-- S2ArtistDemo INSERT INTO singer (singer_name, act_area, song_name, genre, js_play_cnt, down_cnt, favor_cnt) VALUES ('周杰伦', '港台', '青花瓷', '国风', 1000000, 1000000, 1000000); diff --git a/launchers/standalone/src/main/resources/db/schema-mysql-demo.sql b/launchers/standalone/src/main/resources/db/schema-mysql-demo.sql index 904286964..194dba2fb 100644 --- a/launchers/standalone/src/main/resources/db/schema-mysql-demo.sql +++ b/launchers/standalone/src/main/resources/db/schema-mysql-demo.sql @@ -1,4 +1,4 @@ --------S2VisitsDemo +-- S2VisitsDemo CREATE TABLE IF NOT EXISTS `s2_user_department` ( `user_name` varchar(200) NOT NULL, `department` varchar(200) NOT NULL @@ -27,7 +27,7 @@ CREATE TABLE IF NOT EXISTS `singer` ( `favor_cnt` bigint DEFAULT NULL )ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; --------S2ArtistDemo +-- S2ArtistDemo CREATE TABLE IF NOT EXISTS `genre` ( `g_name` varchar(20) NOT NULL , -- genre name `rating` INT , diff --git a/launchers/standalone/src/main/resources/db/schema-mysql.sql b/launchers/standalone/src/main/resources/db/schema-mysql.sql index 2ea501551..a0c1df547 100644 --- a/launchers/standalone/src/main/resources/db/schema-mysql.sql +++ b/launchers/standalone/src/main/resources/db/schema-mysql.sql @@ -15,6 +15,8 @@ CREATE TABLE IF NOT EXISTS `s2_agent` ( `created_at` datetime DEFAULT NULL, `updated_by` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL, `updated_at` datetime DEFAULT NULL, + `admin` varchar(1000) COLLATE utf8_unicode_ci DEFAULT NULL, + `viewer` varchar(1000) COLLATE utf8_unicode_ci DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; @@ -539,7 +541,7 @@ CREATE TABLE IF NOT EXISTS `s2_term` ( PRIMARY KEY (`id`) ) ENGINE = InnoDB DEFAULT CHARSET = utf8 COMMENT ='术语表'; -CREATE TABLE `s2_user_token` ( +CREATE TABLE IF NOT EXISTS `s2_user_token` ( `id` bigint NOT NULL AUTO_INCREMENT, `name` VARCHAR(255) NOT NULL, `user_name` VARCHAR(255) NOT NULL, diff --git a/launchers/standalone/src/test/java/com/tencent/supersonic/chat/BaseTest.java b/launchers/standalone/src/test/java/com/tencent/supersonic/chat/BaseTest.java index a48825177..d92be2031 100644 --- a/launchers/standalone/src/test/java/com/tencent/supersonic/chat/BaseTest.java +++ b/launchers/standalone/src/test/java/com/tencent/supersonic/chat/BaseTest.java @@ -12,14 +12,15 @@ import com.tencent.supersonic.common.pojo.enums.DatePeriodEnum; import com.tencent.supersonic.common.service.ChatModelService; import com.tencent.supersonic.headless.api.pojo.SchemaElement; import com.tencent.supersonic.headless.api.pojo.SemanticParseInfo; -import com.tencent.supersonic.headless.api.pojo.response.ParseResp; import com.tencent.supersonic.headless.api.pojo.response.QueryState; +import com.tencent.supersonic.headless.server.service.SchemaService; import com.tencent.supersonic.util.DataUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import java.time.LocalDate; import java.util.List; +import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; @@ -38,6 +39,8 @@ public class BaseTest extends BaseApplication { protected AgentService agentService; @Autowired protected ChatModelService chatModelService; + @Autowired + protected SchemaService schemaService; @Value("${s2.demo.enableLLM:false}") protected boolean enableLLM; @@ -107,4 +110,10 @@ public class BaseTest extends BaseApplication { assertEquals(expectedParseInfo.getDateInfo(), actualParseInfo.getDateInfo()); } + + protected SchemaElement getSchemaElementByName(Set elementSet, String name) { + Optional matchElement = + elementSet.stream().filter(e -> e.getName().equals(name)).findFirst(); + return matchElement.orElse(null); + } } diff --git a/launchers/standalone/src/test/java/com/tencent/supersonic/chat/DetailTest.java b/launchers/standalone/src/test/java/com/tencent/supersonic/chat/DetailTest.java index 1cf356a6f..dcb5a7865 100644 --- a/launchers/standalone/src/test/java/com/tencent/supersonic/chat/DetailTest.java +++ b/launchers/standalone/src/test/java/com/tencent/supersonic/chat/DetailTest.java @@ -5,6 +5,7 @@ import com.tencent.supersonic.chat.api.pojo.response.QueryResult; import com.tencent.supersonic.common.pojo.enums.AggregateTypeEnum; import com.tencent.supersonic.common.pojo.enums.FilterOperatorEnum; import com.tencent.supersonic.common.pojo.enums.QueryType; +import com.tencent.supersonic.headless.api.pojo.DataSetSchema; import com.tencent.supersonic.headless.api.pojo.SchemaElement; import com.tencent.supersonic.headless.api.pojo.SemanticParseInfo; import com.tencent.supersonic.headless.api.pojo.request.QueryFilter; @@ -12,6 +13,7 @@ import com.tencent.supersonic.headless.chat.query.rule.detail.DetailDimensionQue import com.tencent.supersonic.util.DataUtils; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.Test; +import org.junitpioneer.jupiter.SetSystemProperty; import org.springframework.boot.test.context.SpringBootTest; @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @@ -19,8 +21,9 @@ import org.springframework.boot.test.context.SpringBootTest; public class DetailTest extends BaseTest { @Test + @SetSystemProperty(key = "s2.test", value = "true") public void test_detail_dimension() throws Exception { - QueryResult actualResult = submitNewChat("周杰伦流派和代表作", DataUtils.tagAgentId); + QueryResult actualResult = submitNewChat("周杰伦流派和代表作", DataUtils.singerAgentId); QueryResult expectedResult = new QueryResult(); SemanticParseInfo expectedParseInfo = new SemanticParseInfo(); @@ -30,8 +33,11 @@ public class DetailTest extends BaseTest { expectedParseInfo.setQueryType(QueryType.DETAIL); expectedParseInfo.setAggType(AggregateTypeEnum.NONE); - QueryFilter dimensionFilter = - DataUtils.getFilter("singer_name", FilterOperatorEnum.EQUALS, "周杰伦", "歌手名", 8L); + DataSetSchema schema = schemaService.getDataSetSchema(DataUtils.singerDatasettId); + SchemaElement singerElement = getSchemaElementByName(schema.getDimensions(), "歌手名"); + + QueryFilter dimensionFilter = DataUtils.getFilter("singer_name", FilterOperatorEnum.EQUALS, + "周杰伦", "歌手名", singerElement.getId()); expectedParseInfo.getDimensionFilters().add(dimensionFilter); expectedParseInfo.getDimensions() @@ -43,7 +49,7 @@ public class DetailTest extends BaseTest { @Test public void test_detail_filter() throws Exception { - QueryResult actualResult = submitNewChat("国风歌手", DataUtils.tagAgentId); + QueryResult actualResult = submitNewChat("国风歌手", DataUtils.singerAgentId); QueryResult expectedResult = new QueryResult(); SemanticParseInfo expectedParseInfo = new SemanticParseInfo(); @@ -53,8 +59,10 @@ public class DetailTest extends BaseTest { expectedParseInfo.setQueryType(QueryType.DETAIL); expectedParseInfo.setAggType(AggregateTypeEnum.NONE); - QueryFilter dimensionFilter = - DataUtils.getFilter("genre", FilterOperatorEnum.EQUALS, "国风", "流派", 7L); + DataSetSchema schema = schemaService.getDataSetSchema(DataUtils.singerDatasettId); + SchemaElement genreElement = getSchemaElementByName(schema.getDimensions(), "流派"); + QueryFilter dimensionFilter = DataUtils.getFilter("genre", FilterOperatorEnum.EQUALS, "国风", + "流派", genreElement.getId()); expectedParseInfo.getDimensionFilters().add(dimensionFilter); expectedParseInfo.getDimensions() .addAll(Lists.newArrayList(SchemaElement.builder().name("歌手名").build())); diff --git a/launchers/standalone/src/test/java/com/tencent/supersonic/chat/MetricTest.java b/launchers/standalone/src/test/java/com/tencent/supersonic/chat/MetricTest.java index d0e251eed..e7c2683ad 100644 --- a/launchers/standalone/src/test/java/com/tencent/supersonic/chat/MetricTest.java +++ b/launchers/standalone/src/test/java/com/tencent/supersonic/chat/MetricTest.java @@ -5,14 +5,18 @@ import com.tencent.supersonic.common.pojo.DateConf; import com.tencent.supersonic.common.pojo.enums.DatePeriodEnum; import com.tencent.supersonic.common.pojo.enums.FilterOperatorEnum; import com.tencent.supersonic.common.pojo.enums.QueryType; +import com.tencent.supersonic.headless.api.pojo.DataSetSchema; +import com.tencent.supersonic.headless.api.pojo.SchemaElement; import com.tencent.supersonic.headless.api.pojo.SemanticParseInfo; import com.tencent.supersonic.headless.api.pojo.request.QueryFilter; import com.tencent.supersonic.headless.chat.query.rule.metric.MetricFilterQuery; import com.tencent.supersonic.headless.chat.query.rule.metric.MetricGroupByQuery; +import com.tencent.supersonic.headless.chat.query.rule.metric.MetricModelQuery; import com.tencent.supersonic.headless.chat.query.rule.metric.MetricTopNQuery; import com.tencent.supersonic.util.DataUtils; import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; +import org.junitpioneer.jupiter.SetSystemProperty; import org.springframework.boot.test.context.SpringBootTest; import java.text.DateFormat; @@ -28,24 +32,16 @@ import static com.tencent.supersonic.common.pojo.enums.AggregateTypeEnum.SUM; public class MetricTest extends BaseTest { @Test - public void testMetric() throws Exception { - QueryResult actualResult = submitNewChat("超音数 访问次数", DataUtils.metricAgentId); - } - - @Test - public void testMetricFilter() throws Exception { - QueryResult actualResult = submitNewChat("alice的访问次数", DataUtils.metricAgentId); + public void testMetricModel() throws Exception { + QueryResult actualResult = submitNewChat("超音数 访问次数", DataUtils.productAgentId); QueryResult expectedResult = new QueryResult(); SemanticParseInfo expectedParseInfo = new SemanticParseInfo(); expectedResult.setChatContext(expectedParseInfo); - expectedResult.setQueryMode(MetricFilterQuery.QUERY_MODE); + expectedResult.setQueryMode(MetricModelQuery.QUERY_MODE); expectedParseInfo.setAggType(NONE); - expectedParseInfo.getMetrics().add(DataUtils.getSchemaElement("访问次数")); - expectedParseInfo.getDimensionFilters().add( - DataUtils.getFilter("user_name", FilterOperatorEnum.EQUALS, "alice", "用户", 2L)); expectedParseInfo.setDateInfo( DataUtils.getDateConf(DateConf.DateMode.BETWEEN, unit, period, startDay, endDay)); @@ -56,8 +52,35 @@ public class MetricTest extends BaseTest { } @Test + public void testMetricFilter() throws Exception { + QueryResult actualResult = submitNewChat("alice的访问次数", DataUtils.productAgentId); + + QueryResult expectedResult = new QueryResult(); + SemanticParseInfo expectedParseInfo = new SemanticParseInfo(); + expectedResult.setChatContext(expectedParseInfo); + + expectedResult.setQueryMode(MetricFilterQuery.QUERY_MODE); + expectedParseInfo.setAggType(NONE); + + expectedParseInfo.getMetrics().add(DataUtils.getSchemaElement("访问次数")); + + DataSetSchema schema = schemaService.getDataSetSchema(DataUtils.productDatasetId); + SchemaElement userElement = getSchemaElementByName(schema.getDimensions(), "用户"); + expectedParseInfo.getDimensionFilters().add(DataUtils.getFilter("user_name", + FilterOperatorEnum.EQUALS, "alice", "用户", userElement.getId())); + + expectedParseInfo.setDateInfo( + DataUtils.getDateConf(DateConf.DateMode.BETWEEN, unit, period, startDay, endDay)); + expectedParseInfo.setQueryType(QueryType.AGGREGATE); + + assertQueryResult(expectedResult, actualResult); + assert actualResult.getQueryResults().size() == 1; + } + + @Test + @SetSystemProperty(key = "s2.test", value = "true") public void testMetricGroupBy() throws Exception { - QueryResult actualResult = submitNewChat("近7天超音数各部门的访问次数", DataUtils.metricAgentId); + QueryResult actualResult = submitNewChat("近7天超音数各部门的访问次数和停留时长", DataUtils.productAgentId); QueryResult expectedResult = new QueryResult(); SemanticParseInfo expectedParseInfo = new SemanticParseInfo(); @@ -67,6 +90,7 @@ public class MetricTest extends BaseTest { expectedParseInfo.setAggType(NONE); expectedParseInfo.getMetrics().add(DataUtils.getSchemaElement("访问次数")); + expectedParseInfo.getMetrics().add(DataUtils.getSchemaElement("停留时长")); expectedParseInfo.getDimensions().add(DataUtils.getSchemaElement("部门")); expectedParseInfo.setDateInfo(DataUtils.getDateConf(DateConf.DateMode.BETWEEN, 7, @@ -79,7 +103,7 @@ public class MetricTest extends BaseTest { @Test public void testMetricFilterCompare() throws Exception { - QueryResult actualResult = submitNewChat("对比alice和lucy的访问次数", DataUtils.metricAgentId); + QueryResult actualResult = submitNewChat("对比alice和lucy的访问次数", DataUtils.productAgentId); QueryResult expectedResult = new QueryResult(); SemanticParseInfo expectedParseInfo = new SemanticParseInfo(); @@ -92,8 +116,11 @@ public class MetricTest extends BaseTest { List list = new ArrayList<>(); list.add("alice"); list.add("lucy"); - QueryFilter dimensionFilter = - DataUtils.getFilter("user_name", FilterOperatorEnum.IN, list, "用户", 2L); + + DataSetSchema schema = schemaService.getDataSetSchema(DataUtils.productDatasetId); + SchemaElement userElement = getSchemaElementByName(schema.getDimensions(), "用户"); + QueryFilter dimensionFilter = DataUtils.getFilter("user_name", FilterOperatorEnum.IN, list, + "用户", userElement.getId()); expectedParseInfo.getDimensionFilters().add(dimensionFilter); expectedParseInfo.setDateInfo( @@ -107,7 +134,7 @@ public class MetricTest extends BaseTest { @Test @Order(3) public void testMetricTopN() throws Exception { - QueryResult actualResult = submitNewChat("近3天访问次数最多的用户", DataUtils.metricAgentId); + QueryResult actualResult = submitNewChat("近3天访问次数最多的用户", DataUtils.productAgentId); QueryResult expectedResult = new QueryResult(); SemanticParseInfo expectedParseInfo = new SemanticParseInfo(); @@ -128,7 +155,7 @@ public class MetricTest extends BaseTest { @Test public void testMetricGroupBySum() throws Exception { - QueryResult actualResult = submitNewChat("近7天超音数各部门的访问次数总和", DataUtils.metricAgentId); + QueryResult actualResult = submitNewChat("近7天超音数各部门的访问次数总和", DataUtils.productAgentId); QueryResult expectedResult = new QueryResult(); SemanticParseInfo expectedParseInfo = new SemanticParseInfo(); expectedResult.setChatContext(expectedParseInfo); @@ -154,7 +181,7 @@ public class MetricTest extends BaseTest { String dateStr = textFormat.format(format.parse(startDay)); QueryResult actualResult = - submitNewChat(String.format("alice在%s的访问次数", dateStr), DataUtils.metricAgentId); + submitNewChat(String.format("alice在%s的访问次数", dateStr), DataUtils.productAgentId); QueryResult expectedResult = new QueryResult(); SemanticParseInfo expectedParseInfo = new SemanticParseInfo(); @@ -163,9 +190,11 @@ public class MetricTest extends BaseTest { expectedResult.setQueryMode(MetricFilterQuery.QUERY_MODE); expectedParseInfo.setAggType(NONE); + DataSetSchema schema = schemaService.getDataSetSchema(DataUtils.productDatasetId); + SchemaElement userElement = getSchemaElementByName(schema.getDimensions(), "用户"); expectedParseInfo.getMetrics().add(DataUtils.getSchemaElement("访问次数")); - expectedParseInfo.getDimensionFilters().add( - DataUtils.getFilter("user_name", FilterOperatorEnum.EQUALS, "alice", "用户", 2L)); + expectedParseInfo.getDimensionFilters().add(DataUtils.getFilter("user_name", + FilterOperatorEnum.EQUALS, "alice", "用户", userElement.getId())); expectedParseInfo.setDateInfo( DataUtils.getDateConf(DateConf.DateMode.BETWEEN, 1, period, startDay, startDay)); diff --git a/launchers/standalone/src/test/java/com/tencent/supersonic/evaluation/Text2SQLEval.java b/launchers/standalone/src/test/java/com/tencent/supersonic/evaluation/Text2SQLEval.java index 21a6869c6..4dd9dfb7d 100644 --- a/launchers/standalone/src/test/java/com/tencent/supersonic/evaluation/Text2SQLEval.java +++ b/launchers/standalone/src/test/java/com/tencent/supersonic/evaluation/Text2SQLEval.java @@ -5,7 +5,10 @@ import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.tencent.supersonic.chat.BaseTest; import com.tencent.supersonic.chat.api.pojo.response.QueryResult; -import com.tencent.supersonic.chat.server.agent.*; +import com.tencent.supersonic.chat.server.agent.Agent; +import com.tencent.supersonic.chat.server.agent.AgentToolType; +import com.tencent.supersonic.chat.server.agent.DatasetTool; +import com.tencent.supersonic.chat.server.agent.ToolConfig; import com.tencent.supersonic.common.config.ChatModel; import com.tencent.supersonic.common.pojo.ChatApp; import com.tencent.supersonic.common.pojo.User; @@ -133,11 +136,28 @@ public class Text2SQLEval extends BaseTest { assert result.getTextResult().contains("3"); } + @Test + public void test_detail_query() throws Exception { + long start = System.currentTimeMillis(); + QueryResult result = submitNewChat("特斯拉旗下有哪些品牌", agentId); + durations.add(System.currentTimeMillis() - start); + assert result.getQueryColumns().size() >= 1; + assert result.getTextResult().contains("Model Y"); + assert result.getTextResult().contains("Model 3"); + } + public Agent getLLMAgent() { Agent agent = new Agent(); agent.setName("Agent for Test"); ToolConfig toolConfig = new ToolConfig(); - toolConfig.getTools().add(getDatasetTool()); + DatasetTool datasetTool = new DatasetTool(); + datasetTool.setType(AgentToolType.DATASET); + datasetTool.setDataSetIds(Lists.newArrayList(DataUtils.productDatasetId)); + toolConfig.getTools().add(datasetTool); + DatasetTool datasetTool2 = new DatasetTool(); + datasetTool2.setType(AgentToolType.DATASET); + datasetTool2.setDataSetIds(Lists.newArrayList(DataUtils.companyDatasetId)); + toolConfig.getTools().add(datasetTool2); agent.setToolConfig(JSONObject.toJSONString(toolConfig)); // create chat model for this evaluation ChatModel chatModel = new ChatModel(); @@ -154,11 +174,4 @@ public class Text2SQLEval extends BaseTest { return agent; } - private static DatasetTool getDatasetTool() { - DatasetTool datasetTool = new DatasetTool(); - datasetTool.setType(AgentToolType.DATASET); - datasetTool.setDataSetIds(Lists.newArrayList(1L)); - - return datasetTool; - } } diff --git a/launchers/standalone/src/test/java/com/tencent/supersonic/headless/QueryByMetricTest.java b/launchers/standalone/src/test/java/com/tencent/supersonic/headless/QueryByMetricTest.java index b4e3dd653..5f03983d5 100644 --- a/launchers/standalone/src/test/java/com/tencent/supersonic/headless/QueryByMetricTest.java +++ b/launchers/standalone/src/test/java/com/tencent/supersonic/headless/QueryByMetricTest.java @@ -1,14 +1,18 @@ package com.tencent.supersonic.headless; +import com.tencent.supersonic.common.pojo.Filter; import com.tencent.supersonic.common.pojo.User; +import com.tencent.supersonic.common.pojo.enums.FilterOperatorEnum; import com.tencent.supersonic.headless.api.pojo.request.QueryMetricReq; import com.tencent.supersonic.headless.api.pojo.request.QueryStructReq; import com.tencent.supersonic.headless.api.pojo.response.SemanticQueryResp; import com.tencent.supersonic.headless.server.service.MetricService; import org.junit.Assert; import org.junit.jupiter.api.Test; +import org.junitpioneer.jupiter.SetSystemProperty; import org.springframework.beans.factory.annotation.Autowired; +import java.time.LocalDate; import java.util.Arrays; import static org.junit.Assert.assertThrows; @@ -23,16 +27,24 @@ public class QueryByMetricTest extends BaseTest { QueryMetricReq queryMetricReq = new QueryMetricReq(); queryMetricReq.setMetricNames(Arrays.asList("stay_hours", "pv")); queryMetricReq.setDimensionNames(Arrays.asList("user_name", "department")); + queryMetricReq.getFilters().add(Filter.builder().name("imp_date") + .operator(FilterOperatorEnum.MINOR_THAN_EQUALS).relation(Filter.Relation.FILTER) + .value(LocalDate.now().toString()).build()); SemanticQueryResp queryResp = queryByMetric(queryMetricReq, User.getDefaultUser()); Assert.assertNotNull(queryResp.getResultList()); Assert.assertEquals(6, queryResp.getResultList().size()); } @Test + @SetSystemProperty(key = "s2.test", value = "true") public void testWithMetricAndDimensionNames() throws Exception { QueryMetricReq queryMetricReq = new QueryMetricReq(); queryMetricReq.setMetricNames(Arrays.asList("停留时长", "访问次数")); queryMetricReq.setDimensionNames(Arrays.asList("用户", "部门")); + queryMetricReq.getFilters() + .add(Filter.builder().name("数据日期").operator(FilterOperatorEnum.MINOR_THAN_EQUALS) + .relation(Filter.Relation.FILTER).value(LocalDate.now().toString()) + .build()); SemanticQueryResp queryResp = queryByMetric(queryMetricReq, User.getDefaultUser()); Assert.assertNotNull(queryResp.getResultList()); Assert.assertEquals(6, queryResp.getResultList().size()); @@ -44,6 +56,9 @@ public class QueryByMetricTest extends BaseTest { queryMetricReq.setDomainId(1L); queryMetricReq.setMetricNames(Arrays.asList("stay_hours", "pv")); queryMetricReq.setDimensionNames(Arrays.asList("user_name", "department")); + queryMetricReq.getFilters().add(Filter.builder().name("imp_date") + .operator(FilterOperatorEnum.MINOR_THAN_EQUALS).relation(Filter.Relation.FILTER) + .value(LocalDate.now().toString()).build()); SemanticQueryResp queryResp = queryByMetric(queryMetricReq, User.getDefaultUser()); Assert.assertNotNull(queryResp.getResultList()); Assert.assertEquals(6, queryResp.getResultList().size()); @@ -61,6 +76,9 @@ public class QueryByMetricTest extends BaseTest { queryMetricReq.setDomainId(1L); queryMetricReq.setMetricIds(Arrays.asList(1L, 3L)); queryMetricReq.setDimensionIds(Arrays.asList(1L, 2L)); + queryMetricReq.getFilters().add(Filter.builder().name("imp_date") + .operator(FilterOperatorEnum.MINOR_THAN_EQUALS).relation(Filter.Relation.FILTER) + .value(LocalDate.now().toString()).build()); SemanticQueryResp queryResp = queryByMetric(queryMetricReq, User.getDefaultUser()); Assert.assertNotNull(queryResp.getResultList()); Assert.assertEquals(6, queryResp.getResultList().size()); diff --git a/launchers/standalone/src/test/java/com/tencent/supersonic/headless/TranslateTest.java b/launchers/standalone/src/test/java/com/tencent/supersonic/headless/TranslateTest.java index 555711cc5..18d2880bb 100644 --- a/launchers/standalone/src/test/java/com/tencent/supersonic/headless/TranslateTest.java +++ b/launchers/standalone/src/test/java/com/tencent/supersonic/headless/TranslateTest.java @@ -18,7 +18,7 @@ public class TranslateTest extends BaseTest { public void testSqlExplain() throws Exception { String sql = "SELECT 部门, SUM(访问次数) AS 访问次数 FROM 超音数PVUV统计 GROUP BY 部门 "; SemanticTranslateResp explain = semanticLayerService.translate( - QueryReqBuilder.buildS2SQLReq(sql, DataUtils.getMetricAgentView()), + QueryReqBuilder.buildS2SQLReq(sql, DataUtils.productDatasetId), User.getDefaultUser()); assertNotNull(explain); assertNotNull(explain.getQuerySQL()); diff --git a/launchers/standalone/src/test/java/com/tencent/supersonic/util/DataUtils.java b/launchers/standalone/src/test/java/com/tencent/supersonic/util/DataUtils.java index 4e28f61a3..2292d73b5 100644 --- a/launchers/standalone/src/test/java/com/tencent/supersonic/util/DataUtils.java +++ b/launchers/standalone/src/test/java/com/tencent/supersonic/util/DataUtils.java @@ -15,10 +15,15 @@ import static java.time.LocalDate.now; public class DataUtils { - public static final Integer metricAgentId = 1; - public static final Integer tagAgentId = 2; + public static final Integer productAgentId = 1; + public static final Integer companyAgentId = 2; + public static final Integer singerAgentId = 3; + + public static final Long productDatasetId = 1L; + public static final Long companyDatasetId = 2L; + public static final Long singerDatasettId = 3L; + public static final Integer ONE_TURNS_CHAT_ID = 10; - public static final Integer MULTI_TURNS_CHAT_ID = 11; private static final User user_test = User.getDefaultUser(); public static User getUser() { @@ -40,7 +45,7 @@ public class DataUtils { public static ChatParseReq getChatParseReq(Integer id, String query, boolean enableLLM) { ChatParseReq chatParseReq = new ChatParseReq(); chatParseReq.setQueryText(query); - chatParseReq.setAgentId(metricAgentId); + chatParseReq.setAgentId(productAgentId); chatParseReq.setChatId(id); chatParseReq.setUser(user_test); chatParseReq.setDisableLLM(!enableLLM); @@ -92,7 +97,4 @@ public class DataUtils { return result; } - public static Long getMetricAgentView() { - return 1L; - } } diff --git a/launchers/standalone/src/test/java/com/tencent/supersonic/util/LLMConfigUtils.java b/launchers/standalone/src/test/java/com/tencent/supersonic/util/LLMConfigUtils.java index f95056482..88d855e02 100644 --- a/launchers/standalone/src/test/java/com/tencent/supersonic/util/LLMConfigUtils.java +++ b/launchers/standalone/src/test/java/com/tencent/supersonic/util/LLMConfigUtils.java @@ -11,7 +11,12 @@ public class LLMConfigUtils { OPENAI_GLM(false), OLLAMA_LLAMA3(true), OLLAMA_QWEN2(true), - OLLAMA_QWEN25(true); + OLLAMA_QWEN25_7B(true), + OLLAMA_QWEN25_14B(true), + OLLAMA_QWEN25_CODE_7B(true), + OLLAMA_QWEN25_CODE_3B(true), + OLLAMA_GLM4(true); + public boolean isOllam; @@ -35,10 +40,26 @@ public class LLMConfigUtils { baseUrl = "http://localhost:11434"; modelName = "qwen2:7b"; break; - case OLLAMA_QWEN25: + case OLLAMA_QWEN25_7B: baseUrl = "http://localhost:11434"; modelName = "qwen2.5:7b"; break; + case OLLAMA_QWEN25_14B: + baseUrl = "http://localhost:11434"; + modelName = "qwen2.5:14b"; + break; + case OLLAMA_QWEN25_CODE_7B: + baseUrl = "http://localhost:11434"; + modelName = "qwen2.5-coder:7b"; + break; + case OLLAMA_QWEN25_CODE_3B: + baseUrl = "http://localhost:11434"; + modelName = "qwen2.5-coder:3b"; + break; + case OLLAMA_GLM4: + baseUrl = "http://localhost:11434"; + modelName = "glm4:latest"; + break; case OPENAI_GLM: baseUrl = "https://open.bigmodel.cn/api/pas/v4/"; apiKey = "REPLACE_WITH_YOUR_KEY"; diff --git a/launchers/standalone/src/test/resources/application-local.yaml b/launchers/standalone/src/test/resources/application-local.yaml index 5f3e99e22..a9fa2a589 100644 --- a/launchers/standalone/src/test/resources/application-local.yaml +++ b/launchers/standalone/src/test/resources/application-local.yaml @@ -1,14 +1,34 @@ spring: datasource: driver-class-name: org.h2.Driver - url: jdbc:h2:mem:semantic;DATABASE_TO_UPPER=false;QUERY_TIMEOUT=100 + url: jdbc:h2:mem:semantic;DATABASE_TO_UPPER=false;QUERY_TIMEOUT=30 username: root password: semantic sql: init: - schema-locations: classpath:db/schema-h2.sql - data-locations: classpath:db/data-h2.sql + schema-locations: classpath:db/schema-h2.sql,classpath:db/schema-h2-demo.sql + data-locations: classpath:db/data-h2.sql,classpath:db/data-h2-demo.sql h2: console: path: /h2-console/semantic - enabled: true \ No newline at end of file + enabled: true + +### Comment out following lines if using MySQL +#spring: +# datasource: +# driver-class-name: com.mysql.cj.jdbc.Driver +# url: jdbc:mysql://localhost:3306/s2_database?user=root +# username: root +# password: +# sql: +# enabled: true +# mode: always +# username: root +# password: +# init: +# schema-locations: classpath:db/schema-mysql.sql,classpath:db/schema-mysql-demo.sql +# data-locations: classpath:db/data-mysql.sql,classpath:db/data-mysql-demo.sql +# h2: +# console: +# path: /h2-console/semantic +# enabled: true \ No newline at end of file diff --git a/launchers/standalone/src/test/resources/db/data-h2-demo.sql b/launchers/standalone/src/test/resources/db/data-h2-demo.sql new file mode 100644 index 000000000..6c0ab0091 --- /dev/null +++ b/launchers/standalone/src/test/resources/db/data-h2-demo.sql @@ -0,0 +1,1083 @@ +-------S2VisitsDemo +MERGE INTO s2_user_department (user_name, department) values ('jack','HR'); +MERGE INTO s2_user_department (user_name, department) values ('tom','sales'); +MERGE INTO s2_user_department (user_name, department) values ('lucy','marketing'); +MERGE INTO s2_user_department (user_name, department) values ('john','strategy'); +MERGE INTO s2_user_department (user_name, department) values ('alice','sales'); +MERGE INTO s2_user_department (user_name, department) values ('dean','marketing'); + +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (CURRENT_DATE(), 'lucy', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (CURRENT_DATE(), 'jack', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (CURRENT_DATE(), 'lucy', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (CURRENT_DATE(), 'tom', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (CURRENT_DATE(), 'john', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (CURRENT_DATE(), 'alice', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (CURRENT_DATE(), 'dean', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (CURRENT_DATE(), 'john', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (CURRENT_DATE(), 'tom', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (CURRENT_DATE(), 'lucy', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (CURRENT_DATE(), 'dean', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -5, CURRENT_DATE()), 'lucy', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'jack', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'lucy', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'tom', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'john', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -6, CURRENT_DATE()), 'alice', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -7, CURRENT_DATE()), 'dean', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'john', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'tom', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'lucy', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'dean', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'dean', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'jack', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'john', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'lucy', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'dean', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'dean', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'john', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'john', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'alice', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'lucy', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -17, CURRENT_DATE()), 'lucy', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -18, CURRENT_DATE()), 'tom', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -6, CURRENT_DATE()), 'lucy', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -19, CURRENT_DATE()), 'alice', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'john', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'lucy', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'alice', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'john', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -19, CURRENT_DATE()), 'dean', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'jack', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'dean', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -19, CURRENT_DATE()), 'lucy', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'jack', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -22, CURRENT_DATE()), 'john', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'tom', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'john', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'lucy', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'alice', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'tom', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'jack', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'alice', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'lucy', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'john', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'john', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'dean', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'tom', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'jack', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'lucy', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'jack', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -6, CURRENT_DATE()), 'jack', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'john', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -18, CURRENT_DATE()), 'jack', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'john', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'alice', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'jack', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'lucy', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'lucy', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'john', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'alice', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'john', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'john', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -27, CURRENT_DATE()), 'john', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -27, CURRENT_DATE()), 'lucy', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'alice', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'alice', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -28, CURRENT_DATE()), 'alice', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'tom', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'john', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -19, CURRENT_DATE()), 'jack', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'john', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -7, CURRENT_DATE()), 'jack', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -18, CURRENT_DATE()), 'tom', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'dean', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -17, CURRENT_DATE()), 'jack', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -27, CURRENT_DATE()), 'lucy', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'john', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'jack', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'alice', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -19, CURRENT_DATE()), 'lucy', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'alice', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'dean', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'jack', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -18, CURRENT_DATE()), 'john', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -22, CURRENT_DATE()), 'dean', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'john', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'lucy', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'lucy', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -22, CURRENT_DATE()), 'john', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'jack', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'lucy', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'alice', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'john', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'tom', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'tom', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'dean', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'dean', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'tom', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'john', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'john', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'tom', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'dean', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'alice', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'dean', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'dean', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'john', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'tom', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'john', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'alice', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'lucy', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'jack', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'tom', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'jack', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'jack', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'john', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'john', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'jack', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -27, CURRENT_DATE()), 'lucy', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'jack', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'alice', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'dean', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'lucy', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -6, CURRENT_DATE()), 'tom', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'dean', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'dean', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -28, CURRENT_DATE()), 'dean', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'dean', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -18, CURRENT_DATE()), 'jack', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'dean', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'jack', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'john', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -19, CURRENT_DATE()), 'alice', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -7, CURRENT_DATE()), 'john', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'tom', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'john', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'dean', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'john', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'dean', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'alice', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'john', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'lucy', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'john', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'jack', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'lucy', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'john', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'john', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -18, CURRENT_DATE()), 'john', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'alice', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -27, CURRENT_DATE()), 'dean', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'lucy', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'dean', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'dean', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -22, CURRENT_DATE()), 'john', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'lucy', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -17, CURRENT_DATE()), 'john', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'dean', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'tom', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'jack', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -7, CURRENT_DATE()), 'tom', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'john', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'tom', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'tom', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -19, CURRENT_DATE()), 'john', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'john', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'john', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'john', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -6, CURRENT_DATE()), 'dean', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'john', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'alice', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'john', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'alice', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'john', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'john', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'alice', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -17, CURRENT_DATE()), 'alice', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'tom', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'jack', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'john', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -17, CURRENT_DATE()), 'john', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'tom', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'alice', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -18, CURRENT_DATE()), 'alice', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -17, CURRENT_DATE()), 'john', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'jack', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'alice', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'jack', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'lucy', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'john', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -7, CURRENT_DATE()), 'jack', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'tom', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'dean', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'john', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'alice', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'lucy', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'dean', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -27, CURRENT_DATE()), 'dean', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'dean', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -28, CURRENT_DATE()), 'dean', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'alice', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -18, CURRENT_DATE()), 'dean', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'lucy', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'dean', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'dean', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'jack', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'lucy', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'jack', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'alice', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -6, CURRENT_DATE()), 'dean', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -7, CURRENT_DATE()), 'john', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'dean', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'john', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'john', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'jack', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'dean', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'tom', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'john', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -6, CURRENT_DATE()), 'lucy', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'dean', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -17, CURRENT_DATE()), 'dean', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -18, CURRENT_DATE()), 'tom', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'jack', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'jack', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'john', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'jack', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'lucy', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'john', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'alice', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'lucy', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'alice', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'alice', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'jack', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'tom', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'lucy', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'alice', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'lucy', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'jack', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'dean', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -19, CURRENT_DATE()), 'alice', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -17, CURRENT_DATE()), 'lucy', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'jack', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'tom', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -28, CURRENT_DATE()), 'tom', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'dean', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'dean', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'tom', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'dean', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'dean', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'alice', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'alice', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'tom', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -6, CURRENT_DATE()), 'dean', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -28, CURRENT_DATE()), 'john', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'tom', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'tom', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'dean', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'john', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'lucy', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'dean', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'lucy', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'john', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -27, CURRENT_DATE()), 'lucy', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'john', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'dean', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'dean', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'dean', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'tom', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'lucy', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'jack', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'dean', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'alice', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'jack', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'tom', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'jack', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'dean', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -19, CURRENT_DATE()), 'lucy', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'john', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -7, CURRENT_DATE()), 'tom', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'dean', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'alice', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'tom', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -17, CURRENT_DATE()), 'john', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'tom', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'lucy', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'jack', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'alice', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'tom', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -22, CURRENT_DATE()), 'alice', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -19, CURRENT_DATE()), 'tom', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'dean', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'dean', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -27, CURRENT_DATE()), 'john', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'alice', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -28, CURRENT_DATE()), 'alice', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'lucy', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -22, CURRENT_DATE()), 'john', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -7, CURRENT_DATE()), 'alice', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'tom', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -18, CURRENT_DATE()), 'jack', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'lucy', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'jack', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'alice', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'jack', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'john', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -6, CURRENT_DATE()), 'jack', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'dean', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'jack', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'lucy', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'jack', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -19, CURRENT_DATE()), 'dean', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'tom', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'jack', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'dean', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'alice', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'jack', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'john', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -22, CURRENT_DATE()), 'jack', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'dean', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'john', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'alice', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'jack', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'lucy', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'dean', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -22, CURRENT_DATE()), 'john', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'jack', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'jack', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'jack', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -17, CURRENT_DATE()), 'tom', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'jack', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'john', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'dean', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -27, CURRENT_DATE()), 'tom', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -18, CURRENT_DATE()), 'tom', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'alice', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'tom', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'john', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'john', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -28, CURRENT_DATE()), 'tom', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'alice', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'lucy', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'lucy', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'john', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'alice', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'alice', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'jack', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'alice', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'john', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'jack', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'john', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'jack', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'dean', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'dean', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'tom', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'tom', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'dean', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'jack', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'jack', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'alice', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -7, CURRENT_DATE()), 'tom', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'tom', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -28, CURRENT_DATE()), 'alice', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'alice', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'john', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -17, CURRENT_DATE()), 'alice', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'lucy', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'jack', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'alice', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'alice', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -7, CURRENT_DATE()), 'alice', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'lucy', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -6, CURRENT_DATE()), 'tom', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'jack', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'jack', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -6, CURRENT_DATE()), 'tom', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'dean', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'tom', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'dean', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'tom', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'tom', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'john', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'jack', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'dean', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -19, CURRENT_DATE()), 'alice', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'john', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'tom', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'dean', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -19, CURRENT_DATE()), 'alice', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'tom', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -18, CURRENT_DATE()), 'tom', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -6, CURRENT_DATE()), 'alice', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'john', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'dean', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'lucy', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'jack', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'lucy', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'alice', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'tom', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'tom', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'john', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -6, CURRENT_DATE()), 'jack', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -6, CURRENT_DATE()), 'dean', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'alice', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'lucy', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'john', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'jack', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'lucy', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'alice', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -18, CURRENT_DATE()), 'tom', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'jack', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'dean', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -27, CURRENT_DATE()), 'tom', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'tom', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'lucy', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'dean', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -22, CURRENT_DATE()), 'john', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'alice', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'jack', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'dean', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'dean', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'lucy', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -19, CURRENT_DATE()), 'jack', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'alice', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'dean', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'dean', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -28, CURRENT_DATE()), 'dean', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'lucy', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'tom', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'dean', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'john', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'jack', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'dean', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'jack', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -28, CURRENT_DATE()), 'tom', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'dean', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'lucy', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'jack', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'john', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'alice', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'jack', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'lucy', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'alice', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'tom', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'alice', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -17, CURRENT_DATE()), 'tom', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'dean', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -7, CURRENT_DATE()), 'john', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -17, CURRENT_DATE()), 'lucy', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'john', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'jack', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -28, CURRENT_DATE()), 'tom', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'lucy', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'lucy', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -27, CURRENT_DATE()), 'tom', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -17, CURRENT_DATE()), 'lucy', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'alice', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'john', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'dean', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -22, CURRENT_DATE()), 'dean', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'lucy', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'lucy', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'alice', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'alice', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'alice', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -19, CURRENT_DATE()), 'lucy', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'tom', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'dean', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'john', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'john', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'tom', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -28, CURRENT_DATE()), 'tom', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -18, CURRENT_DATE()), 'dean', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'john', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'dean', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -27, CURRENT_DATE()), 'alice', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'john', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'tom', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -27, CURRENT_DATE()), 'john', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'dean', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'john', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -18, CURRENT_DATE()), 'lucy', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'tom', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'alice', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -27, CURRENT_DATE()), 'dean', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'alice', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'jack', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -22, CURRENT_DATE()), 'jack', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'john', 'p2'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'tom', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'lucy', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -28, CURRENT_DATE()), 'tom', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'dean', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'lucy', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'jack', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -18, CURRENT_DATE()), 'lucy', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'alice', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'john', 'p1'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'alice', 'p3'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'alice', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'tom', 'p4'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'dean', 'p5'); +INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'tom', 'p4'); + +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'jack', '0.7636857512911863', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'dean', '0.17663327393462436', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'alice', '0.38943688941552057', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'lucy', '0.2715819955225307', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'tom', '0.9358210273119568', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'alice', '0.9364586435510802', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'jack', '0.9707723036513162', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'tom', '0.8497763866782723', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'alice', '0.15504417761372413', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'jack', '0.9507563118298399', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'alice', '0.9746364180572994', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'dean', '0.12869214941133378', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'lucy', '0.3024970533288409', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'tom', '0.6639702099980812', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'lucy', '0.4929901454858626', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'lucy', '0.06853040276026445', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'tom', '0.8488086078299616', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'lucy', '0.8589111177125592', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'alice', '0.5576357066482228', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -7, CURRENT_DATE()), 'john', '0.8047888670006846', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'john', '0.766944548494366', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'lucy', '0.5280072184505449', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'tom', '0.9693343356046343', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'dean', '0.12805203958456424', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -22, CURRENT_DATE()), 'dean', '0.16963603387027637', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'alice', '0.5901202956521101', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'jack', '0.12710364646712236', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'tom', '0.6346530909156196', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'dean', '0.12461289103639872', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'john', '0.9863947334662437', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'alice', '0.48899961064192987', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -27, CURRENT_DATE()), 'alice', '0.5382796792688207', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'dean', '0.3506568687014143', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'jack', '0.8633072449771709', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'tom', '0.13999135315363687', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'john', '0.07258740493845894', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'jack', '0.5244413940436958', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'john', '0.13258670732966138', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -19, CURRENT_DATE()), 'john', '0.6015982054464575', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'lucy', '0.05513158944480323', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'alice', '0.6707121735296985', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -18, CURRENT_DATE()), 'jack', '0.9330440339006469', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'dean', '0.5630674323371607', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -27, CURRENT_DATE()), 'dean', '0.8720647566229917', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'john', '0.8331899070546519', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -6, CURRENT_DATE()), 'alice', '0.6712876436249856', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'alice', '0.6694409980332703', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -27, CURRENT_DATE()), 'john', '0.3703307480606334', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'dean', '0.775368688472696', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'lucy', '0.9151205443267096', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'tom', '0.09543108823305857', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'dean', '0.7893992120771057', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'lucy', '0.5119923080070498', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'lucy', '0.49906724167974936', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -7, CURRENT_DATE()), 'tom', '0.046258282700961884', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -7, CURRENT_DATE()), 'dean', '0.44843595680103954', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'alice', '0.7743935471689718', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'john', '0.5855299615656824', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'lucy', '0.9412963512379853', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'jack', '0.8383247587082538', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'lucy', '0.14517876867236124', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'john', '0.9327229861441061', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'john', '0.19042326582894153', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'jack', '0.6029067818254513', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'jack', '0.21715964747214422', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -18, CURRENT_DATE()), 'lucy', '0.34259842721045974', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -28, CURRENT_DATE()), 'john', '0.7064419016593382', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'lucy', '0.5725636566517865', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -17, CURRENT_DATE()), 'john', '0.22332539583809208', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'jack', '0.8049036189055911', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'alice', '0.6029674758974956', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'lucy', '0.11884976360561716', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -28, CURRENT_DATE()), 'alice', '0.7124916829130662', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'jack', '0.5893693718556829', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'alice', '0.602073304496253', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'tom', '0.10491061160039927', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'dean', '0.9006548872378379', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'alice', '0.8545144244288455', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -18, CURRENT_DATE()), 'jack', '0.16915384987875726', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'dean', '0.2271640700690446', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'alice', '0.7807518577160636', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'john', '0.8919859648888653', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'dean', '0.1564450687270359', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'jack', '0.5840549187653847', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'tom', '0.2213255596777869', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'tom', '0.07868261880306426', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'jack', '0.07710010861455818', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'jack', '0.5131249730162654', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'jack', '0.5035035055368601', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'tom', '0.8996978291173905', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'john', '0.057442290722216294', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'jack', '0.6443079066865616', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'lucy', '0.7398098480748726', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -27, CURRENT_DATE()), 'dean', '0.9835694815034591', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'john', '0.9879213445635557', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'jack', '0.4020136688147111', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'lucy', '0.6698797170128024', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'john', '0.17325132416789113', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'lucy', '0.5784229486763606', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'tom', '0.9185978183932058', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'jack', '0.5474783153973963', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'alice', '0.9730731954700215', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'tom', '0.5390873359288765', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'alice', '0.20522241320887713', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'alice', '0.4088233242325021', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'jack', '0.7608047695853417', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'tom', '0.2749731221085713', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'john', '0.06154055374702494', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'dean', '0.460668002022406', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'alice', '0.4474746325306228', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'alice', '0.5761666885467472', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -7, CURRENT_DATE()), 'dean', '0.33233441360339655', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'alice', '0.7426534909874778', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -6, CURRENT_DATE()), 'tom', '0.5841437875889118', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'alice', '0.2818296500094526', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -17, CURRENT_DATE()), 'tom', '0.8670888843915217', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'alice', '0.5249294365740248', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'jack', '0.5483356748008438', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'dean', '0.7278566847412673', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'jack', '0.6779976902157362', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'lucy', '0.09995341651736978', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'jack', '0.4528538159233879', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'alice', '0.5870756885301056', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'tom', '0.9842091927290255', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'tom', '0.04580936015706816', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'alice', '0.8814678270145769', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -27, CURRENT_DATE()), 'john', '0.06517379256096412', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'alice', '0.8769832364187129', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'dean', '0.584562279025023', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -22, CURRENT_DATE()), 'john', '0.8102404090621375', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'john', '0.11481653429176686', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'jack', '0.43422888918962554', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -22, CURRENT_DATE()), 'lucy', '0.0684414272594508', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'alice', '0.976546463969412', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'dean', '0.617906858141431', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -27, CURRENT_DATE()), 'jack', '0.08663740247579998', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'lucy', '0.7124944606691416', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'alice', '0.1321700521239627', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -19, CURRENT_DATE()), 'jack', '0.3078946609431664', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'alice', '0.6149442855237194', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -7, CURRENT_DATE()), 'alice', '0.5963801306980994', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'lucy', '0.6999542038973406', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -19, CURRENT_DATE()), 'john', '0.4599112653446624', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'dean', '0.20300901401048832', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'john', '0.39989705958717037', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'jack', '0.2486378364940327', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'john', '0.16880398079144077', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'tom', '0.73927288385526', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -22, CURRENT_DATE()), 'john', '0.8645283506689198', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'alice', '0.3266940826759587', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -7, CURRENT_DATE()), 'tom', '0.9195490073037541', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'lucy', '0.9452523036658287', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'john', '0.21269683438120535', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'dean', '0.7377502855387184', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -27, CURRENT_DATE()), 'tom', '0.38981597634408716', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'john', '0.7001799391999863', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'john', '0.6616720024008785', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -19, CURRENT_DATE()), 'dean', '0.497721735058096', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -17, CURRENT_DATE()), 'jack', '0.22255613760959603', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -22, CURRENT_DATE()), 'jack', '0.05247640233319417', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'dean', '0.27237572107833363', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'alice', '0.9529452406380252', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'alice', '0.28243045060463157', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'lucy', '0.17880444250082506', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'john', '0.035050038002381156', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'lucy', '0.840803223728221', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'jack', '0.5318457377361356', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'tom', '0.9280332892460665', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'lucy', '0.752354382202208', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'dean', '0.1866528331789219', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -17, CURRENT_DATE()), 'alice', '0.7016165545791373', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'john', '0.4191547989960899', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'john', '0.7025516699007639', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'john', '0.6160127317884274', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'alice', '0.91223094958137', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'tom', '0.4383056089013998', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -18, CURRENT_DATE()), 'jack', '0.595750781166582', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -28, CURRENT_DATE()), 'lucy', '0.9472349338730268', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -6, CURRENT_DATE()), 'jack', '0.0519104588842193', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'alice', '0.48043983034526205', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'lucy', '0.14754707786497478', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'alice', '0.36124288370035695', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'dean', '0.21777919493494613', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'lucy', '0.22637666702475057', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'john', '0.9378215576942598', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'john', '0.3309229261144562', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'alice', '0.7602880453727515', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'alice', '0.9470462487873785', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'dean', '0.6770215935547629', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -22, CURRENT_DATE()), 'john', '0.1586074803669385', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -28, CURRENT_DATE()), 'lucy', '0.2754855564794071', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'tom', '0.8355347738454384', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'alice', '0.7251813505573811', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'jack', '0.006606625589642534', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -19, CURRENT_DATE()), 'alice', '0.304832277753024', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'jack', '0.026368662837989554', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -6, CURRENT_DATE()), 'tom', '0.6855977520602776', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -22, CURRENT_DATE()), 'tom', '0.8193746826441749', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'john', '0.021179295102459972', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'jack', '0.1533849522536005', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'alice', '0.18893553542301778', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'john', '0.39870999343833624', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'john', '0.9985665103520182', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'john', '0.6961441157700171', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'tom', '0.9861933923851885', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'tom', '0.993076500099477', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'alice', '0.4320547269058953', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'lucy', '0.18441071030375877', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'jack', '0.1501504986117118', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -27, CURRENT_DATE()), 'tom', '0.252021845734527', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -17, CURRENT_DATE()), 'lucy', '0.24442701577183745', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'tom', '0.07563738855797564', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'john', '0.34247820646440985', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'john', '0.9456979276862031', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'alice', '0.19494357263973816', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'alice', '0.9371493867882469', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -7, CURRENT_DATE()), 'john', '0.6136241316589367', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -22, CURRENT_DATE()), 'alice', '0.8922330760877784', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -22, CURRENT_DATE()), 'dean', '0.9001986074661864', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'tom', '0.4889702884422866', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'tom', '0.2689551234431401', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'dean', '0.5223573993758465', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'tom', '0.05042295556527243', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'tom', '0.2717147121880483', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'john', '0.7397093309370814', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'dean', '0.157064341631733', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'lucy', '0.7213399784998017', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'tom', '0.764081440588005', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'john', '0.7514070600074144', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -28, CURRENT_DATE()), 'john', '0.611647412825278', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'tom', '0.6600796877195596', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'john', '0.8942204153751679', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'dean', '0.07398121085929721', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -28, CURRENT_DATE()), 'dean', '0.1652506990439564', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'dean', '0.5849759516111703', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -27, CURRENT_DATE()), 'tom', '0.1672502732600889', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'tom', '0.7836135556233219', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'dean', '0.26181269644936356', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'alice', '0.6577275876355586', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -19, CURRENT_DATE()), 'tom', '0.3067293364197956', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'alice', '0.8608288543866495', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -28, CURRENT_DATE()), 'john', '0.814283434116926', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -28, CURRENT_DATE()), 'jack', '0.33993584425872936', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -6, CURRENT_DATE()), 'john', '0.010812798859160089', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'dean', '0.5156558224263926', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -17, CURRENT_DATE()), 'jack', '0.46320035330198406', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'lucy', '0.2651020283994786', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'john', '0.42467241545664147', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'tom', '0.3695905136678498', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'tom', '0.15269122123348644', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'jack', '0.6755688670583248', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -28, CURRENT_DATE()), 'jack', '0.39064306179528907', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'john', '0.36479296691952023', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -6, CURRENT_DATE()), 'lucy', '0.5069249157662691', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'tom', '0.4785315495532231', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -6, CURRENT_DATE()), 'dean', '0.7582526218052175', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'dean', '0.42064109605717914', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'dean', '0.5587757581237022', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'lucy', '0.3561686564964428', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'tom', '0.7101688305173135', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'dean', '0.6518061375522985', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'tom', '0.7564485884156583', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'tom', '0.36531347293134464', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'jack', '0.5201689359070235', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'john', '0.7138792929290383', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'tom', '0.9751003716333827', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'tom', '0.5281906318027629', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'tom', '0.6291356541485003', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'jack', '0.1938712974807698', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'john', '0.6267850210775459', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'tom', '0.4469970592043767', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'lucy', '0.7690659124175409', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -27, CURRENT_DATE()), 'jack', '0.13335067838090386', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -27, CURRENT_DATE()), 'jack', '0.2966621725922035', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -19, CURRENT_DATE()), 'john', '0.5740481445089863', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'alice', '0.838028890036331', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'jack', '0.8094354537628714', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'alice', '0.5552924586108698', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'jack', '0.49150373927678315', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'dean', '0.7264346889377966', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'alice', '0.9292830287297702', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'dean', '0.3905616258240767', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'dean', '0.15912349648571666', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'alice', '0.6030082006630102', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'lucy', '0.8712354035243679', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'dean', '0.7685306377211826', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'john', '0.2869913942171415', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'john', '0.7142615166855639', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'tom', '0.5625978475154423', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'jack', '0.13611601734791123', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'alice', '0.6977333962685311', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'jack', '0.35140477709778295', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -28, CURRENT_DATE()), 'john', '0.8805119222967716', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'john', '0.7014124236538637', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -22, CURRENT_DATE()), 'alice', '0.12759538003439375', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'john', '0.7515403792213445', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'lucy', '0.03700239289885987', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'tom', '0.31674618364630946', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'dean', '0.4491378834800146', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'tom', '0.6742764131652571', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -7, CURRENT_DATE()), 'lucy', '0.5286362221140248', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'alice', '0.007890326473113496', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'alice', '0.8046560540950831', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'tom', '0.7198364371127147', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'tom', '0.7400546712169153', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'jack', '0.16859870460868698', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'lucy', '0.8462852684569557', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'john', '0.010211452005474353', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'alice', '0.8617802368201087', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'jack', '0.21667479046797633', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'john', '0.8667689615468714', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'jack', '0.16140709875863557', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'dean', '0.16713368182304666', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -7, CURRENT_DATE()), 'lucy', '0.8957484629768053', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'tom', '0.457835758220534', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -22, CURRENT_DATE()), 'jack', '0.9435170960198477', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'jack', '0.9699253608913104', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -28, CURRENT_DATE()), 'john', '0.2309897429566834', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'lucy', '0.7879705066452681', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'john', '0.20795869239817255', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -6, CURRENT_DATE()), 'dean', '0.4110352469382019', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'jack', '0.4979592772533561', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'dean', '0.18810865430947044', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'tom', '0.5001240246982048', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'jack', '0.08341934160029707', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'lucy', '0.04812784841651041', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'alice', '0.4655982693269717', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'dean', '0.8539357978460663', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'john', '0.9649541785823592', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'john', '0.8243635648047365', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -7, CURRENT_DATE()), 'john', '0.929949719929735', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'john', '0.055983276861168996', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'tom', '0.07845430274829746', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'alice', '0.28257674222099116', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'dean', '0.1578419214960578', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'dean', '0.7853118484860825', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'lucy', '0.20790127125904156', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'tom', '0.8650538395535204', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'dean', '0.902116091225815', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -19, CURRENT_DATE()), 'lucy', '0.48542770770171373', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'jack', '0.16725337150113984', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -7, CURRENT_DATE()), 'lucy', '0.3157444453259486', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -7, CURRENT_DATE()), 'tom', '0.565727220131555', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'jack', '0.2531688065358064', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'lucy', '0.9191434620980499', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'jack', '0.9224628853942058', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'jack', '0.3256288410730337', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'jack', '0.9709152566761661', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'dean', '0.9794173893522709', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'alice', '0.16582064407977237', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -17, CURRENT_DATE()), 'alice', '0.2652519246960059', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'alice', '0.04092489871261762', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -22, CURRENT_DATE()), 'jack', '0.3020444893927522', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'john', '0.4655412764350543', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -28, CURRENT_DATE()), 'dean', '0.9226436424888846', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -22, CURRENT_DATE()), 'jack', '0.4707663393012884', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'lucy', '0.3277970119243966', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'tom', '0.4730675479071551', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'jack', '0.10261940477901954', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -17, CURRENT_DATE()), 'alice', '0.4148892373198616', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'john', '0.2877219827348403', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -19, CURRENT_DATE()), 'tom', '0.16212409974675845', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'tom', '0.9567425121214822', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -22, CURRENT_DATE()), 'lucy', '0.19795350030679149', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'john', '0.6954199597749198', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -22, CURRENT_DATE()), 'alice', '0.32884293488801164', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -27, CURRENT_DATE()), 'john', '0.4789917995407148', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -18, CURRENT_DATE()), 'lucy', '0.0698927593996298', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'john', '0.3352267723792438', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'tom', '0.8085116661598726', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'john', '0.17515060210353794', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'dean', '0.6006963088370202', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'alice', '0.8794167536704468', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'dean', '0.04091469320757368', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -17, CURRENT_DATE()), 'tom', '0.6709116812690366', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'john', '0.4850646101328463', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -7, CURRENT_DATE()), 'tom', '0.547488212623346', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'dean', '0.6301717145008927', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'lucy', '0.06123370093612068', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'alice', '0.2545600223228257', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'john', '0.28355287519210803', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'dean', '0.3231348374147818', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'tom', '0.4585172495754063', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'john', '0.7893945285152268', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -22, CURRENT_DATE()), 'john', '0.6810596014794181', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'john', '0.7136031244915907', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'jack', '0.259734039051829', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'jack', '0.7759518703827996', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -19, CURRENT_DATE()), 'john', '0.06288891046833589', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'dean', '0.8242980461154241', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'tom', '0.36590300307021595', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'lucy', '0.20254092528445444', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'tom', '0.5427356081880325', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'dean', '0.1467846603517391', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'john', '0.8975527268892767', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'dean', '0.3483541520806722', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'alice', '0.6922544855316723', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'tom', '0.3690185253006011', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'tom', '0.7564541265683148', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -18, CURRENT_DATE()), 'tom', '0.3634152133342695', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'tom', '0.33740378933701987', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'lucy', '0.7942640738315301', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'jack', '0.7894896778233523', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -22, CURRENT_DATE()), 'jack', '0.7153281477198108', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -22, CURRENT_DATE()), 'tom', '0.5546359859065261', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'john', '0.7727157385809087', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'dean', '0.8707097754747494', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'john', '0.3873936520764878', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'alice', '0.7590305068820566', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'john', '0.512826935863365', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'john', '0.19120284727846926', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -6, CURRENT_DATE()), 'dean', '0.5382693105670825', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'john', '0.826241649014955', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'lucy', '0.6133080470571559', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'jack', '0.6452862617544055', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'lucy', '0.3025772179023586', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'lucy', '4.709864550322962E-4', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'dean', '0.024816355013726588', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -6, CURRENT_DATE()), 'alice', '0.8407500495605565', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'alice', '0.8420879584266481', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'lucy', '0.2719224735814776', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'tom', '0.8939712577294938', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'dean', '0.8086189323362379', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'tom', '0.6063415085381448', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'tom', '0.39783242658234674', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -19, CURRENT_DATE()), 'tom', '0.6085577206028068', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'tom', '0.5154289424127074', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'john', '0.878436600887031', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'john', '0.5577906295015223', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -27, CURRENT_DATE()), 'lucy', '0.1143260282925247', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'jack', '0.312756557275364', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'john', '0.05548807854726956', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'tom', '0.12140791431139175', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'dean', '0.23897628700410234', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'lucy', '0.22223137342481392', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'john', '0.12379891645900953', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'john', '0.33729146112854247', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'dean', '0.8816768640060831', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'jack', '0.6301700633426532', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'alice', '0.4566295223861714', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'john', '0.1777378523933678', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -27, CURRENT_DATE()), 'tom', '0.8163769471165477', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'tom', '0.4380805149704541', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'alice', '0.2987018822475964', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'dean', '0.6726495645391617', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'alice', '0.8394327461109705', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -18, CURRENT_DATE()), 'dean', '0.820512945501936', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'tom', '0.1580105370757261', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'jack', '0.9961450897279505', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -7, CURRENT_DATE()), 'john', '0.6574891890500061', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'john', '0.5201205570085158', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'alice', '0.2445069633928285', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -17, CURRENT_DATE()), 'john', '0.3155229654901067', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'jack', '0.3665971881269575', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'john', '0.5544977915912215', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'tom', '0.15978771803015113', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'lucy', '0.038128748344929186', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -19, CURRENT_DATE()), 'tom', '0.49026304025118594', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'dean', '0.5166802080526571', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'alice', '0.22568230066042194', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -28, CURRENT_DATE()), 'john', '0.9888634109849955', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'jack', '0.21022365182102054', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -18, CURRENT_DATE()), 'john', '0.47052993358031114', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'dean', '0.25686122383263454', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'tom', '0.18929054223320718', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'jack', '0.7925339862375451', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'john', '0.12613308249498645', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'jack', '0.7381524971311578', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'alice', '0.08639585437319919', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -27, CURRENT_DATE()), 'tom', '0.9519897106846164', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'jack', '0.33446548574801926', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'jack', '0.40667134603483324', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'jack', '0.17100718420628735', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'lucy', '0.4445585525686886', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'tom', '0.47372916928883013', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'john', '0.19826861093848824', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'john', '0.13679268112019338', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'tom', '0.9805515708224516', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'dean', '0.4738376165601095', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'dean', '0.5739441073158964', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'alice', '0.8428505498030564', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'lucy', '0.32655416551155336', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'tom', '0.7055736367780644', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'tom', '0.9621355090189875', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'jack', '0.9665339161730553', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'dean', '0.44309781869697995', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -18, CURRENT_DATE()), 'tom', '0.8651220802537761', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'lucy', '0.6451892308277741', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'dean', '0.056797307451316725', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'lucy', '0.6847604118085596', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'jack', '0.13428051757364667', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'lucy', '0.9814797176951834', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'tom', '0.7386074051153445', 'p3'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'alice', '0.4825297824657663', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -19, CURRENT_DATE()), 'alice', '0.06608870508231235', 'p5'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -22, CURRENT_DATE()), 'lucy', '0.6278253028988848', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'alice', '0.6705580511822682', 'p1'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -19, CURRENT_DATE()), 'alice', '0.8131712486302015', 'p2'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'lucy', '0.8124302447925607', 'p4'); +INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'lucy', '0.039935860913407284', 'p2'); + + +-------S2ArtistDemo +MERGE INTO singer (singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES ('周杰伦', '港台','青花瓷','国风',1000000,1000000,1000000); +MERGE INTO singer (singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES ('陈奕迅', '港台','爱情转移','流行',1000000,1000000,1000000); +MERGE INTO singer (singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES ('林俊杰', '港台','美人鱼','流行',1000000,1000000,1000000); +MERGE INTO singer (singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES ('张碧晨', '内地','光的方向','流行',1000000,1000000,1000000); +MERGE INTO singer (singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES ('程响', '内地','人间烟火','国风',1000000,1000000,1000000); +MERGE INTO singer (singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES ('Taylor Swift', '欧美','Love Story','流行',1000000,1000000,1000000); + +MERGE INTO genre(g_name,rating,most_popular_in) VALUES ('tagore',8,'孟加拉国'); +MERGE INTO genre(g_name,rating,most_popular_in) VALUES ('nazrul',7,'孟加拉国'); +MERGE INTO genre(g_name,rating,most_popular_in) VALUES ('民间',9,'锡尔赫特、吉大港、库斯蒂亚'); +MERGE INTO genre(g_name,rating,most_popular_in) VALUES ('现代',8,'孟加拉国'); +MERGE INTO genre(g_name,rating,most_popular_in) VALUES ('蓝调',7,'加拿大'); +MERGE INTO genre(g_name,rating,most_popular_in) VALUES ('流行',9,'美国'); + +MERGE INTO artist(artist_name,citizenship,gender,g_name) VALUES ('Shrikanta','印度','男性','tagore'); +MERGE INTO artist(artist_name,citizenship,gender,g_name) VALUES ('Prity','孟加拉国','女性','nazrul'); +MERGE INTO artist(artist_name,citizenship,gender,g_name) VALUES ('Farida','孟加拉国','女性','民间'); +MERGE INTO artist(artist_name,citizenship,gender,g_name) VALUES ('Topu','印度','女性','现代'); +MERGE INTO artist(artist_name,citizenship,gender,g_name) VALUES ('Enrique','美国','男性','蓝调'); +MERGE INTO artist(artist_name,citizenship,gender,g_name) VALUES ('Michel','英国','男性','流行'); + + +-------S2CompanyDemo +MERGE INTO company(company_id,company_name,headquarter_address,company_established_time,founder,ceo,annual_turnover,employee_count) VALUES ('item_enterprise_13_131','微软','西雅图','1975','盖茨','纳德拉',102300000000,210000); +MERGE INTO company(company_id,company_name,headquarter_address,company_established_time,founder,ceo,annual_turnover,employee_count) VALUES ('item_enterprise_13_132','特斯拉','加州','2003','艾伯哈德','马斯克',376800000000,140473); +MERGE INTO company(company_id,company_name,headquarter_address,company_established_time,founder,ceo,annual_turnover,employee_count) VALUES ('item_enterprise_13_133','谷歌','加州','1998','拉里佩奇','劈柴',321600000000,182503); +MERGE INTO company(company_id,company_name,headquarter_address,company_established_time,founder,ceo,annual_turnover,employee_count) VALUES ('item_enterprise_13_134','亚马逊','加州','1994','贝索斯','贝索斯',28800000000,950000); +MERGE INTO company(company_id,company_name,headquarter_address,company_established_time,founder,ceo,annual_turnover,employee_count) VALUES ('item_enterprise_13_135','英伟达','杭州','1993','黄仁勋','黄仁勋',67500000000,29000); + +MERGE INTO brand(brand_id,brand_name,brand_established_time,company_id,legal_representative,registered_capital) VALUES ('item_brand_13_131','Office','1990','item_enterprise_13_131','盖茨',50000000); +MERGE INTO brand(brand_id,brand_name,brand_established_time,company_id,legal_representative,registered_capital) VALUES ('item_brand_13_132','Windows','1991','item_enterprise_13_131','盖茨',50000000); +MERGE INTO brand(brand_id,brand_name,brand_established_time,company_id,legal_representative,registered_capital) VALUES ('item_brand_13_133','Model 3','2017','item_enterprise_13_132','马斯克',100000000); +MERGE INTO brand(brand_id,brand_name,brand_established_time,company_id,legal_representative,registered_capital) VALUES ('item_brand_13_134','Model Y','2020','item_enterprise_13_132','马斯克',100000000); +MERGE INTO brand(brand_id,brand_name,brand_established_time,company_id,legal_representative,registered_capital) VALUES ('item_brand_13_135','Google','2003','item_enterprise_13_133','拉里佩奇',50000000); +MERGE INTO brand(brand_id,brand_name,brand_established_time,company_id,legal_representative,registered_capital) VALUES ('item_brand_13_136','Android','2007','item_enterprise_13_133','拉里佩奇',50000000); +MERGE INTO brand(brand_id,brand_name,brand_established_time,company_id,legal_representative,registered_capital) VALUES ('item_brand_13_137','aws','2004','item_enterprise_13_134','贝索斯',100000000); +MERGE INTO brand(brand_id,brand_name,brand_established_time,company_id,legal_representative,registered_capital) VALUES ('item_brand_13_138','kindle','2007','item_enterprise_13_134','贝索斯',100000000); +MERGE INTO brand(brand_id,brand_name,brand_established_time,company_id,legal_representative,registered_capital) VALUES ('item_brand_13_139','H100','2022','item_enterprise_13_135','黄仁勋',100000000); +MERGE INTO brand(brand_id,brand_name,brand_established_time,company_id,legal_representative,registered_capital) VALUES ('item_brand_13_140','A100','2021','item_enterprise_13_135','黄仁勋',100000000); + +INSERT INTO brand_revenue(year_time,brand_id,revenue,profit,revenue_growth_year_on_year,profit_growth_year_on_year) VALUES ('2023','item_brand_13_131',12100000000, 2100000000,10,10); +INSERT INTO brand_revenue(year_time,brand_id,revenue,profit,revenue_growth_year_on_year,profit_growth_year_on_year) VALUES ('2023','item_brand_13_132',12200000000, 2200000000,20,20); +INSERT INTO brand_revenue(year_time,brand_id,revenue,profit,revenue_growth_year_on_year,profit_growth_year_on_year) VALUES ('2023','item_brand_13_133',12300000000, 2300000000,30,30); +INSERT INTO brand_revenue(year_time,brand_id,revenue,profit,revenue_growth_year_on_year,profit_growth_year_on_year) VALUES ('2023','item_brand_13_134',12400000000, 2400000000,10,10); +INSERT INTO brand_revenue(year_time,brand_id,revenue,profit,revenue_growth_year_on_year,profit_growth_year_on_year) VALUES ('2023','item_brand_13_135',12500000000, 2500000000,30,30); +INSERT INTO brand_revenue(year_time,brand_id,revenue,profit,revenue_growth_year_on_year,profit_growth_year_on_year) VALUES ('2023','item_brand_13_136',12600000000, 2600000000,40,40); +INSERT INTO brand_revenue(year_time,brand_id,revenue,profit,revenue_growth_year_on_year,profit_growth_year_on_year) VALUES ('2023','item_brand_13_137',12700000000, 2700000000,50,50); +INSERT INTO brand_revenue(year_time,brand_id,revenue,profit,revenue_growth_year_on_year,profit_growth_year_on_year) VALUES ('2023','item_brand_13_138',12800000000, 2800000000,20,10); +INSERT INTO brand_revenue(year_time,brand_id,revenue,profit,revenue_growth_year_on_year,profit_growth_year_on_year) VALUES ('2023','item_brand_13_139',12900000000, 2900000000,60,70); +INSERT INTO brand_revenue(year_time,brand_id,revenue,profit,revenue_growth_year_on_year,profit_growth_year_on_year) VALUES ('2023','item_brand_13_140',13000000000, 3000000000,80,100); +INSERT INTO brand_revenue(year_time,brand_id,revenue,profit,revenue_growth_year_on_year,profit_growth_year_on_year) VALUES ('2024','item_brand_13_131',13100000000,3100000000, 10,10); +INSERT INTO brand_revenue(year_time,brand_id,revenue,profit,revenue_growth_year_on_year,profit_growth_year_on_year) VALUES ('2024','item_brand_13_132',13200000000, 3200000000,20,20); +INSERT INTO brand_revenue(year_time,brand_id,revenue,profit,revenue_growth_year_on_year,profit_growth_year_on_year) VALUES ('2024','item_brand_13_133',13300000000, 3300000000,30,30); +INSERT INTO brand_revenue(year_time,brand_id,revenue,profit,revenue_growth_year_on_year,profit_growth_year_on_year) VALUES ('2024','item_brand_13_134',13400000000, 3400000000,10,10); +INSERT INTO brand_revenue(year_time,brand_id,revenue,profit,revenue_growth_year_on_year,profit_growth_year_on_year) VALUES ('2024','item_brand_13_135',13500000000, 3500000000,30,30); +INSERT INTO brand_revenue(year_time,brand_id,revenue,profit,revenue_growth_year_on_year,profit_growth_year_on_year) VALUES ('2024','item_brand_13_136',13600000000, 3600000000,40,40); +INSERT INTO brand_revenue(year_time,brand_id,revenue,profit,revenue_growth_year_on_year,profit_growth_year_on_year) VALUES ('2024','item_brand_13_137',13700000000, 3700000000,50,50); +INSERT INTO brand_revenue(year_time,brand_id,revenue,profit,revenue_growth_year_on_year,profit_growth_year_on_year) VALUES ('2024','item_brand_13_138',13800000000, 3800000000,20,10); +INSERT INTO brand_revenue(year_time,brand_id,revenue,profit,revenue_growth_year_on_year,profit_growth_year_on_year) VALUES ('2024','item_brand_13_139',13900000000, 3900000000,60,70); +INSERT INTO brand_revenue(year_time,brand_id,revenue,profit,revenue_growth_year_on_year,profit_growth_year_on_year) VALUES ('2024','item_brand_13_140',14000000000, 4000000000,80,100); diff --git a/launchers/standalone/src/test/resources/db/data-h2.sql b/launchers/standalone/src/test/resources/db/data-h2.sql index 75b45404b..fd364a8c4 100644 --- a/launchers/standalone/src/test/resources/db/data-h2.sql +++ b/launchers/standalone/src/test/resources/db/data-h2.sql @@ -1,4 +1,9 @@ -- sample user +MERGE INTO s2_user (id, `name`, password, salt, display_name, email, is_admin) values (1, 'admin','c3VwZXJzb25pY0BiaWNvbTD12g9wGXESwL7+o7xUW90=','jGl25bVBBBW96Qi9Te4V3w==','admin','admin@xx.com', 1); +MERGE INTO s2_user (id, `name`, password, display_name, email) values (2, 'jack','123456','jack','jack@xx.com'); +MERGE INTO s2_user (id, `name`, password, display_name, email) values (3, 'tom','123456','tom','tom@xx.com'); +MERGE INTO s2_user (id, `name`, password, display_name, email, is_admin) values (4, 'lucy','123456','lucy','lucy@xx.com', 1); +MERGE INTO s2_user (id, `name`, password, display_name, email) values (5, 'alice','123456','alice','alice@xx.com'); ---The default value for the password is 123456 MERGE INTO s2_user (id, `name`, password, salt, display_name, email, is_admin) values (1, 'admin','c3VwZXJzb25pY0BiaWNvbdktJJYWw6A3rEmBUPzbn/6DNeYnD+y3mAwDKEMS3KVT','jGl25bVBBBW96Qi9Te4V3w==','admin','admin@xx.com', 1); MERGE INTO s2_user (id, `name`, password, salt, display_name, email) values (2, 'jack','c3VwZXJzb25pY0BiaWNvbWxGalmwa0h/trkh/3CWOYMDiku0Op1VmOfESIKmN0HG','MWERWefm/3hD6kYndF6JIg==','jack','jack@xx.com'); @@ -14,1096 +19,4 @@ MERGE INTO s2_available_date_info(`id`,`item_id` ,`type` ,`date_format` ,`sta values (3 , 3, 'dimension', 'yyyy-MM-dd', DATEADD('DAY', -28, CURRENT_DATE()), DATEADD('DAY', -1, CURRENT_DATE()), '[]', '2023-06-01', 'admin', '2023-06-01', 'admin'); MERGE INTO s2_canvas(`id`, `domain_id`, `type`, `config` ,`created_at` ,`created_by` ,`updated_at` ,`updated_by` ) -values (1, 1, 'modelEdgeRelation', '[{"source":"datasource-1","target":"datasource-3","type":"polyline","id":"edge-0.305251275235679741702883718912","style":{"active":{"stroke":"rgb(95, 149, 255)","lineWidth":1},"selected":{"stroke":"rgb(95, 149, 255)","lineWidth":2,"shadowColor":"rgb(95, 149, 255)","shadowBlur":10,"text-shape":{"fontWeight":500}},"highlight":{"stroke":"rgb(95, 149, 255)","lineWidth":2,"text-shape":{"fontWeight":500}},"inactive":{"stroke":"rgb(234, 234, 234)","lineWidth":1},"disable":{"stroke":"rgb(245, 245, 245)","lineWidth":1},"stroke":"#296df3","endArrow":true},"startPoint":{"x":-94,"y":-137.5,"anchorIndex":0,"id":"-94|||-137.5"},"endPoint":{"x":-234,"y":-45,"anchorIndex":1,"id":"-234|||-45"},"sourceAnchor":2,"targetAnchor":1,"label":"模型关系编辑"},{"source":"datasource-1","target":"datasource-2","type":"polyline","id":"edge-0.466237264629309141702883756359","style":{"active":{"stroke":"rgb(95, 149, 255)","lineWidth":1},"selected":{"stroke":"rgb(95, 149, 255)","lineWidth":2,"shadowColor":"rgb(95, 149, 255)","shadowBlur":10,"text-shape":{"fontWeight":500}},"highlight":{"stroke":"rgb(95, 149, 255)","lineWidth":2,"text-shape":{"fontWeight":500}},"inactive":{"stroke":"rgb(234, 234, 234)","lineWidth":1},"disable":{"stroke":"rgb(245, 245, 245)","lineWidth":1},"stroke":"#296df3","endArrow":true},"startPoint":{"x":-12,"y":-137.5,"anchorIndex":1,"id":"-12|||-137.5"},"endPoint":{"x":85,"y":31.5,"anchorIndex":0,"id":"85|||31.5"},"sourceAnchor":1,"targetAnchor":2,"label":"模型关系编辑"}]', '2023-06-01', 'admin', '2023-06-01', 'admin'); - --- sample data -MERGE INTO singer (singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES ('周杰伦', '港台','青花瓷','国风',1000000,1000000,1000000); -MERGE INTO singer (singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES ('陈奕迅', '港台','爱情转移','流行',1000000,1000000,1000000); -MERGE INTO singer (singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES ('林俊杰', '港台','美人鱼','流行',1000000,1000000,1000000); -MERGE INTO singer (singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES ('张碧晨', '内地','光的方向','流行',1000000,1000000,1000000); -MERGE INTO singer (singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES ('程响', '内地','人间烟火','国风',1000000,1000000,1000000); -MERGE INTO singer (singer_name,act_area, song_name,genre,js_play_cnt,down_cnt,favor_cnt) VALUES ('Taylor Swift', '欧美','Love Story','流行',1000000,1000000,1000000); - ----demo data for semantic and chat -MERGE INTO s2_user_department (user_name, department) values ('jack','HR'); - -MERGE INTO s2_user_department (user_name, department) values ('jack','HR'); -MERGE INTO s2_user_department (user_name, department) values ('tom','sales'); -MERGE INTO s2_user_department (user_name, department) values ('lucy','marketing'); -MERGE INTO s2_user_department (user_name, department) values ('john','strategy'); -MERGE INTO s2_user_department (user_name, department) values ('alice','sales'); -MERGE INTO s2_user_department (user_name, department) values ('dean','marketing'); - -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (CURRENT_DATE(), 'lucy', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (CURRENT_DATE(), 'jack', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (CURRENT_DATE(), 'lucy', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (CURRENT_DATE(), 'tom', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (CURRENT_DATE(), 'john', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (CURRENT_DATE(), 'alice', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (CURRENT_DATE(), 'dean', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (CURRENT_DATE(), 'john', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (CURRENT_DATE(), 'tom', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (CURRENT_DATE(), 'lucy', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (CURRENT_DATE(), 'dean', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -5, CURRENT_DATE()), 'lucy', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'jack', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'lucy', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'tom', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'john', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -6, CURRENT_DATE()), 'alice', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -7, CURRENT_DATE()), 'dean', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'john', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'tom', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'lucy', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'dean', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'dean', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'jack', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'john', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'lucy', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'dean', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'dean', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'john', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'john', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'alice', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'lucy', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -17, CURRENT_DATE()), 'lucy', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -18, CURRENT_DATE()), 'tom', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -6, CURRENT_DATE()), 'lucy', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -19, CURRENT_DATE()), 'alice', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'john', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'lucy', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'alice', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'john', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -19, CURRENT_DATE()), 'dean', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'jack', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'dean', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -19, CURRENT_DATE()), 'lucy', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'jack', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -22, CURRENT_DATE()), 'john', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'tom', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'john', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'lucy', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'alice', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'tom', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'jack', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'alice', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'lucy', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'john', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'john', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'dean', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'tom', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'jack', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'lucy', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'jack', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -6, CURRENT_DATE()), 'jack', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'john', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -18, CURRENT_DATE()), 'jack', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'john', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'alice', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'jack', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'lucy', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'lucy', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'john', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'alice', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'john', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'john', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -27, CURRENT_DATE()), 'john', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -27, CURRENT_DATE()), 'lucy', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'alice', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'alice', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -28, CURRENT_DATE()), 'alice', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'tom', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'john', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -19, CURRENT_DATE()), 'jack', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'john', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -7, CURRENT_DATE()), 'jack', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -18, CURRENT_DATE()), 'tom', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'dean', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -17, CURRENT_DATE()), 'jack', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -27, CURRENT_DATE()), 'lucy', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'john', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'jack', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'alice', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -19, CURRENT_DATE()), 'lucy', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'alice', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'dean', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'jack', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -18, CURRENT_DATE()), 'john', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -22, CURRENT_DATE()), 'dean', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'john', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'lucy', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'lucy', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -22, CURRENT_DATE()), 'john', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'jack', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'lucy', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'alice', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'john', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'tom', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'tom', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'dean', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'dean', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'tom', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'john', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'john', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'tom', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'dean', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'alice', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'dean', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'dean', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'john', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'tom', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'john', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'alice', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'lucy', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'jack', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'tom', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'jack', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'jack', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'john', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'john', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'jack', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -27, CURRENT_DATE()), 'lucy', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'jack', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'alice', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'dean', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'lucy', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -6, CURRENT_DATE()), 'tom', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'dean', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'dean', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -28, CURRENT_DATE()), 'dean', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'dean', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -18, CURRENT_DATE()), 'jack', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'dean', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'jack', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'john', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -19, CURRENT_DATE()), 'alice', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -7, CURRENT_DATE()), 'john', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'tom', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'john', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'dean', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'john', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'dean', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'alice', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'john', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'lucy', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'john', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'jack', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'lucy', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'john', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'john', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -18, CURRENT_DATE()), 'john', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'alice', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -27, CURRENT_DATE()), 'dean', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'lucy', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'dean', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'dean', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -22, CURRENT_DATE()), 'john', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'lucy', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -17, CURRENT_DATE()), 'john', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'dean', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'tom', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'jack', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -7, CURRENT_DATE()), 'tom', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'john', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'tom', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'tom', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -19, CURRENT_DATE()), 'john', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'john', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'john', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'john', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -6, CURRENT_DATE()), 'dean', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'john', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'alice', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'john', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'alice', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'john', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'john', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'alice', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -17, CURRENT_DATE()), 'alice', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'tom', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'jack', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'john', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -17, CURRENT_DATE()), 'john', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'tom', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'alice', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -18, CURRENT_DATE()), 'alice', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -17, CURRENT_DATE()), 'john', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'jack', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'alice', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'jack', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'lucy', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'john', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -7, CURRENT_DATE()), 'jack', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'tom', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'dean', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'john', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'alice', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'lucy', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'dean', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -27, CURRENT_DATE()), 'dean', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'dean', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -28, CURRENT_DATE()), 'dean', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'alice', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -18, CURRENT_DATE()), 'dean', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'lucy', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'dean', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'dean', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'jack', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'lucy', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'jack', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'alice', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -6, CURRENT_DATE()), 'dean', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -7, CURRENT_DATE()), 'john', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'dean', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'john', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'john', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'jack', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'dean', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'tom', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'john', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -6, CURRENT_DATE()), 'lucy', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'dean', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -17, CURRENT_DATE()), 'dean', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -18, CURRENT_DATE()), 'tom', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'jack', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'jack', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'john', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'jack', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'lucy', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'john', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'alice', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'lucy', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'alice', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'alice', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'jack', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'tom', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'lucy', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'alice', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'lucy', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'jack', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'dean', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -19, CURRENT_DATE()), 'alice', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -17, CURRENT_DATE()), 'lucy', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'jack', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'tom', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -28, CURRENT_DATE()), 'tom', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'dean', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'dean', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'tom', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'dean', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'dean', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'alice', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'alice', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'tom', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -6, CURRENT_DATE()), 'dean', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -28, CURRENT_DATE()), 'john', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'tom', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'tom', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'dean', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'john', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'lucy', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'dean', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'lucy', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'john', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -27, CURRENT_DATE()), 'lucy', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'john', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'dean', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'dean', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'dean', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'tom', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'lucy', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'jack', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'dean', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'alice', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'jack', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'tom', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'jack', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'dean', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -19, CURRENT_DATE()), 'lucy', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'john', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -7, CURRENT_DATE()), 'tom', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'dean', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'alice', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'tom', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -17, CURRENT_DATE()), 'john', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'tom', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'lucy', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'jack', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'alice', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'tom', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -22, CURRENT_DATE()), 'alice', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -19, CURRENT_DATE()), 'tom', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'dean', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'dean', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -27, CURRENT_DATE()), 'john', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'alice', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -28, CURRENT_DATE()), 'alice', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'lucy', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -22, CURRENT_DATE()), 'john', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -7, CURRENT_DATE()), 'alice', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'tom', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -18, CURRENT_DATE()), 'jack', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'lucy', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'jack', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'alice', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'jack', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'john', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -6, CURRENT_DATE()), 'jack', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'dean', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'jack', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'lucy', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'jack', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -19, CURRENT_DATE()), 'dean', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'tom', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'jack', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'dean', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'alice', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'jack', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'john', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -22, CURRENT_DATE()), 'jack', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'dean', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'john', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'alice', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'jack', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'lucy', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'dean', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -22, CURRENT_DATE()), 'john', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'jack', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'jack', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'jack', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -17, CURRENT_DATE()), 'tom', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'jack', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'john', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'dean', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -27, CURRENT_DATE()), 'tom', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -18, CURRENT_DATE()), 'tom', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'alice', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'tom', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'john', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'john', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -28, CURRENT_DATE()), 'tom', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'alice', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'lucy', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'lucy', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'john', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'alice', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'alice', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'jack', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'alice', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'john', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'jack', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'john', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'jack', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'dean', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'dean', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'tom', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'tom', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'dean', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'jack', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'jack', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'alice', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -7, CURRENT_DATE()), 'tom', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'tom', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -28, CURRENT_DATE()), 'alice', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'alice', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'john', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -17, CURRENT_DATE()), 'alice', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'lucy', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'jack', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'alice', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'alice', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -7, CURRENT_DATE()), 'alice', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'lucy', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -6, CURRENT_DATE()), 'tom', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'jack', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'jack', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -6, CURRENT_DATE()), 'tom', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'dean', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'tom', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'dean', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'tom', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'tom', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'john', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'jack', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'dean', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -19, CURRENT_DATE()), 'alice', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'john', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'tom', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'dean', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -19, CURRENT_DATE()), 'alice', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'tom', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -18, CURRENT_DATE()), 'tom', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -6, CURRENT_DATE()), 'alice', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'john', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'dean', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'lucy', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'jack', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'lucy', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'alice', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'tom', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'tom', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'john', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -6, CURRENT_DATE()), 'jack', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -6, CURRENT_DATE()), 'dean', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'alice', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'lucy', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'john', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'jack', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'lucy', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'alice', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -18, CURRENT_DATE()), 'tom', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'jack', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'dean', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -27, CURRENT_DATE()), 'tom', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'tom', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'lucy', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'dean', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -22, CURRENT_DATE()), 'john', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'alice', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'jack', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'dean', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'dean', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'lucy', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -19, CURRENT_DATE()), 'jack', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'alice', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'dean', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'dean', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -28, CURRENT_DATE()), 'dean', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'lucy', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'tom', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'dean', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'john', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'jack', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'dean', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'jack', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -28, CURRENT_DATE()), 'tom', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'dean', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'lucy', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'jack', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'john', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'alice', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'jack', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'lucy', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'alice', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'tom', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'alice', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -17, CURRENT_DATE()), 'tom', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'dean', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -7, CURRENT_DATE()), 'john', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -17, CURRENT_DATE()), 'lucy', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'john', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'jack', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -28, CURRENT_DATE()), 'tom', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'lucy', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'lucy', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -27, CURRENT_DATE()), 'tom', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -17, CURRENT_DATE()), 'lucy', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'alice', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'john', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'dean', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -22, CURRENT_DATE()), 'dean', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'lucy', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'lucy', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'alice', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'alice', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'alice', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -19, CURRENT_DATE()), 'lucy', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'tom', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'dean', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'john', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'john', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'tom', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -28, CURRENT_DATE()), 'tom', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -18, CURRENT_DATE()), 'dean', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'john', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'dean', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -27, CURRENT_DATE()), 'alice', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'john', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'tom', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -27, CURRENT_DATE()), 'john', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'dean', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'john', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -18, CURRENT_DATE()), 'lucy', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'tom', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'alice', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -27, CURRENT_DATE()), 'dean', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'alice', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'jack', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -22, CURRENT_DATE()), 'jack', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'john', 'p2'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'tom', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'lucy', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -28, CURRENT_DATE()), 'tom', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'dean', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'lucy', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'jack', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -18, CURRENT_DATE()), 'lucy', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'alice', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'john', 'p1'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'alice', 'p3'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'alice', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'tom', 'p4'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'dean', 'p5'); -INSERT INTO s2_pv_uv_statis (imp_date, user_name, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'tom', 'p4'); - - - - - -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'jack', '0.7636857512911863', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'dean', '0.17663327393462436', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'alice', '0.38943688941552057', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'lucy', '0.2715819955225307', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'tom', '0.9358210273119568', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'alice', '0.9364586435510802', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'jack', '0.9707723036513162', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'tom', '0.8497763866782723', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'alice', '0.15504417761372413', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'jack', '0.9507563118298399', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'alice', '0.9746364180572994', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'dean', '0.12869214941133378', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'lucy', '0.3024970533288409', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'tom', '0.6639702099980812', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'lucy', '0.4929901454858626', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'lucy', '0.06853040276026445', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'tom', '0.8488086078299616', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'lucy', '0.8589111177125592', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'alice', '0.5576357066482228', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -7, CURRENT_DATE()), 'john', '0.8047888670006846', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'john', '0.766944548494366', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'lucy', '0.5280072184505449', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'tom', '0.9693343356046343', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'dean', '0.12805203958456424', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -22, CURRENT_DATE()), 'dean', '0.16963603387027637', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'alice', '0.5901202956521101', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'jack', '0.12710364646712236', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'tom', '0.6346530909156196', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'dean', '0.12461289103639872', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'john', '0.9863947334662437', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'alice', '0.48899961064192987', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -27, CURRENT_DATE()), 'alice', '0.5382796792688207', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'dean', '0.3506568687014143', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'jack', '0.8633072449771709', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'tom', '0.13999135315363687', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'john', '0.07258740493845894', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'jack', '0.5244413940436958', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'john', '0.13258670732966138', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -19, CURRENT_DATE()), 'john', '0.6015982054464575', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'lucy', '0.05513158944480323', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'alice', '0.6707121735296985', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -18, CURRENT_DATE()), 'jack', '0.9330440339006469', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'dean', '0.5630674323371607', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -27, CURRENT_DATE()), 'dean', '0.8720647566229917', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'john', '0.8331899070546519', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -6, CURRENT_DATE()), 'alice', '0.6712876436249856', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'alice', '0.6694409980332703', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -27, CURRENT_DATE()), 'john', '0.3703307480606334', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'dean', '0.775368688472696', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'lucy', '0.9151205443267096', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'tom', '0.09543108823305857', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'dean', '0.7893992120771057', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'lucy', '0.5119923080070498', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'lucy', '0.49906724167974936', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -7, CURRENT_DATE()), 'tom', '0.046258282700961884', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -7, CURRENT_DATE()), 'dean', '0.44843595680103954', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'alice', '0.7743935471689718', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'john', '0.5855299615656824', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'lucy', '0.9412963512379853', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'jack', '0.8383247587082538', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'lucy', '0.14517876867236124', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'john', '0.9327229861441061', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'john', '0.19042326582894153', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'jack', '0.6029067818254513', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'jack', '0.21715964747214422', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -18, CURRENT_DATE()), 'lucy', '0.34259842721045974', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -28, CURRENT_DATE()), 'john', '0.7064419016593382', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'lucy', '0.5725636566517865', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -17, CURRENT_DATE()), 'john', '0.22332539583809208', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'jack', '0.8049036189055911', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'alice', '0.6029674758974956', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'lucy', '0.11884976360561716', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -28, CURRENT_DATE()), 'alice', '0.7124916829130662', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'jack', '0.5893693718556829', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'alice', '0.602073304496253', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'tom', '0.10491061160039927', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'dean', '0.9006548872378379', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'alice', '0.8545144244288455', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -18, CURRENT_DATE()), 'jack', '0.16915384987875726', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'dean', '0.2271640700690446', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'alice', '0.7807518577160636', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'john', '0.8919859648888653', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'dean', '0.1564450687270359', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'jack', '0.5840549187653847', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'tom', '0.2213255596777869', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'tom', '0.07868261880306426', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'jack', '0.07710010861455818', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'jack', '0.5131249730162654', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'jack', '0.5035035055368601', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'tom', '0.8996978291173905', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'john', '0.057442290722216294', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'jack', '0.6443079066865616', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'lucy', '0.7398098480748726', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -27, CURRENT_DATE()), 'dean', '0.9835694815034591', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'john', '0.9879213445635557', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'jack', '0.4020136688147111', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'lucy', '0.6698797170128024', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'john', '0.17325132416789113', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'lucy', '0.5784229486763606', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'tom', '0.9185978183932058', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'jack', '0.5474783153973963', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'alice', '0.9730731954700215', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'tom', '0.5390873359288765', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'alice', '0.20522241320887713', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'alice', '0.4088233242325021', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'jack', '0.7608047695853417', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'tom', '0.2749731221085713', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'john', '0.06154055374702494', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'dean', '0.460668002022406', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'alice', '0.4474746325306228', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'alice', '0.5761666885467472', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -7, CURRENT_DATE()), 'dean', '0.33233441360339655', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'alice', '0.7426534909874778', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -6, CURRENT_DATE()), 'tom', '0.5841437875889118', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'alice', '0.2818296500094526', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -17, CURRENT_DATE()), 'tom', '0.8670888843915217', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'alice', '0.5249294365740248', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'jack', '0.5483356748008438', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'dean', '0.7278566847412673', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'jack', '0.6779976902157362', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'lucy', '0.09995341651736978', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'jack', '0.4528538159233879', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'alice', '0.5870756885301056', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'tom', '0.9842091927290255', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'tom', '0.04580936015706816', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'alice', '0.8814678270145769', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -27, CURRENT_DATE()), 'john', '0.06517379256096412', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'alice', '0.8769832364187129', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'dean', '0.584562279025023', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -22, CURRENT_DATE()), 'john', '0.8102404090621375', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'john', '0.11481653429176686', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'jack', '0.43422888918962554', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -22, CURRENT_DATE()), 'lucy', '0.0684414272594508', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'alice', '0.976546463969412', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'dean', '0.617906858141431', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -27, CURRENT_DATE()), 'jack', '0.08663740247579998', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'lucy', '0.7124944606691416', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'alice', '0.1321700521239627', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -19, CURRENT_DATE()), 'jack', '0.3078946609431664', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'alice', '0.6149442855237194', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -7, CURRENT_DATE()), 'alice', '0.5963801306980994', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'lucy', '0.6999542038973406', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -19, CURRENT_DATE()), 'john', '0.4599112653446624', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'dean', '0.20300901401048832', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'john', '0.39989705958717037', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'jack', '0.2486378364940327', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'john', '0.16880398079144077', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'tom', '0.73927288385526', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -22, CURRENT_DATE()), 'john', '0.8645283506689198', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'alice', '0.3266940826759587', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -7, CURRENT_DATE()), 'tom', '0.9195490073037541', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'lucy', '0.9452523036658287', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'john', '0.21269683438120535', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'dean', '0.7377502855387184', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -27, CURRENT_DATE()), 'tom', '0.38981597634408716', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'john', '0.7001799391999863', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'john', '0.6616720024008785', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -19, CURRENT_DATE()), 'dean', '0.497721735058096', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -17, CURRENT_DATE()), 'jack', '0.22255613760959603', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -22, CURRENT_DATE()), 'jack', '0.05247640233319417', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'dean', '0.27237572107833363', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'alice', '0.9529452406380252', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'alice', '0.28243045060463157', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'lucy', '0.17880444250082506', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'john', '0.035050038002381156', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'lucy', '0.840803223728221', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'jack', '0.5318457377361356', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'tom', '0.9280332892460665', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'lucy', '0.752354382202208', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'dean', '0.1866528331789219', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -17, CURRENT_DATE()), 'alice', '0.7016165545791373', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'john', '0.4191547989960899', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'john', '0.7025516699007639', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'john', '0.6160127317884274', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'alice', '0.91223094958137', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'tom', '0.4383056089013998', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -18, CURRENT_DATE()), 'jack', '0.595750781166582', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -28, CURRENT_DATE()), 'lucy', '0.9472349338730268', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -6, CURRENT_DATE()), 'jack', '0.0519104588842193', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'alice', '0.48043983034526205', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'lucy', '0.14754707786497478', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'alice', '0.36124288370035695', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'dean', '0.21777919493494613', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'lucy', '0.22637666702475057', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'john', '0.9378215576942598', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'john', '0.3309229261144562', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'alice', '0.7602880453727515', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'alice', '0.9470462487873785', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'dean', '0.6770215935547629', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -22, CURRENT_DATE()), 'john', '0.1586074803669385', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -28, CURRENT_DATE()), 'lucy', '0.2754855564794071', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'tom', '0.8355347738454384', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'alice', '0.7251813505573811', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'jack', '0.006606625589642534', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -19, CURRENT_DATE()), 'alice', '0.304832277753024', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'jack', '0.026368662837989554', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -6, CURRENT_DATE()), 'tom', '0.6855977520602776', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -22, CURRENT_DATE()), 'tom', '0.8193746826441749', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'john', '0.021179295102459972', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'jack', '0.1533849522536005', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'alice', '0.18893553542301778', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'john', '0.39870999343833624', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'john', '0.9985665103520182', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'john', '0.6961441157700171', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'tom', '0.9861933923851885', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'tom', '0.993076500099477', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'alice', '0.4320547269058953', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'lucy', '0.18441071030375877', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'jack', '0.1501504986117118', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -27, CURRENT_DATE()), 'tom', '0.252021845734527', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -17, CURRENT_DATE()), 'lucy', '0.24442701577183745', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'tom', '0.07563738855797564', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'john', '0.34247820646440985', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'john', '0.9456979276862031', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'alice', '0.19494357263973816', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'alice', '0.9371493867882469', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -7, CURRENT_DATE()), 'john', '0.6136241316589367', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -22, CURRENT_DATE()), 'alice', '0.8922330760877784', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -22, CURRENT_DATE()), 'dean', '0.9001986074661864', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'tom', '0.4889702884422866', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'tom', '0.2689551234431401', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'dean', '0.5223573993758465', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'tom', '0.05042295556527243', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'tom', '0.2717147121880483', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'john', '0.7397093309370814', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'dean', '0.157064341631733', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'lucy', '0.7213399784998017', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'tom', '0.764081440588005', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'john', '0.7514070600074144', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -28, CURRENT_DATE()), 'john', '0.611647412825278', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'tom', '0.6600796877195596', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'john', '0.8942204153751679', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'dean', '0.07398121085929721', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -28, CURRENT_DATE()), 'dean', '0.1652506990439564', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'dean', '0.5849759516111703', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -27, CURRENT_DATE()), 'tom', '0.1672502732600889', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'tom', '0.7836135556233219', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'dean', '0.26181269644936356', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'alice', '0.6577275876355586', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -19, CURRENT_DATE()), 'tom', '0.3067293364197956', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'alice', '0.8608288543866495', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -28, CURRENT_DATE()), 'john', '0.814283434116926', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -28, CURRENT_DATE()), 'jack', '0.33993584425872936', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -6, CURRENT_DATE()), 'john', '0.010812798859160089', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'dean', '0.5156558224263926', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -17, CURRENT_DATE()), 'jack', '0.46320035330198406', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'lucy', '0.2651020283994786', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'john', '0.42467241545664147', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'tom', '0.3695905136678498', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'tom', '0.15269122123348644', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'jack', '0.6755688670583248', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -28, CURRENT_DATE()), 'jack', '0.39064306179528907', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'john', '0.36479296691952023', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -6, CURRENT_DATE()), 'lucy', '0.5069249157662691', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'tom', '0.4785315495532231', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -6, CURRENT_DATE()), 'dean', '0.7582526218052175', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'dean', '0.42064109605717914', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'dean', '0.5587757581237022', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'lucy', '0.3561686564964428', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'tom', '0.7101688305173135', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'dean', '0.6518061375522985', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'tom', '0.7564485884156583', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'tom', '0.36531347293134464', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'jack', '0.5201689359070235', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'john', '0.7138792929290383', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'tom', '0.9751003716333827', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'tom', '0.5281906318027629', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'tom', '0.6291356541485003', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'jack', '0.1938712974807698', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'john', '0.6267850210775459', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'tom', '0.4469970592043767', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'lucy', '0.7690659124175409', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -27, CURRENT_DATE()), 'jack', '0.13335067838090386', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -27, CURRENT_DATE()), 'jack', '0.2966621725922035', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -19, CURRENT_DATE()), 'john', '0.5740481445089863', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'alice', '0.838028890036331', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'jack', '0.8094354537628714', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'alice', '0.5552924586108698', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'jack', '0.49150373927678315', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'dean', '0.7264346889377966', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'alice', '0.9292830287297702', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'dean', '0.3905616258240767', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'dean', '0.15912349648571666', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'alice', '0.6030082006630102', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'lucy', '0.8712354035243679', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'dean', '0.7685306377211826', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'john', '0.2869913942171415', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'john', '0.7142615166855639', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'tom', '0.5625978475154423', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'jack', '0.13611601734791123', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'alice', '0.6977333962685311', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'jack', '0.35140477709778295', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -28, CURRENT_DATE()), 'john', '0.8805119222967716', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'john', '0.7014124236538637', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -22, CURRENT_DATE()), 'alice', '0.12759538003439375', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'john', '0.7515403792213445', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'lucy', '0.03700239289885987', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'tom', '0.31674618364630946', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'dean', '0.4491378834800146', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'tom', '0.6742764131652571', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -7, CURRENT_DATE()), 'lucy', '0.5286362221140248', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'alice', '0.007890326473113496', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'alice', '0.8046560540950831', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'tom', '0.7198364371127147', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'tom', '0.7400546712169153', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'jack', '0.16859870460868698', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'lucy', '0.8462852684569557', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'john', '0.010211452005474353', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'alice', '0.8617802368201087', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'jack', '0.21667479046797633', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'john', '0.8667689615468714', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'jack', '0.16140709875863557', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'dean', '0.16713368182304666', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -7, CURRENT_DATE()), 'lucy', '0.8957484629768053', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'tom', '0.457835758220534', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -22, CURRENT_DATE()), 'jack', '0.9435170960198477', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'jack', '0.9699253608913104', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -28, CURRENT_DATE()), 'john', '0.2309897429566834', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'lucy', '0.7879705066452681', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'john', '0.20795869239817255', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -6, CURRENT_DATE()), 'dean', '0.4110352469382019', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'jack', '0.4979592772533561', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'dean', '0.18810865430947044', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'tom', '0.5001240246982048', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'jack', '0.08341934160029707', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'lucy', '0.04812784841651041', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'alice', '0.4655982693269717', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'dean', '0.8539357978460663', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'john', '0.9649541785823592', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'john', '0.8243635648047365', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -7, CURRENT_DATE()), 'john', '0.929949719929735', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'john', '0.055983276861168996', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'tom', '0.07845430274829746', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'alice', '0.28257674222099116', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'dean', '0.1578419214960578', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'dean', '0.7853118484860825', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'lucy', '0.20790127125904156', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'tom', '0.8650538395535204', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'dean', '0.902116091225815', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -19, CURRENT_DATE()), 'lucy', '0.48542770770171373', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'jack', '0.16725337150113984', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -7, CURRENT_DATE()), 'lucy', '0.3157444453259486', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -7, CURRENT_DATE()), 'tom', '0.565727220131555', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'jack', '0.2531688065358064', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'lucy', '0.9191434620980499', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'jack', '0.9224628853942058', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'jack', '0.3256288410730337', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'jack', '0.9709152566761661', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'dean', '0.9794173893522709', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'alice', '0.16582064407977237', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -17, CURRENT_DATE()), 'alice', '0.2652519246960059', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'alice', '0.04092489871261762', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -22, CURRENT_DATE()), 'jack', '0.3020444893927522', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'john', '0.4655412764350543', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -28, CURRENT_DATE()), 'dean', '0.9226436424888846', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -22, CURRENT_DATE()), 'jack', '0.4707663393012884', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'lucy', '0.3277970119243966', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'tom', '0.4730675479071551', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'jack', '0.10261940477901954', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -17, CURRENT_DATE()), 'alice', '0.4148892373198616', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'john', '0.2877219827348403', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -19, CURRENT_DATE()), 'tom', '0.16212409974675845', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'tom', '0.9567425121214822', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -22, CURRENT_DATE()), 'lucy', '0.19795350030679149', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'john', '0.6954199597749198', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -22, CURRENT_DATE()), 'alice', '0.32884293488801164', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -27, CURRENT_DATE()), 'john', '0.4789917995407148', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -18, CURRENT_DATE()), 'lucy', '0.0698927593996298', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'john', '0.3352267723792438', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'tom', '0.8085116661598726', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'john', '0.17515060210353794', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'dean', '0.6006963088370202', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'alice', '0.8794167536704468', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'dean', '0.04091469320757368', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -17, CURRENT_DATE()), 'tom', '0.6709116812690366', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'john', '0.4850646101328463', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -7, CURRENT_DATE()), 'tom', '0.547488212623346', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'dean', '0.6301717145008927', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'lucy', '0.06123370093612068', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'alice', '0.2545600223228257', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'john', '0.28355287519210803', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'dean', '0.3231348374147818', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'tom', '0.4585172495754063', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'john', '0.7893945285152268', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -22, CURRENT_DATE()), 'john', '0.6810596014794181', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'john', '0.7136031244915907', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'jack', '0.259734039051829', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'jack', '0.7759518703827996', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -19, CURRENT_DATE()), 'john', '0.06288891046833589', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'dean', '0.8242980461154241', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'tom', '0.36590300307021595', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'lucy', '0.20254092528445444', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'tom', '0.5427356081880325', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'dean', '0.1467846603517391', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'john', '0.8975527268892767', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'dean', '0.3483541520806722', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'alice', '0.6922544855316723', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'tom', '0.3690185253006011', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'tom', '0.7564541265683148', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -18, CURRENT_DATE()), 'tom', '0.3634152133342695', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'tom', '0.33740378933701987', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'lucy', '0.7942640738315301', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'jack', '0.7894896778233523', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -22, CURRENT_DATE()), 'jack', '0.7153281477198108', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -22, CURRENT_DATE()), 'tom', '0.5546359859065261', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'john', '0.7727157385809087', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'dean', '0.8707097754747494', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'john', '0.3873936520764878', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'alice', '0.7590305068820566', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'john', '0.512826935863365', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'john', '0.19120284727846926', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -6, CURRENT_DATE()), 'dean', '0.5382693105670825', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'john', '0.826241649014955', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'lucy', '0.6133080470571559', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'jack', '0.6452862617544055', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'lucy', '0.3025772179023586', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'lucy', '4.709864550322962E-4', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'dean', '0.024816355013726588', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -6, CURRENT_DATE()), 'alice', '0.8407500495605565', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'alice', '0.8420879584266481', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'lucy', '0.2719224735814776', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'tom', '0.8939712577294938', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'dean', '0.8086189323362379', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'tom', '0.6063415085381448', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'tom', '0.39783242658234674', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -19, CURRENT_DATE()), 'tom', '0.6085577206028068', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'tom', '0.5154289424127074', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'john', '0.878436600887031', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'john', '0.5577906295015223', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -27, CURRENT_DATE()), 'lucy', '0.1143260282925247', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'jack', '0.312756557275364', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'john', '0.05548807854726956', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'tom', '0.12140791431139175', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'dean', '0.23897628700410234', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'lucy', '0.22223137342481392', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'john', '0.12379891645900953', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'john', '0.33729146112854247', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'dean', '0.8816768640060831', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -21, CURRENT_DATE()), 'jack', '0.6301700633426532', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -3, CURRENT_DATE()), 'alice', '0.4566295223861714', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'john', '0.1777378523933678', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -27, CURRENT_DATE()), 'tom', '0.8163769471165477', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'tom', '0.4380805149704541', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'alice', '0.2987018822475964', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'dean', '0.6726495645391617', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'alice', '0.8394327461109705', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -18, CURRENT_DATE()), 'dean', '0.820512945501936', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'tom', '0.1580105370757261', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -20, CURRENT_DATE()), 'jack', '0.9961450897279505', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -7, CURRENT_DATE()), 'john', '0.6574891890500061', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'john', '0.5201205570085158', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'alice', '0.2445069633928285', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -17, CURRENT_DATE()), 'john', '0.3155229654901067', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'jack', '0.3665971881269575', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'john', '0.5544977915912215', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'tom', '0.15978771803015113', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'lucy', '0.038128748344929186', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -19, CURRENT_DATE()), 'tom', '0.49026304025118594', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'dean', '0.5166802080526571', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'alice', '0.22568230066042194', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -28, CURRENT_DATE()), 'john', '0.9888634109849955', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'jack', '0.21022365182102054', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -18, CURRENT_DATE()), 'john', '0.47052993358031114', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'dean', '0.25686122383263454', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'tom', '0.18929054223320718', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'jack', '0.7925339862375451', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -12, CURRENT_DATE()), 'john', '0.12613308249498645', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'jack', '0.7381524971311578', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -4, CURRENT_DATE()), 'alice', '0.08639585437319919', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -27, CURRENT_DATE()), 'tom', '0.9519897106846164', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'jack', '0.33446548574801926', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'jack', '0.40667134603483324', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -10, CURRENT_DATE()), 'jack', '0.17100718420628735', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -26, CURRENT_DATE()), 'lucy', '0.4445585525686886', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'tom', '0.47372916928883013', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'john', '0.19826861093848824', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -13, CURRENT_DATE()), 'john', '0.13679268112019338', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -24, CURRENT_DATE()), 'tom', '0.9805515708224516', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'dean', '0.4738376165601095', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'dean', '0.5739441073158964', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'alice', '0.8428505498030564', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'lucy', '0.32655416551155336', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -14, CURRENT_DATE()), 'tom', '0.7055736367780644', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -2, CURRENT_DATE()), 'tom', '0.9621355090189875', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -9, CURRENT_DATE()), 'jack', '0.9665339161730553', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'dean', '0.44309781869697995', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -18, CURRENT_DATE()), 'tom', '0.8651220802537761', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'lucy', '0.6451892308277741', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -16, CURRENT_DATE()), 'dean', '0.056797307451316725', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'lucy', '0.6847604118085596', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -23, CURRENT_DATE()), 'jack', '0.13428051757364667', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -29, CURRENT_DATE()), 'lucy', '0.9814797176951834', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -11, CURRENT_DATE()), 'tom', '0.7386074051153445', 'p3'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -25, CURRENT_DATE()), 'alice', '0.4825297824657663', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -19, CURRENT_DATE()), 'alice', '0.06608870508231235', 'p5'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -22, CURRENT_DATE()), 'lucy', '0.6278253028988848', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), 'alice', '0.6705580511822682', 'p1'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -19, CURRENT_DATE()), 'alice', '0.8131712486302015', 'p2'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -15, CURRENT_DATE()), 'lucy', '0.8124302447925607', 'p4'); -INSERT INTO s2_stay_time_statis (imp_date, user_name, stay_hours, page) VALUES (DATEADD('DAY', -8, CURRENT_DATE()), 'lucy', '0.039935860913407284', 'p2'); - - - -MERGE INTO genre(g_name,rating,most_popular_in) VALUES ('tagore',8,'孟加拉国'); -MERGE INTO genre(g_name,rating,most_popular_in) VALUES ('nazrul',7,'孟加拉国'); -MERGE INTO genre(g_name,rating,most_popular_in) VALUES ('民间',9,'锡尔赫特、吉大港、库斯蒂亚'); -MERGE INTO genre(g_name,rating,most_popular_in) VALUES ('现代',8,'孟加拉国'); -MERGE INTO genre(g_name,rating,most_popular_in) VALUES ('蓝调',7,'加拿大'); -MERGE INTO genre(g_name,rating,most_popular_in) VALUES ('流行',9,'美国'); - -MERGE INTO artist(artist_name,citizenship,gender,g_name) VALUES ('Shrikanta','印度','男性','tagore'); -MERGE INTO artist(artist_name,citizenship,gender,g_name) VALUES ('Prity','孟加拉国','女性','nazrul'); -MERGE INTO artist(artist_name,citizenship,gender,g_name) VALUES ('Farida','孟加拉国','女性','民间'); -MERGE INTO artist(artist_name,citizenship,gender,g_name) VALUES ('Topu','印度','女性','现代'); -MERGE INTO artist(artist_name,citizenship,gender,g_name) VALUES ('Enrique','美国','男性','蓝调'); -MERGE INTO artist(artist_name,citizenship,gender,g_name) VALUES ('Michel','英国','男性','流行'); - -MERGE INTO files(f_id,artist_name,file_size,duration,formats) VALUES (1,'Shrikanta','3.78 MB','3:45','mp4'); -MERGE INTO files(f_id,artist_name,file_size,duration,formats) VALUES (2,'Prity','4.12 MB','2:56','mp3'); -MERGE INTO files(f_id,artist_name,file_size,duration,formats) VALUES (3,'Farida','3.69 MB','4:12','mp4'); -MERGE INTO files(f_id,artist_name,file_size,duration,formats) VALUES (4,'Enrique','4.58 MB','5:23','mp4'); -MERGE INTO files(f_id,artist_name,file_size,duration,formats) VALUES (5,'Michel','5.10 MB','4:34','mp3'); -MERGE INTO files(f_id,artist_name,file_size,duration,formats) VALUES (6,'Topu','4.10 MB','4:30','mp4'); - -MERGE INTO song(imp_date,song_name,artist_name,country,f_id,g_name,rating,languages,releasedate,resolution) VALUES (DATEADD('DAY', 0, CURRENT_DATE()),'Tumi 长袍 尼罗布','Shrikanta','印度',1,'tagore',8,'孟加拉语','28-AUG-2011',1080); -MERGE INTO song(imp_date,song_name,artist_name,country,f_id,g_name,rating,languages,releasedate,resolution) VALUES (DATEADD('DAY', 0, CURRENT_DATE()),'舒克诺 帕塔尔 努普尔 帕埃','Prity','孟加拉国',2,'nazrul',5,'孟加拉语','21-SEP-1997',512); -MERGE INTO song(imp_date,song_name,artist_name,country,f_id,g_name,rating,languages,releasedate,resolution) VALUES (DATEADD('DAY', 0, CURRENT_DATE()),'阿米·奥帕尔·霍伊','Farida','孟加拉国',3,'民间',7,'孟加拉语','7-APR-2001',320); -MERGE INTO song(imp_date,song_name,artist_name,country,f_id,g_name,rating,languages,releasedate,resolution) VALUES (DATEADD('DAY', 0, CURRENT_DATE()),'我的爱','Enrique','美国',4,'蓝调',6,'英文','24-JAN-2007',1080); -MERGE INTO song(imp_date,song_name,artist_name,country,f_id,g_name,rating,languages,releasedate,resolution) VALUES (DATEADD('DAY', 0, CURRENT_DATE()),'打败它','Michel','英国',5,'流行',8,'英文','17-MAR-2002',720); -MERGE INTO song(imp_date,song_name,artist_name,country,f_id,g_name,rating,languages,releasedate,resolution) VALUES (DATEADD('DAY', 0, CURRENT_DATE()),'阿杰伊阿卡什','Topu','印度',6,'现代',10,'孟加拉语','27-MAR-2004',320); - - -MERGE into company(imp_date,company_id,company_name,headquarter_address,company_established_time,founder,ceo,annual_turnover,employee_count) VALUES (DATEADD('DAY', -1, CURRENT_DATE()),'item_enterprise_13_131','百度集团','北京','2000','李彦宏','李彦宏',102300000000,40000); -MERGE into company(imp_date,company_id,company_name,headquarter_address,company_established_time,founder,ceo,annual_turnover,employee_count) VALUES (DATEADD('DAY', -1, CURRENT_DATE()),'item_enterprise_13_132','阿里巴巴集团','杭州','1999年','马云','张勇',376800000000,103699); -MERGE into company(imp_date,company_id,company_name,headquarter_address,company_established_time,founder,ceo,annual_turnover,employee_count) VALUES (DATEADD('DAY', -1, CURRENT_DATE()),'item_enterprise_13_133','深圳市腾讯计算机系统有限公司','深圳','1998','马化腾','刘炽平',321600000000,56310); -MERGE into company(imp_date,company_id,company_name,headquarter_address,company_established_time,founder,ceo,annual_turnover,employee_count) VALUES (DATEADD('DAY', -1, CURRENT_DATE()),'item_enterprise_13_134','北京京东世纪贸易有限公司','北京','1998','刘强东','刘强东',28800000000,179000); -MERGE into company(imp_date,company_id,company_name,headquarter_address,company_established_time,founder,ceo,annual_turnover,employee_count) VALUES (DATEADD('DAY', -1, CURRENT_DATE()),'item_enterprise_13_135','网易公司','杭州','1997','丁磊','丁磊',67500000000,20000); - -MERGE into brand(imp_date,brand_id,brand_name,brand_established_time,company_id,legal_representative,registered_capital) VALUES (DATEADD('DAY', -1, CURRENT_DATE()),'item_enterprise_13_136','阿里云','2009年9月10日','item_enterprise_13_132','张勇',50000000); -MERGE into brand(imp_date,brand_id,brand_name,brand_established_time,company_id,legal_representative,registered_capital) VALUES (DATEADD('DAY', -1, CURRENT_DATE()),'item_enterprise_13_137','天猫','2012年1月11日','item_enterprise_13_132','张勇',100000000); -MERGE into brand(imp_date,brand_id,brand_name,brand_established_time,company_id,legal_representative,registered_capital) VALUES (DATEADD('DAY', -1, CURRENT_DATE()),'item_enterprise_13_138','腾讯游戏','2003','item_enterprise_13_133','马化腾',50000000); -MERGE into brand(imp_date,brand_id,brand_name,brand_established_time,company_id,legal_representative,registered_capital) VALUES (DATEADD('DAY', -1, CURRENT_DATE()),'item_enterprise_13_139','度小满','2018','item_enterprise_13_131','朱光',100000000); -MERGE into brand(imp_date,brand_id,brand_name,brand_established_time,company_id,legal_representative,registered_capital) VALUES (DATEADD('DAY', -1, CURRENT_DATE()),'item_enterprise_13_140','京东金融','2017','item_enterprise_13_134','刘强东',100000000); - -insert into company_revenue(imp_date,company_id,brand_id,revenue_proportion,profit_proportion,expenditure_proportion) VALUES ( DATEADD('DAY', -1, CURRENT_DATE()),'item_enterprise_13_131','item_enterprise_13_139',10,10,30); -insert into company_revenue(imp_date,company_id,brand_id,revenue_proportion,profit_proportion,expenditure_proportion) VALUES ( DATEADD('DAY', -1, CURRENT_DATE()),'item_enterprise_13_133','item_enterprise_13_138',80,80,60); -insert into company_revenue(imp_date,company_id,brand_id,revenue_proportion,profit_proportion,expenditure_proportion) VALUES ( DATEADD('DAY', -1, CURRENT_DATE()),'item_enterprise_13_134','item_enterprise_13_140',80,80,60); -insert into company_revenue(imp_date,company_id,brand_id,revenue_proportion,profit_proportion,expenditure_proportion) VALUES ( DATEADD('DAY', -1, CURRENT_DATE()),'item_enterprise_13_132','item_enterprise_13_137',80,80,60); -insert into company_revenue(imp_date,company_id,brand_id,revenue_proportion,profit_proportion,expenditure_proportion) VALUES ( DATEADD('DAY', -1, CURRENT_DATE()),'item_enterprise_13_132','item_enterprise_13_136',10,10,30); - -insert into company_brand_revenue(imp_date,year_time,brand_id,revenue,profit,revenue_growth_year_on_year,profit_growth_year_on_year) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), '2018','item_enterprise_13_138',500000000,-300000000,10,-10); -insert into company_brand_revenue(imp_date,year_time,brand_id,revenue,profit,revenue_growth_year_on_year,profit_growth_year_on_year) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), '2019','item_enterprise_13_136',100000000000,50000000000,100,50); -insert into company_brand_revenue(imp_date,year_time,brand_id,revenue,profit,revenue_growth_year_on_year,profit_growth_year_on_year) VALUES ( DATEADD('DAY', -1, CURRENT_DATE()),'2018','item_enterprise_13_137',100000000000,50000000000,100,-10); -insert into company_brand_revenue(imp_date,year_time,brand_id,revenue,profit,revenue_growth_year_on_year,profit_growth_year_on_year) VALUES (DATEADD('DAY', -1, CURRENT_DATE()), '2018','item_enterprise_13_139',500000000,50000000000,10,50); -insert into company_brand_revenue(imp_date,year_time,brand_id,revenue,profit,revenue_growth_year_on_year,profit_growth_year_on_year) VALUES ( DATEADD('DAY', -1, CURRENT_DATE()),'2018','item_enterprise_13_140',100000000000,-300000000,10,50); - --- benchmark +values (1, 1, 'modelEdgeRelation', '[{"source":"datasource-1","target":"datasource-3","type":"polyline","id":"edge-0.305251275235679741702883718912","style":{"active":{"stroke":"rgb(95, 149, 255)","lineWidth":1},"selected":{"stroke":"rgb(95, 149, 255)","lineWidth":2,"shadowColor":"rgb(95, 149, 255)","shadowBlur":10,"text-shape":{"fontWeight":500}},"highlight":{"stroke":"rgb(95, 149, 255)","lineWidth":2,"text-shape":{"fontWeight":500}},"inactive":{"stroke":"rgb(234, 234, 234)","lineWidth":1},"disable":{"stroke":"rgb(245, 245, 245)","lineWidth":1},"stroke":"#296df3","endArrow":true},"startPoint":{"x":-94,"y":-137.5,"anchorIndex":0,"id":"-94|||-137.5"},"endPoint":{"x":-234,"y":-45,"anchorIndex":1,"id":"-234|||-45"},"sourceAnchor":2,"targetAnchor":1,"label":"模型关系编辑"},{"source":"datasource-1","target":"datasource-2","type":"polyline","id":"edge-0.466237264629309141702883756359","style":{"active":{"stroke":"rgb(95, 149, 255)","lineWidth":1},"selected":{"stroke":"rgb(95, 149, 255)","lineWidth":2,"shadowColor":"rgb(95, 149, 255)","shadowBlur":10,"text-shape":{"fontWeight":500}},"highlight":{"stroke":"rgb(95, 149, 255)","lineWidth":2,"text-shape":{"fontWeight":500}},"inactive":{"stroke":"rgb(234, 234, 234)","lineWidth":1},"disable":{"stroke":"rgb(245, 245, 245)","lineWidth":1},"stroke":"#296df3","endArrow":true},"startPoint":{"x":-12,"y":-137.5,"anchorIndex":1,"id":"-12|||-137.5"},"endPoint":{"x":85,"y":31.5,"anchorIndex":0,"id":"85|||31.5"},"sourceAnchor":1,"targetAnchor":2,"label":"模型关系编辑"}]', '2023-06-01', 'admin', '2023-06-01', 'admin'); \ No newline at end of file diff --git a/launchers/standalone/src/test/resources/db/schema-h2-demo.sql b/launchers/standalone/src/test/resources/db/schema-h2-demo.sql new file mode 100644 index 000000000..20f361cb7 --- /dev/null +++ b/launchers/standalone/src/test/resources/db/schema-h2-demo.sql @@ -0,0 +1,85 @@ +-------S2VisitsDemo +CREATE TABLE IF NOT EXISTS `s2_user_department` ( + `user_name` varchar(200) NOT NULL, + `department` varchar(200) NOT NULL, -- department of user + PRIMARY KEY (`user_name`,`department`) + ); +COMMENT ON TABLE s2_user_department IS 'user_department_info'; + +CREATE TABLE IF NOT EXISTS `s2_pv_uv_statis` ( + `imp_date` varchar(200) NOT NULL, + `user_name` varchar(200) NOT NULL, + `page` varchar(200) NOT NULL + ); +COMMENT ON TABLE s2_pv_uv_statis IS 's2_pv_uv_statis'; + +CREATE TABLE IF NOT EXISTS `s2_stay_time_statis` ( + `imp_date` varchar(200) NOT NULL, + `user_name` varchar(200) NOT NULL, + `stay_hours` DOUBLE NOT NULL, + `page` varchar(200) NOT NULL + ); +COMMENT ON TABLE s2_stay_time_statis IS 's2_stay_time_statis_info'; + +-------S2ArtistDemo +CREATE TABLE IF NOT EXISTS `singer` ( + `singer_name` varchar(200) NOT NULL, + `act_area` varchar(200) NOT NULL, + `song_name` varchar(200) NOT NULL, + `genre` varchar(200) NOT NULL, + `js_play_cnt` bigINT DEFAULT NULL, + `down_cnt` bigINT DEFAULT NULL, + `favor_cnt` bigINT DEFAULT NULL, + PRIMARY KEY (`singer_name`) + ); +COMMENT ON TABLE singer IS 'singer_info'; + +CREATE TABLE IF NOT EXISTS `genre` ( + `g_name` varchar(20) NOT NULL , -- genre name + `rating` INT , + `most_popular_in` varchar(50) , + PRIMARY KEY (`g_name`) + ); +COMMENT ON TABLE genre IS 'genre'; + +CREATE TABLE IF NOT EXISTS `artist` ( + `artist_name` varchar(50) NOT NULL , -- genre name + `citizenship` varchar(20) , + `gender` varchar(20) , + `g_name` varchar(50), + PRIMARY KEY (`artist_name`,`citizenship`) + ); +COMMENT ON TABLE artist IS 'artist'; + +-------S2CompanyDemo +CREATE TABLE IF NOT EXISTS `company` ( + `company_id` varchar(50) NOT NULL , + `company_name` varchar(50) NOT NULL , + `headquarter_address` varchar(50) NOT NULL , + `company_established_time` varchar(20) NOT NULL , + `founder` varchar(20) NOT NULL , + `ceo` varchar(20) NOT NULL , + `annual_turnover` bigint(15) , + `employee_count` int(7) , + PRIMARY KEY (`company_id`) + ); + +CREATE TABLE IF NOT EXISTS `brand` ( + `brand_id` varchar(50) NOT NULL , + `brand_name` varchar(50) NOT NULL , + `brand_established_time` varchar(20) NOT NULL , + `company_id` varchar(50) NOT NULL , + `legal_representative` varchar(20) NOT NULL , + `registered_capital` bigint(15) , + PRIMARY KEY (`brand_id`) + ); + +CREATE TABLE IF NOT EXISTS `brand_revenue` ( + `year_time` varchar(10) NOT NULL , + `brand_id` varchar(50) NOT NULL , + `revenue` bigint(15) NOT NULL, + `profit` bigint(15) NOT NULL , + `revenue_growth_year_on_year` double NOT NULL , + `profit_growth_year_on_year` double NOT NULL + ); + diff --git a/launchers/standalone/src/test/resources/s2-config.yaml b/launchers/standalone/src/test/resources/s2-config.yaml index e570dfb12..a95a4df7e 100644 --- a/launchers/standalone/src/test/resources/s2-config.yaml +++ b/launchers/standalone/src/test/resources/s2-config.yaml @@ -21,7 +21,7 @@ s2: date: true demo: - names: S2VisitsDemo,S2SingerDemo + names: S2VisitsDemo,S2SingerDemo,S2CompanyDemo enableLLM: false authentication: diff --git a/pom.xml b/pom.xml index 3ef71963e..81c9d17f5 100644 --- a/pom.xml +++ b/pom.xml @@ -47,7 +47,7 @@ 2.14.1 2.12.1 0.12.3 - 1.2.3 + 1.2.24 5.1.46 3.5.7 0.4.6 diff --git a/webapp/packages/supersonic-fe/config/routes.ts b/webapp/packages/supersonic-fe/config/routes.ts index 0326eabf3..04a8413d8 100644 --- a/webapp/packages/supersonic-fe/config/routes.ts +++ b/webapp/packages/supersonic-fe/config/routes.ts @@ -57,24 +57,139 @@ const ROUTES = [ }, { path: '/model/', - component: './SemanticModel/DomainManager', + component: './SemanticModel/', name: 'semanticModel', envEnableList: [ENV_KEY.SEMANTIC], routes: [ { - path: '/model/:domainId/:modelId', - component: './SemanticModel/DomainManager', - // name: 'semanticModel', - envEnableList: [ENV_KEY.SEMANTIC], + path: '/model/', + redirect: '/model/domain', }, { - path: '/model/:domainId/:modelId/:menuKey', - component: './SemanticModel/DomainManager', - // name: 'semanticModel', - envEnableList: [ENV_KEY.SEMANTIC], + path: '/model/domain/', + component: './SemanticModel/OverviewContainer', + routes: [ + { + path: '/model/domain/:domainId', + component: './SemanticModel/DomainManager', + routes: [ + { + path: '/model/domain/:domainId/:menuKey', + component: './SemanticModel/DomainManager', + }, + ], + }, + { + path: '/model/domain/manager/:domainId/:modelId', + component: './SemanticModel/ModelManager', + routes: [ + { + path: '/model/domain/manager/:domainId/:modelId/:menuKey', + component: './SemanticModel/ModelManager', + }, + ], + }, + ], }, + { + path: '/model/metric/:domainId/:modelId/:metricId', + component: './SemanticModel/Metric/Edit', + envEnableList: [ENV_KEY.SEMANTIC], + // routes: [ + // { + // path: '/model/manager/:domainId/:modelId/:menuKey', + // component: './SemanticModel/ModelManager', + // }, + // ], + }, + // { + // path: '/model/manager/', + // component: './SemanticModel/OverviewContainer', + // routes: [ + // { + // path: '/model/manager/:domainId/:modelId', + // component: './SemanticModel/ModelManager', + // routes: [ + // { + // path: '/model/manager/:domainId/:modelId/:menuKey', + // component: './SemanticModel/ModelManager', + // }, + // ], + // }, + // ], + // }, + // { + // path: '/model/:domainId', + // component: './SemanticModel/DomainManager', + // envEnableList: [ENV_KEY.SEMANTIC], + // routes: [ + // { + // path: '/model/:domainId/:menuKey', + // component: './SemanticModel/DomainManager', + // }, + // ], + // }, + // { + // path: '/model/manager/:domainId/:modelId', + // component: './SemanticModel/ModelManager', + // envEnableList: [ENV_KEY.SEMANTIC], + // routes: [ + // { + // path: '/model/manager/:domainId/:modelId/:menuKey', + // component: './SemanticModel/ModelManager', + // }, + // ], + // }, + + // { + // path: '/model/:domainId/:modelId/:menuKey', + // component: './SemanticModel/DomainManager', + // envEnableList: [ENV_KEY.SEMANTIC], + // }, + // { + // path: '/model/:domainId/:modelId/metric', + // component: './SemanticModel/components/ModelMetric', + // envEnableList: [ENV_KEY.SEMANTIC], + // routes: [ + // { + // path: '/model/:domainId/:modelId/metric/list', + // component: './SemanticModel/components/ClassMetricTable', + // envEnableList: [ENV_KEY.SEMANTIC], + // }, + // ], + // }, ], }, + // { + // path: '/model/', + // component: './SemanticModel/DomainManager', + // name: 'semanticModel', + // envEnableList: [ENV_KEY.SEMANTIC], + // routes: [ + // { + // path: '/model/:domainId/:modelId', + // component: './SemanticModel/DomainManager', + // envEnableList: [ENV_KEY.SEMANTIC], + // }, + // { + // path: '/model/:domainId/:modelId/:menuKey', + // component: './SemanticModel/DomainManager', + // envEnableList: [ENV_KEY.SEMANTIC], + // }, + // { + // path: '/model/:domainId/:modelId/metric', + // component: './SemanticModel/components/ModelMetric', + // envEnableList: [ENV_KEY.SEMANTIC], + // routes: [ + // { + // path: '/model/:domainId/:modelId/metric/list', + // component: './SemanticModel/components/ClassMetricTable', + // envEnableList: [ENV_KEY.SEMANTIC], + // }, + // ], + // }, + // ], + // }, // { // path: '/model/:domainId/:modelId/:menuKey', diff --git a/webapp/packages/supersonic-fe/src/pages/SemanticModel/Dimension/index.tsx b/webapp/packages/supersonic-fe/src/pages/SemanticModel/Dimension/index.tsx new file mode 100644 index 000000000..81dc60372 --- /dev/null +++ b/webapp/packages/supersonic-fe/src/pages/SemanticModel/Dimension/index.tsx @@ -0,0 +1,12 @@ +import React from 'react'; +import { Outlet } from '@umijs/max'; + +const Dimension: React.FC = () => { + return ( + <> + + + ); +}; + +export default Dimension; diff --git a/webapp/packages/supersonic-fe/src/pages/SemanticModel/Dimension/style.less b/webapp/packages/supersonic-fe/src/pages/SemanticModel/Dimension/style.less new file mode 100644 index 000000000..e69de29bb diff --git a/webapp/packages/supersonic-fe/src/pages/SemanticModel/DomainManager.tsx b/webapp/packages/supersonic-fe/src/pages/SemanticModel/DomainManager.tsx index 6b6106d62..d278a710b 100644 --- a/webapp/packages/supersonic-fe/src/pages/SemanticModel/DomainManager.tsx +++ b/webapp/packages/supersonic-fe/src/pages/SemanticModel/DomainManager.tsx @@ -1,12 +1,31 @@ -import React from 'react'; -import OverviewContainer from './OverviewContainer'; +import React, { useState } from 'react'; +import { history, useParams, useModel } from '@umijs/max'; +import DomainManagerTab from './components/DomainManagerTab'; type Props = {}; -const DomainManager: React.FC = () => { + +const DomainManager: React.FC = ({}) => { + const defaultTabKey = 'overview'; + const params: any = useParams(); + const domainModel = useModel('SemanticModel.domainData'); + + const { selectDomainId } = domainModel; + const menuKey = params.menuKey ? params.menuKey : defaultTabKey; + + const [activeKey, setActiveKey] = useState(menuKey); + + const pushUrlMenu = (domainId: number, menuKey: string) => { + history.push(`/model/domain/${domainId}/${menuKey}`); + }; + return ( - <> - - + { + setActiveKey(menuKey); + pushUrlMenu(selectDomainId, menuKey); + }} + /> ); }; diff --git a/webapp/packages/supersonic-fe/src/pages/SemanticModel/Insights/Market.tsx b/webapp/packages/supersonic-fe/src/pages/SemanticModel/Insights/Market.tsx index bcb2df739..b2c931391 100644 --- a/webapp/packages/supersonic-fe/src/pages/SemanticModel/Insights/Market.tsx +++ b/webapp/packages/supersonic-fe/src/pages/SemanticModel/Insights/Market.tsx @@ -155,7 +155,7 @@ const ClassMetricTable: React.FC = ({}) => { const columnsConfig = ColumnsConfig({ indicatorInfo: { - url: '/tag/detail/', + url: '/tag/detail/:indicatorId', starType: 'tag', }, }); diff --git a/webapp/packages/supersonic-fe/src/pages/SemanticModel/Metric/Edit.tsx b/webapp/packages/supersonic-fe/src/pages/SemanticModel/Metric/Edit.tsx index abcf8432d..e7bec7836 100644 --- a/webapp/packages/supersonic-fe/src/pages/SemanticModel/Metric/Edit.tsx +++ b/webapp/packages/supersonic-fe/src/pages/SemanticModel/Metric/Edit.tsx @@ -1,7 +1,7 @@ import { message } from 'antd'; import React, { useState, useEffect } from 'react'; import { getMetricData } from '../service'; -import { useParams } from '@umijs/max'; +import { useParams, useModel } from '@umijs/max'; import styles from './style.less'; import { ISemantic } from '../data'; import MetricInfoEditSider from './MetricInfoEditSider'; @@ -14,7 +14,8 @@ const MetricDetail: React.FC = () => { const params: any = useParams(); const metricId = params.metricId; const [metircData, setMetircData] = useState(); - + const metricModel = useModel('SemanticModel.metricData'); + const { selectMetric, setSelectMetric } = metricModel; const [settingKey, setSettingKey] = useState(MetricSettingKey.BASIC); useEffect(() => { @@ -24,10 +25,17 @@ const MetricDetail: React.FC = () => { queryMetricData(metricId); }, [metricId]); + useEffect(() => { + return () => { + setSelectMetric(undefined); + }; + }, []); + const queryMetricData = async (metricId: string) => { const { code, data, msg } = await getMetricData(metricId); if (code === 200) { setMetircData({ ...data }); + setSelectMetric({ ...data }); return; } message.error(msg); diff --git a/webapp/packages/supersonic-fe/src/pages/SemanticModel/Metric/components/MetricInfoCreateForm.tsx b/webapp/packages/supersonic-fe/src/pages/SemanticModel/Metric/components/MetricInfoCreateForm.tsx index c7c0b6460..217b25e05 100644 --- a/webapp/packages/supersonic-fe/src/pages/SemanticModel/Metric/components/MetricInfoCreateForm.tsx +++ b/webapp/packages/supersonic-fe/src/pages/SemanticModel/Metric/components/MetricInfoCreateForm.tsx @@ -904,7 +904,9 @@ const MetricInfoCreateForm: React.FC = ({ type="primary" key="console" onClick={() => { - history.replace(`/model/${domainId}/${modelId || metricItem?.modelId}/dataSource`); + history.replace( + `/model/domain/manager/${domainId}/${modelId || metricItem?.modelId}/dataSource`, + ); onCancel?.(); }} > diff --git a/webapp/packages/supersonic-fe/src/pages/SemanticModel/ModelManager.tsx b/webapp/packages/supersonic-fe/src/pages/SemanticModel/ModelManager.tsx new file mode 100644 index 000000000..1cf463814 --- /dev/null +++ b/webapp/packages/supersonic-fe/src/pages/SemanticModel/ModelManager.tsx @@ -0,0 +1,53 @@ +import React, { useEffect, useState } from 'react'; +import { history, useParams, useModel } from '@umijs/max'; +import ModelManagerTab from './components/ModelManagerTab'; + +type Props = {}; + +const ModelManager: React.FC = ({}) => { + const defaultTabKey = 'overview'; + const params: any = useParams(); + const modelId = params.modelId; + const domainModel = useModel('SemanticModel.domainData'); + const modelModel = useModel('SemanticModel.modelData'); + const dimensionModel = useModel('SemanticModel.dimensionData'); + const metricModel = useModel('SemanticModel.metricData'); + const { selectDomainId } = domainModel; + const { selectModelId, modelList } = modelModel; + const { MrefreshDimensionList } = dimensionModel; + const { MrefreshMetricList } = metricModel; + const menuKey = params.menuKey ? params.menuKey : !Number(modelId) ? defaultTabKey : ''; + const [activeKey, setActiveKey] = useState(menuKey); + + const initModelConfig = () => { + const currentMenuKey = menuKey === defaultTabKey ? '' : menuKey; + pushUrlMenu(selectDomainId, selectModelId, currentMenuKey); + setActiveKey(currentMenuKey); + }; + + useEffect(() => { + if (!selectModelId || `${selectModelId}` === `${modelId}`) { + return; + } + initModelConfig(); + MrefreshDimensionList({ modelId: selectModelId }); + MrefreshMetricList({ modelId: selectModelId }); + }, [selectModelId]); + + const pushUrlMenu = (domainId: number, modelId: number, menuKey: string) => { + history.push(`/model/domain/manager/${domainId}/${modelId}/${menuKey}`); + }; + + return ( + { + setActiveKey(menuKey); + pushUrlMenu(selectDomainId, selectModelId, menuKey); + }} + /> + ); +}; + +export default ModelManager; diff --git a/webapp/packages/supersonic-fe/src/pages/SemanticModel/OverviewContainer.tsx b/webapp/packages/supersonic-fe/src/pages/SemanticModel/OverviewContainer.tsx index 20786ca24..e99c011ef 100644 --- a/webapp/packages/supersonic-fe/src/pages/SemanticModel/OverviewContainer.tsx +++ b/webapp/packages/supersonic-fe/src/pages/SemanticModel/OverviewContainer.tsx @@ -1,163 +1,99 @@ -import { message } from 'antd'; import React, { useEffect, useState } from 'react'; -import { history, useParams, useModel } from '@umijs/max'; +import { history, useParams, useModel, Outlet } from '@umijs/max'; import DomainListTree from './components/DomainList'; import styles from './components/style.less'; import { LeftOutlined, RightOutlined } from '@ant-design/icons'; import { ISemantic } from './data'; -import { getDomainList, getDataSetList } from './service'; -import DomainManagerTab from './components/DomainManagerTab'; -import { isArrayOfValues } from '@/utils/utils'; -type Props = { - mode: 'domain'; -}; +type Props = {}; -const OverviewContainer: React.FC = ({ mode }) => { +const OverviewContainer: React.FC = ({}) => { const defaultTabKey = 'overview'; - // 'overview' dataSetManage const params: any = useParams(); const domainId = params.domainId; const modelId = params.modelId; const domainModel = useModel('SemanticModel.domainData'); const modelModel = useModel('SemanticModel.modelData'); - const dimensionModel = useModel('SemanticModel.dimensionData'); - const metricModel = useModel('SemanticModel.metricData'); const databaseModel = useModel('SemanticModel.databaseData'); - const { selectDomainId, domainList, setSelectDomain, setDomainList } = domainModel; - const { - selectModelId, - modelList, - MrefreshModelList, - setSelectModel, - setModelTableHistoryParams, - } = modelModel; - const { MrefreshDimensionList } = dimensionModel; - const { MrefreshMetricList } = metricModel; + const { setSelectDomain, setDomainList, selectDomainId } = domainModel; + const { setSelectModel, setModelTableHistoryParams, MrefreshModelList } = modelModel; const { MrefreshDatabaseList } = databaseModel; const menuKey = params.menuKey ? params.menuKey : !Number(modelId) ? defaultTabKey : ''; - const [isModel, setIsModel] = useState(false); const [collapsedState, setCollapsedState] = useState(true); - const [activeKey, setActiveKey] = useState(menuKey); - const [dataSetList, setDataSetList] = useState([]); - - const initSelectedDomain = (domainList: ISemantic.IDomainItem[]) => { - const targetNode = domainList.filter((item: any) => { - return `${item.id}` === domainId; - })[0]; - if (!targetNode) { - const firstRootNode = domainList.filter((item: any) => { - return item.parentId === 0; - })[0]; - if (firstRootNode) { - const { id } = firstRootNode; - setSelectDomain(firstRootNode); - setActiveKey(menuKey); - pushUrlMenu(id, 0, menuKey); - } - } else { - setSelectDomain(targetNode); - } - }; - - const initProjectTree = async () => { - const { code, data, msg } = await getDomainList(); - if (code === 200) { - initSelectedDomain(data); - setDomainList(data); - } else { - message.error(msg); - } - }; useEffect(() => { - initProjectTree(); - MrefreshDatabaseList(); - return () => { - setSelectDomain(undefined); - setSelectModel(undefined); - }; - }, []); + if (!selectDomainId || `${domainId}` === `${selectDomainId}`) { + return; + } + pushUrlMenu(selectDomainId, menuKey); + }, [selectDomainId]); + + // const initSelectedDomain = (domainList: ISemantic.IDomainItem[]) => { + // const targetNode = domainList.filter((item: any) => { + // return `${item.id}` === domainId; + // })[0]; + // if (!targetNode) { + // const firstRootNode = domainList.filter((item: any) => { + // return item.parentId === 0; + // })[0]; + // if (firstRootNode) { + // const { id } = firstRootNode; + // setSelectDomain(firstRootNode); + // pushUrlMenu(id, menuKey); + // } + // } else { + // setSelectDomain(targetNode); + // } + // }; + + // const initProjectTree = async () => { + // const { code, data, msg } = await getDomainList(); + // if (code === 200) { + // initSelectedDomain(data); + // setDomainList(data); + // } else { + // message.error(msg); + // } + // }; + + // useEffect(() => { + // initProjectTree(); + // MrefreshDatabaseList(); + // return () => { + // setSelectDomain(undefined); + // }; + // }, []); + + const pushUrlMenu = (domainId: number, menuKey: string) => { + history.push(`/model/domain/${domainId}/${menuKey}`); + }; + + const cleanModelInfo = (domainId) => { + pushUrlMenu(domainId, defaultTabKey); + setSelectModel(undefined); + }; + + const handleCollapsedBtn = () => { + setCollapsedState(!collapsedState); + }; useEffect(() => { if (!selectDomainId) { return; } queryModelList(); - queryDataSetList(); }, [selectDomainId]); - const queryDataSetList = async () => { - const { code, data, msg } = await getDataSetList(selectDomainId); - if (code === 200) { - setDataSetList(data); - if (!isArrayOfValues(data)) { - setActiveKey(defaultTabKey); - } - } else { - message.error(msg); - } - }; - const queryModelList = async () => { await MrefreshModelList(selectDomainId); }; - useEffect(() => { - if (!selectDomainId) { - return; - } - setIsModel(false); - }, [domainList, selectDomainId]); - - const initModelConfig = () => { - setIsModel(true); - const currentMenuKey = menuKey === defaultTabKey ? '' : menuKey; - pushUrlMenu(selectDomainId, selectModelId, currentMenuKey); - setActiveKey(currentMenuKey); - }; - - useEffect(() => { - if (!selectModelId) { - return; - } - initModelConfig(); - MrefreshDimensionList({ modelId: selectModelId }); - MrefreshMetricList({ modelId: selectModelId }); - }, [selectModelId]); - - const pushUrlMenu = (domainId: number, modelId: number, menuKey: string) => { - history.push(`/model/${domainId}/${modelId || 0}/${menuKey}`); - }; - - const handleModelChange = (model?: ISemantic.IModelItem) => { - if (!model) { - return; - } - if (`${model.id}` === `${selectModelId}`) { - initModelConfig(); - } - setSelectModel(model); - }; - - const cleanModelInfo = (domainId) => { - setIsModel(false); - setActiveKey(defaultTabKey); - pushUrlMenu(domainId, 0, defaultTabKey); - setSelectModel(undefined); - }; - - const handleCollapsedBtn = () => { - setCollapsedState(!collapsedState); - }; - return (
{ const { id } = domainData; cleanModelInfo(id); @@ -166,9 +102,9 @@ const OverviewContainer: React.FC = ({ mode }) => { [id]: {}, }); }} - onTreeDataUpdate={() => { - initProjectTree(); - }} + // onTreeDataUpdate={() => { + // // initProjectTree(); + // }} />
@@ -182,29 +118,7 @@ const OverviewContainer: React.FC = ({ mode }) => {
- {selectDomainId ? ( - <> - { - handleModelChange(model); - MrefreshModelList(selectDomainId); - }} - onBackDomainBtnClick={() => { - cleanModelInfo(selectDomainId); - }} - onMenuChange={(menuKey) => { - setActiveKey(menuKey); - pushUrlMenu(selectDomainId, selectModelId, menuKey); - }} - /> - - ) : ( -

请选择项目

- )} +
diff --git a/webapp/packages/supersonic-fe/src/pages/SemanticModel/PageBreadcrumb.tsx b/webapp/packages/supersonic-fe/src/pages/SemanticModel/PageBreadcrumb.tsx new file mode 100644 index 000000000..8c3efdc37 --- /dev/null +++ b/webapp/packages/supersonic-fe/src/pages/SemanticModel/PageBreadcrumb.tsx @@ -0,0 +1,78 @@ +import { Outlet } from '@umijs/max'; +import { Tabs, Breadcrumb, Space, Radio } from 'antd'; +import React, { useRef, useEffect, useState } from 'react'; +import { history, useModel } from '@umijs/max'; +import { HomeOutlined, FundViewOutlined } from '@ant-design/icons'; +import styles from './components/style.less'; + +const PageBreadcrumb: React.FC = () => { + const domainModel = useModel('SemanticModel.domainData'); + const modelModel = useModel('SemanticModel.modelData'); + const metricModel = useModel('SemanticModel.metricData'); + const { selectDomainId, selectDomainName, selectDomain: domainData } = domainModel; + const { selectModelId, selectModelName, setSelectModel } = modelModel; + + const { selectMetric, setSelectMetric } = metricModel; + + const items = [ + { + title: ( + { + setSelectModel(undefined); + history.push(`/model/domain/${selectDomainId}/overview`); + }} + > + + {selectDomainName} + + ), + }, + ]; + + if (selectModelName) { + items.push( + { + type: 'separator', + separator: '/', + }, + { + title: ( + { + setSelectMetric(undefined); + history.push(`/model/domain/manager/${selectDomainId}/${selectModelId}/`); + }} + > + + {selectModelName} + + ), + }, + ); + } + + if (selectMetric?.name) { + items.push( + { + type: 'separator', + separator: '/', + }, + { + title: selectMetric?.name ? ( + + + {selectMetric.name} + + ) : undefined, + }, + ); + } + return ( + <> + + + ); +}; + +export default PageBreadcrumb; diff --git a/webapp/packages/supersonic-fe/src/pages/SemanticModel/View/components/DataSetTable.tsx b/webapp/packages/supersonic-fe/src/pages/SemanticModel/View/components/DataSetTable.tsx index 0827df07b..d75534090 100644 --- a/webapp/packages/supersonic-fe/src/pages/SemanticModel/View/components/DataSetTable.tsx +++ b/webapp/packages/supersonic-fe/src/pages/SemanticModel/View/components/DataSetTable.tsx @@ -13,12 +13,11 @@ import { ColumnsConfig } from '../../components/TableColumnRender'; import ViewSearchFormModal from './ViewSearchFormModal'; type Props = { - dataSetList: ISemantic.IDatasetItem[]; + // dataSetList: ISemantic.IDatasetItem[]; disabledEdit?: boolean; - isCurrent: boolean; }; -const DataSetTable: React.FC = ({ dataSetList, disabledEdit = false, isCurrent }) => { +const DataSetTable: React.FC = ({ disabledEdit = false }) => { const domainModel = useModel('SemanticModel.domainData'); const { selectDomainId } = domainModel; @@ -44,16 +43,15 @@ const DataSetTable: React.FC = ({ dataSetList, disabledEdit = false, isCu } }; - const [viewList, setViewList] = useState(dataSetList); + const [viewList, setViewList] = useState(); useEffect(() => { - setViewList(dataSetList); - }, [dataSetList]); - - useEffect(() => { - // queryDataSetList(); - if (isCurrent) queryDomainAllModel(); - }, [selectDomainId, isCurrent]); + if (!selectDomainId) { + return; + } + queryDataSetList(); + queryDomainAllModel(); + }, [selectDomainId]); const queryDataSetList = async () => { setLoading(true); diff --git a/webapp/packages/supersonic-fe/src/pages/SemanticModel/View/index.tsx b/webapp/packages/supersonic-fe/src/pages/SemanticModel/View/index.tsx index fab3c3acc..f36197f88 100644 --- a/webapp/packages/supersonic-fe/src/pages/SemanticModel/View/index.tsx +++ b/webapp/packages/supersonic-fe/src/pages/SemanticModel/View/index.tsx @@ -3,15 +3,13 @@ import { ISemantic } from '../data'; import DataSetTable from './components/DataSetTable'; type Props = { - isCurrent: boolean; disabledEdit?: boolean; - dataSetList: ISemantic.IDatasetItem[]; }; -const View: React.FC = ({ isCurrent, dataSetList, disabledEdit = false }) => { +const View: React.FC = ({ disabledEdit = false }) => { return (
- +
); }; diff --git a/webapp/packages/supersonic-fe/src/pages/SemanticModel/components/ClassMetricTable.tsx b/webapp/packages/supersonic-fe/src/pages/SemanticModel/components/ClassMetricTable.tsx index c5da0348f..3a22ba7ec 100644 --- a/webapp/packages/supersonic-fe/src/pages/SemanticModel/components/ClassMetricTable.tsx +++ b/webapp/packages/supersonic-fe/src/pages/SemanticModel/components/ClassMetricTable.tsx @@ -3,7 +3,7 @@ import { ProTable } from '@ant-design/pro-components'; import { message, Button, Space, Popconfirm, Input, Select, Tag } from 'antd'; import React, { useRef, useState, useEffect } from 'react'; import { StatusEnum, SemanticNodeType } from '../enum'; -import { useModel } from '@umijs/max'; +import { useModel, history } from '@umijs/max'; import { SENSITIVE_LEVEL_ENUM, SENSITIVE_LEVEL_OPTIONS, TAG_DEFINE_TYPE } from '../constant'; import { queryMetric, @@ -32,7 +32,7 @@ const ClassMetricTable: React.FC = ({ onEmptyMetricData }) => { const metricModel = useModel('SemanticModel.metricData'); const { selectDomainId } = domainModel; const { selectModelId: modelId } = modelModel; - const { MrefreshMetricList } = metricModel; + const { MrefreshMetricList, selectMetric, setSelectMetric } = metricModel; const [batchSensitiveLevelOpenState, setBatchSensitiveLevelOpenState] = useState(false); const [createModalVisible, setCreateModalVisible] = useState(false); const [metricItem, setMetricItem] = useState(); @@ -142,7 +142,14 @@ const ClassMetricTable: React.FC = ({ onEmptyMetricData }) => { } }; - const columnsConfig = ColumnsConfig({ indicatorInfo: { url: '/model/metric/edit/' } }); + const columnsConfig = ColumnsConfig({ + indicatorInfo: { + url: '/model/metric/:domainId/:modelId/:indicatorId', + onNameClick: (record: ISemantic.IMetricItem) => { + setSelectMetric(record); + }, + }, + }); const columns: ProColumns[] = [ { @@ -236,8 +243,9 @@ const ClassMetricTable: React.FC = ({ onEmptyMetricData }) => { type="link" key="metricEditBtn" onClick={() => { - setMetricItem(record); - setCreateModalVisible(true); + history.push(`/model/metric/${record.domainId}/${record.modelId}/${record.id}`); + // setMetricItem(record); + // setCreateModalVisible(true); }} > 编辑 diff --git a/webapp/packages/supersonic-fe/src/pages/SemanticModel/components/DomainList.tsx b/webapp/packages/supersonic-fe/src/pages/SemanticModel/components/DomainList.tsx index d67bdfef4..59306b816 100644 --- a/webapp/packages/supersonic-fe/src/pages/SemanticModel/components/DomainList.tsx +++ b/webapp/packages/supersonic-fe/src/pages/SemanticModel/components/DomainList.tsx @@ -1,14 +1,11 @@ -import { DownOutlined, PlusOutlined, EditOutlined, DeleteOutlined } from '@ant-design/icons'; -import { Input, message, Tree, Popconfirm, Tooltip, Row, Col, Button, Menu } from 'antd'; +import { PlusOutlined, EditOutlined, DeleteOutlined } from '@ant-design/icons'; +import { Input, message, Popconfirm, Tooltip, Row, Col, Button, Menu } from 'antd'; import type { DataNode } from 'antd/lib/tree'; import { useEffect, useState } from 'react'; -import type { FC, Key } from 'react'; +import type { FC } from 'react'; import { useModel } from '@umijs/max'; import { createDomain, updateDomain, deleteDomain } from '../service'; -import { treeParentKeyLists } from '../utils'; import DomainInfoForm from './DomainInfoForm'; -import { constructorClassTreeFromList, addPathInTreeData } from '../utils'; -import { AppstoreOutlined } from '@ant-design/icons'; import styles from './style.less'; import { ISemantic } from '../data'; @@ -42,20 +39,15 @@ const DomainListTree: FC = ({ onTreeSelected, onTreeDataUpdate, }) => { - const [projectTree, setProjectTree] = useState([]); const [projectInfoModalVisible, setProjectInfoModalVisible] = useState(false); const [domainInfoParams, setDomainInfoParams] = useState({}); const [filterValue, setFliterValue] = useState(''); - const [expandedKeys, setExpandedKeys] = useState([]); const [classList, setClassList] = useState([]); const domainModel = useModel('SemanticModel.domainData'); const { selectDomainId, domainList } = domainModel; useEffect(() => { - const treeData = addPathInTreeData(constructorClassTreeFromList(domainList)); - setProjectTree(treeData); setClassList(domainList); - setExpandedKeys(treeParentKeyLists(treeData)); }, [domainList]); const onSearch = (value: any) => { @@ -67,7 +59,7 @@ const DomainListTree: FC = ({ return; } const targetNodeData = classList.filter((item: any) => { - return item.id === selectedKeys; + return `${item.id}` === `${selectedKeys}`; })[0]; onTreeSelected?.(targetNodeData); }; @@ -84,20 +76,6 @@ const DomainListTree: FC = ({ } }; - // const createDefaultModelSet = async (domainId: number) => { - // const { code, msg } = await createDomain({ - // modelType: 'add', - // type: 'normal', - // parentId: domainId, - // name: '默认模型集', - // bizName: `defaultModelSet_${(Math.random() * 1000000).toFixed(0)}`, - // isUnique: 1, - // }); - // if (code !== 200) { - // message.error(msg); - // } - // }; - const domainSubmit = async (values: any) => { if (values.modelType === 'add') { const { code, data } = await createDomain(values); @@ -126,21 +104,19 @@ const DomainListTree: FC = ({ const { id, name, path, hasEditPermission, parentId, hasModel } = node as any; const type = parentId === 0 ? 'top' : 'normal'; return ( -
- { - handleSelect(id); - }} - > - {name} - +
{ + // handleSelect(id); + // }} + > + {name} {createDomainBtnVisible && hasEditPermission && ( {Array.isArray(path) && path.length < 2 && !hasModel && ( { + onClick={(e) => { setDomainInfoParams({ modelType: 'add', type: 'normal', @@ -148,19 +124,21 @@ const DomainListTree: FC = ({ parentName: name, }); setProjectInfoModalVisible(true); + e.stopPropagation(); }} /> )} { + onClick={(e) => { setDomainInfoParams({ modelType: 'edit', type, ...node, }); setProjectInfoModalVisible(true); + e.stopPropagation(); }} /> = ({ okText="是" cancelText="否" > - + { + e.stopPropagation(); + }} + /> )} @@ -180,14 +163,14 @@ const DomainListTree: FC = ({ ); }; - const projectRenderTree = filterValue ? projectTreeFlat(projectTree, filterValue) : projectTree; - - const handleExpand = (_expandedKeys: Key[]) => { - setExpandedKeys(_expandedKeys as string[]); - }; - const items = domainList - .filter((domain) => domain.parentId === 0) + .filter((domain) => { + if (filterValue) { + return domain.parentId === 0 && domain.name.includes(filterValue); + } else { + return domain.parentId === 0; + } + }) .map((domain: ISemantic.IDomainItem) => { return { key: domain.id, @@ -245,6 +228,12 @@ const DomainListTree: FC = ({ className={styles.search} placeholder="请输入名称搜索" onSearch={onSearch} + onChange={(e) => { + const value = e.target.value; + if (!value) { + setFliterValue(value); + } + }} /> {createDomainBtnVisible && ( @@ -265,25 +254,19 @@ const DomainListTree: FC = ({ )}
- - {/* } - defaultExpandAll={true} - treeData={projectRenderTree} - titleRender={titleRender} - /> */} + {selectDomainId && ( + { + handleSelect(info.key); + }} + /> + )} {projectInfoModalVisible && ( void; - onBackDomainBtnClick?: () => void; onMenuChange?: (menuKey: string) => void; }; -const DomainManagerTab: React.FC = ({ - isModel, - activeKey, - modelList, - dataSetList, - handleModelChange, - onBackDomainBtnClick, - onMenuChange, -}) => { +const DomainManagerTab: React.FC = ({ activeKey, onMenuChange }) => { const initState = useRef(false); const defaultTabKey = 'metric'; const domainModel = useModel('SemanticModel.domainData'); const modelModel = useModel('SemanticModel.modelData'); - const { selectDomainId, selectDomainName, selectDomain: domainData } = domainModel; - const { selectModelId, selectModelName } = modelModel; + const { selectDomainId, selectDomain: domainData } = domainModel; + const { selectModelId, modelList } = modelModel; useEffect(() => { initState.current = false; @@ -50,7 +33,7 @@ const DomainManagerTab: React.FC = ({ label: '数据集管理', key: 'overview', hidden: !!domainData?.parentId, - children: , + children: , }, { label: '模型管理', @@ -59,9 +42,9 @@ const DomainManagerTab: React.FC = ({ showModelType === 'list' ? ( { - handleModelChange(model); - }} + // onModelChange={(model) => { + // handleModelChange(model); + // }} /> ) : (
@@ -98,36 +81,9 @@ const DomainManagerTab: React.FC = ({ return item.key !== 'permissonSetting'; }); - const isModelItem = [ - { - label: '指标管理', - key: 'metric', - children: ( - { - if (!initState.current) { - initState.current = true; - onMenuChange?.('dimenstion'); - } - }} - /> - ), - }, - { - label: '维度管理', - key: 'dimenstion', - children: , - }, - { - label: '权限管理', - key: 'permissonSetting', - children: , - }, - ]; - const getActiveKey = () => { const key = activeKey || defaultTabKey; - const tabItems = !isModel ? tabItem : isModelItem; + const tabItems = tabItem; const tabItemsKeys = tabItems.map((item) => item.key); if (!tabItemsKeys.includes(key)) { return tabItemsKeys[0]; @@ -137,47 +93,9 @@ const DomainManagerTab: React.FC = ({ return (
- { - onBackDomainBtnClick?.(); - }} - style={ - selectModelName ? { cursor: 'pointer' } : { color: '#296df3', fontWeight: 'bold' } - } - > - - {selectDomainName} - - ), - }, - { - type: 'separator', - separator: selectModelName ? '/' : '', - }, - { - title: selectModelName ? ( - { - history.push(`/model/${selectDomainId}/${selectModelId}/`); - }} - style={{ color: '#296df3' }} - > - - {selectModelName} - - ) : undefined, - }, - ]} - /> = ({ type="primary" key="console" onClick={() => { - history.replace(`/model/${domainId}/${modelId || metricItem?.modelId}/dataSource`); + history.replace( + `/model/domain/manager/${domainId}/${modelId || metricItem?.modelId}/dataSource`, + ); onCancel?.(); }} > diff --git a/webapp/packages/supersonic-fe/src/pages/SemanticModel/components/ModelManagerTab.tsx b/webapp/packages/supersonic-fe/src/pages/SemanticModel/components/ModelManagerTab.tsx new file mode 100644 index 000000000..be3d39d83 --- /dev/null +++ b/webapp/packages/supersonic-fe/src/pages/SemanticModel/components/ModelManagerTab.tsx @@ -0,0 +1,88 @@ +import { Tabs, Breadcrumb, Space, Radio } from 'antd'; +import React, { useRef, useEffect, useState } from 'react'; +import { history, useModel } from '@umijs/max'; +import ClassDimensionTable from './ClassDimensionTable'; +import ClassMetricTable from './ClassMetricTable'; +import PermissionSection from './Permission/PermissionSection'; +import TagObjectTable from '../Insights/components/TagObjectTable'; +import TermTable from '../components/Term/TermTable'; +import OverView from './OverView'; +import styles from './style.less'; +import { HomeOutlined, FundViewOutlined } from '@ant-design/icons'; +import { ISemantic } from '../data'; +import SemanticGraphCanvas from '../SemanticGraphCanvas'; +import Dimension from '../Dimension'; +import ModelMetric from '../components/ModelMetric'; +import View from '../View'; + +type Props = { + activeKey: string; + modelList: ISemantic.IModelItem[]; + onMenuChange?: (menuKey: string) => void; +}; +const ModelManagerTab: React.FC = ({ activeKey, onMenuChange }) => { + const initState = useRef(false); + const defaultTabKey = 'metric'; + const modelModel = useModel('SemanticModel.modelData'); + + const { selectModelId } = modelModel; + + useEffect(() => { + initState.current = false; + }, [selectModelId]); + + const isModelItem = [ + { + label: '指标管理', + key: 'metric', + // children: , + children: ( + { + if (!initState.current) { + initState.current = true; + onMenuChange?.('dimension'); + } + }} + /> + ), + }, + { + label: '维度管理', + key: 'dimension', + children: , + // children: , + }, + { + label: '权限管理', + key: 'permissonSetting', + children: , + }, + ]; + + const getActiveKey = () => { + const key = activeKey || defaultTabKey; + const tabItems = isModelItem; + const tabItemsKeys = tabItems.map((item) => item.key); + if (!tabItemsKeys.includes(key)) { + return tabItemsKeys[0]; + } + return key; + }; + + return ( +
+ { + onMenuChange?.(menuKey); + }} + /> +
+ ); +}; + +export default ModelManagerTab; diff --git a/webapp/packages/supersonic-fe/src/pages/SemanticModel/components/ModelMetric/index.tsx b/webapp/packages/supersonic-fe/src/pages/SemanticModel/components/ModelMetric/index.tsx new file mode 100644 index 000000000..81dc60372 --- /dev/null +++ b/webapp/packages/supersonic-fe/src/pages/SemanticModel/components/ModelMetric/index.tsx @@ -0,0 +1,12 @@ +import React from 'react'; +import { Outlet } from '@umijs/max'; + +const Dimension: React.FC = () => { + return ( + <> + + + ); +}; + +export default Dimension; diff --git a/webapp/packages/supersonic-fe/src/pages/SemanticModel/components/ModelMetric/style.less b/webapp/packages/supersonic-fe/src/pages/SemanticModel/components/ModelMetric/style.less new file mode 100644 index 000000000..e69de29bb diff --git a/webapp/packages/supersonic-fe/src/pages/SemanticModel/components/ModelTable.tsx b/webapp/packages/supersonic-fe/src/pages/SemanticModel/components/ModelTable.tsx index 1ecd296da..65df43670 100644 --- a/webapp/packages/supersonic-fe/src/pages/SemanticModel/components/ModelTable.tsx +++ b/webapp/packages/supersonic-fe/src/pages/SemanticModel/components/ModelTable.tsx @@ -3,7 +3,7 @@ import { ProTable } from '@ant-design/pro-components'; import { message, Button, Space, Popconfirm, Input } from 'antd'; import React, { useRef, useState, useEffect } from 'react'; import { StatusEnum } from '../enum'; -import { useModel } from '@umijs/max'; +import { useModel, history } from '@umijs/max'; import { deleteModel, batchUpdateModelStatus } from '../service'; import ClassModelTypeModal from './ClassModelTypeModal'; import { ColumnsConfig } from './TableColumnRender'; @@ -22,14 +22,14 @@ const ModelTable: React.FC = ({ modelList, disabledEdit = false, onModelC const domainModel = useModel('SemanticModel.domainData'); const modelModel = useModel('SemanticModel.modelData'); const { selectDomainId } = domainModel; - const { modelTableHistoryParams, setModelTableHistoryParams } = modelModel; + const { modelTableHistoryParams, setModelTableHistoryParams, setSelectModel } = modelModel; const [modelItem, setModelItem] = useState(); const [filterParams, setFilterParams] = useState>({}); const [createDataSourceModalOpen, setCreateDataSourceModalOpen] = useState(false); const [currentPageNumber, setCurrentPageNumber] = useState(1); const actionRef = useRef(); - + const [isEditing, setIsEditing] = useState(false); const [tableData, setTableData] = useState([]); const params = modelTableHistoryParams?.[selectDomainId]; @@ -100,10 +100,14 @@ const ModelTable: React.FC = ({ modelList, disabledEdit = false, onModelC title: '模型名称', search: false, render: (_, record) => { + const { domainId, id } = record; return ( { - onModelChange?.(record); + setSelectModel(record); + + history.push(`/model/domain/manager/${domainId}/${id}`); + // onModelChange?.(record); }} > {_} @@ -161,6 +165,7 @@ const ModelTable: React.FC = ({ modelList, disabledEdit = false, onModelC onClick={() => { setModelItem(record); setCreateDataSourceModalOpen(true); + setIsEditing(true); }} > 编辑 @@ -209,84 +214,88 @@ const ModelTable: React.FC = ({ modelList, disabledEdit = false, onModelC return ( <> - { - return false; - }} - pagination={{ - current: currentPageNumber, - onChange: (pageNumber) => { - setCurrentPageNumber(pageNumber); - dipatchParams({ - ...filterParams, - pageNumber: `${pageNumber}`, - }); - }, - }} - headerTitle={ - { - setCurrentPageNumber(1); - dipatchParams({ - ...filterParams, - key: value, - pageNumber: `1`, - }); - setFilterParams((preState) => { - return { - ...preState, +
+ { + return false; + }} + pagination={{ + current: currentPageNumber, + onChange: (pageNumber) => { + setCurrentPageNumber(pageNumber); + dipatchParams({ + ...filterParams, + pageNumber: `${pageNumber}`, + }); + }, + }} + headerTitle={ + { + setCurrentPageNumber(1); + dipatchParams({ + ...filterParams, key: value, - }; - }); + pageNumber: `1`, + }); + setFilterParams((preState) => { + return { + ...preState, + key: value, + }; + }); + }} + /> + ), + }, + ]} + /> + } + size="small" + options={{ reload: false, density: false, fullScreen: false }} + toolBarRender={() => + disabledEdit + ? [<>] + : [ + , - ] - } - /> + > + 创建模型 + , + ] + } + /> +
{createDataSourceModalOpen && ( { onModelChange?.(); + setIsEditing(false); setCreateDataSourceModalOpen(false); }} onCancel={() => { + setIsEditing(false); setCreateDataSourceModalOpen(false); }} /> diff --git a/webapp/packages/supersonic-fe/src/pages/SemanticModel/components/TableColumnRender.tsx b/webapp/packages/supersonic-fe/src/pages/SemanticModel/components/TableColumnRender.tsx index f592344c4..0a06443cc 100644 --- a/webapp/packages/supersonic-fe/src/pages/SemanticModel/components/TableColumnRender.tsx +++ b/webapp/packages/supersonic-fe/src/pages/SemanticModel/components/TableColumnRender.tsx @@ -6,31 +6,113 @@ import { history } from '@umijs/max'; import { ISemantic } from '../data'; import { isString } from 'lodash'; import dayjs from 'dayjs'; -import { isArrayOfValues } from '@/utils/utils'; +import { isArrayOfValues, replaceRouteParams } from '@/utils/utils'; import styles from './style.less'; import IndicatorStar, { StarType } from '../components/IndicatorStar'; +interface IndicatorInfo { + url?: string; + starType?: StarType; + onNameClick?: (record: ISemantic.IMetricItem) => void | boolean; +} + +interface ColumnsConfigParams { + indicatorInfo?: IndicatorInfo; +} + const { Text, Paragraph } = Typography; -export const ColumnsConfig: any = (params?: { - indicatorInfo?: { - url?: string; - starType?: StarType; - }; -}) => { +export const ColumnsConfig = (params?: ColumnsConfigParams) => { + const renderAliasAndClassifications = ( + alias: string | undefined, + classifications: string[] | undefined, + ) => ( +
+ + {alias && ( + + +
别名:
+ + + {isString(alias) && + alias.split(',').map((aliasName: string) => ( + + + {aliasName} + + + ))} + + +
+ )} + + {isArrayOfValues(classifications) && ( + + +
分类:
+ + + {classifications.map((tag: string) => ( + + + {tag} + + + ))} + + +
+ )} +
+
+ ); + return { description: { - render: (_, record: ISemantic.IMetricItem) => { - const { description } = record; - return ( - - {description} - - ); - }, + render: (_, record: ISemantic.IMetricItem) => ( + + {record.description} + + ), }, dimensionInfo: { render: (_, record: ISemantic.IDimensionItem) => { @@ -45,70 +127,26 @@ export const ColumnsConfig: any = (params?: {
{bizName}
- - {alias && ( -
- - {alias && ( - - -
别名:
- - - {isString(alias) && - alias.split(',').map((aliasName: string) => { - return ( - - - {aliasName} - - - ); - })} - - -
- )} -
-
- )} + {renderAliasAndClassifications(alias, undefined)} ); }, }, indicatorInfo: { render: (_, record: ISemantic.IMetricItem) => { - const { name, alias, bizName, classifications, id, isCollect } = record; + const { name, alias, bizName, classifications, id, isCollect, domainId, modelId } = record; + let url = `/metric/detail/`; let starType: StarType = 'metric'; - if (params) { - if (params?.indicatorInfo?.url) { - url = params.indicatorInfo.url; - } - if (params?.indicatorInfo?.starType) { - starType = params.indicatorInfo.starType; - } + if (params?.indicatorInfo) { + url = replaceRouteParams(params.indicatorInfo.url || '', { + domainId: `${domainId}`, + modelId: `${modelId}`, + indicatorId: `${id}`, + }); + starType = params.indicatorInfo.starType || 'metric'; } + return ( <>
{bizName}
- - {(alias || isArrayOfValues(classifications)) && ( -
- - {alias && ( - - -
别名:
- - - {isString(alias) && - alias.split(',').map((aliasName: string) => { - return ( - - - {aliasName} - - - ); - })} - - -
- )} - - {isArrayOfValues(classifications) && ( - - -
分类:
- - - {classifications.map((tag: string) => { - return ( - - - {tag} - - - ); - })} - - -
- )} - {/* - - - : - {id} - - - - : - {createdBy} - - */} -
-
- )} + {renderAliasAndClassifications(alias, classifications)} ); }, }, sensitiveLevel: { - render: (_, record: ISemantic.IMetricItem) => { - const { sensitiveLevel } = record; - return SENSITIVE_LEVEL_COLOR[sensitiveLevel] ? ( - - {SENSITIVE_LEVEL_ENUM[sensitiveLevel]} - - ) : ( - - 未知 - - ); - }, + render: (_, record: ISemantic.IMetricItem) => ( + + {SENSITIVE_LEVEL_ENUM[record.sensitiveLevel] || '未知'} + + ), }, state: { render: (status) => { - let tagProps: { color: string; label: string; style?: any } = { + const tagProps = { color: 'default', label: '未知', style: {}, }; switch (status) { case StatusEnum.ONLINE: - tagProps = { - // color: 'processing', - color: 'geekblue', - label: '已启用', - }; + tagProps.color = 'geekblue'; + tagProps.label = '已启用'; break; case StatusEnum.OFFLINE: - tagProps = { - color: 'default', - label: '未启用', - style: { - color: 'rgb(95, 116, 141)', - fontWeight: 400, - }, - }; + tagProps.color = 'default'; + tagProps.label = '未启用'; + tagProps.style = { color: 'rgb(95, 116, 141)', fontWeight: 400 }; break; case StatusEnum.INITIALIZED: - tagProps = { - color: 'processing', - label: '初始化', - }; + tagProps.color = 'processing'; + tagProps.label = '初始化'; break; case StatusEnum.DELETED: - tagProps = { - color: 'default', - label: '已删除', - }; + tagProps.color = 'default'; + tagProps.label = '已删除'; break; case StatusEnum.UNAVAILABLE: - tagProps = { - color: 'default', - label: '不可用', - }; + tagProps.color = 'default'; + tagProps.label = '不可用'; break; default: break; @@ -339,14 +247,12 @@ export const ColumnsConfig: any = (params?: { tooltip: '创建人/更新时间', width: 180, search: false, - render: (value: any, record: ISemantic.IMetricItem) => { - return ( - - {record.createdBy} - {value && value !== '-' ? dayjs(value).format('YYYY-MM-DD HH:mm:ss') : '-'} - - ); - }, + render: (value: any, record: ISemantic.IMetricItem) => ( + + {record.createdBy} + {value && value !== '-' ? dayjs(value).format('YYYY-MM-DD HH:mm:ss') : '-'} + + ), }, }; }; diff --git a/webapp/packages/supersonic-fe/src/pages/SemanticModel/components/style.less b/webapp/packages/supersonic-fe/src/pages/SemanticModel/components/style.less index 96527bfae..e5e32db88 100644 --- a/webapp/packages/supersonic-fe/src/pages/SemanticModel/components/style.less +++ b/webapp/packages/supersonic-fe/src/pages/SemanticModel/components/style.less @@ -6,6 +6,7 @@ .projectManger { + border-top: 1px solid #eee; width: 100%; min-height: calc(100vh - 56px); background-color: #fff; @@ -163,8 +164,8 @@ // } // } .tab { - border-top: 1px solid #eee; - margin-top: 10px; + + // margin-top: 10px; :global { .ant-tabs-tab-btn { font-size: 16px; @@ -338,12 +339,14 @@ .breadcrumb{ font-size: 18px; - margin: 17px 0 0 20px; - padding-bottom: 3px; + height: 48px; + line-height: 48px; + padding: 0 20px; :global { .ant-breadcrumb-link { height: 28px; color: #709bf1; + cursor: pointer; &:hover{ color: #296df3; } @@ -351,6 +354,14 @@ .anticon { font-size: 18px; } + li { + &:last-child { + .ant-breadcrumb-link { + color: #296df3; + } + + } + } } } diff --git a/webapp/packages/supersonic-fe/src/pages/SemanticModel/index.tsx b/webapp/packages/supersonic-fe/src/pages/SemanticModel/index.tsx index 01f7068a0..0390e30ae 100644 --- a/webapp/packages/supersonic-fe/src/pages/SemanticModel/index.tsx +++ b/webapp/packages/supersonic-fe/src/pages/SemanticModel/index.tsx @@ -1,7 +1,89 @@ -import React from 'react'; +import { message } from 'antd'; +import React, { useEffect, useState } from 'react'; +import { history, useParams, useModel, Outlet } from '@umijs/max'; +import DomainListTree from './components/DomainList'; +import styles from './components/style.less'; +import { LeftOutlined, RightOutlined } from '@ant-design/icons'; +import { ISemantic } from './data'; +import { getDomainList, getDataSetList, getModelDetail } from './service'; +import PageBreadcrumb from './PageBreadcrumb'; -const classManager: React.FC = ({ children }) => { - return
{children}
; +type Props = {}; + +const SemanticModel: React.FC = ({}) => { + const params: any = useParams(); + const domainId = params.domainId; + const modelId = params.modelId; + const domainModel = useModel('SemanticModel.domainData'); + const modelModel = useModel('SemanticModel.modelData'); + const databaseModel = useModel('SemanticModel.databaseData'); + const metricModel = useModel('SemanticModel.metricData'); + const { setSelectDomain, setDomainList, selectDomainId } = domainModel; + const { selectModel, setSelectModel, setModelTableHistoryParams, MrefreshModelList } = modelModel; + const { MrefreshDatabaseList } = databaseModel; + + const { selectMetric, setSelectMetric } = metricModel; + + const initSelectedDomain = (domainList: ISemantic.IDomainItem[]) => { + const targetNode = domainList.filter((item: any) => { + return `${item.id}` === domainId; + })[0]; + if (!targetNode) { + const firstRootNode = domainList.filter((item: any) => { + return item.parentId === 0; + })[0]; + if (firstRootNode) { + const { id } = firstRootNode; + setSelectDomain(firstRootNode); + // pushUrlMenu(id, menuKey); + } + } else { + setSelectDomain(targetNode); + } + }; + + const initProjectTree = async () => { + const { code, data, msg } = await getDomainList(); + if (code === 200) { + initSelectedDomain(data); + setDomainList(data); + } else { + message.error(msg); + } + }; + + const initModelData = async () => { + const { code, data, msg } = await getModelDetail({ modelId }); + if (code === 200) { + setSelectModel(data); + } else { + message.error(msg); + } + }; + + useEffect(() => { + initProjectTree(); + MrefreshDatabaseList(); + if (modelId && modelId !== selectModel) { + initModelData(); + } + + return () => { + setSelectDomain(undefined); + }; + }, []); + + return ( +
+
+ +
+
+ + {/* */} +
+
+ ); }; -export default classManager; +export default SemanticModel; diff --git a/webapp/packages/supersonic-fe/src/pages/SemanticModel/models/metricData.ts b/webapp/packages/supersonic-fe/src/pages/SemanticModel/models/metricData.ts index caab8b12e..29123730c 100644 --- a/webapp/packages/supersonic-fe/src/pages/SemanticModel/models/metricData.ts +++ b/webapp/packages/supersonic-fe/src/pages/SemanticModel/models/metricData.ts @@ -5,6 +5,7 @@ import { queryMetric } from '../service'; export default function Metric() { const [metricList, setMetricList] = useState([]); + const [selectMetric, setSelectMetric] = useState(); const queryMetricList = async (params: any) => { const { code, data, msg } = await queryMetric({ @@ -25,6 +26,8 @@ export default function Metric() { return { MmetricList: metricList, + setSelectMetric: setSelectMetric, + selectMetric: selectMetric, MrefreshMetricList: refreshMetricList, MqueryMetricList: queryMetricList, }; diff --git a/webapp/packages/supersonic-fe/src/pages/SemanticModel/service.ts b/webapp/packages/supersonic-fe/src/pages/SemanticModel/service.ts index 230ce74dc..c36de3f6c 100644 --- a/webapp/packages/supersonic-fe/src/pages/SemanticModel/service.ts +++ b/webapp/packages/supersonic-fe/src/pages/SemanticModel/service.ts @@ -453,7 +453,7 @@ export function getUnAvailableItem(data: any): Promise { export function getModelDetail(data: any): Promise { if (!data.modelId) { - return; + return {}; } return request.get(`${process.env.API_BASE_URL}model/getModel/${data.modelId}`); } diff --git a/webapp/packages/supersonic-fe/src/utils/utils.ts b/webapp/packages/supersonic-fe/src/utils/utils.ts index bf48da88f..e327acc85 100644 --- a/webapp/packages/supersonic-fe/src/utils/utils.ts +++ b/webapp/packages/supersonic-fe/src/utils/utils.ts @@ -502,3 +502,10 @@ export function decryptPassword(encryptPassword: string) { export function uniqueArray(arr: any[]) { return Array.from(new Set(arr)); } + +// 替换以:开头标记的变量 +export const replaceRouteParams = (template: string, values: Record): string => { + return template.replace(/:([a-zA-Z0-9_]+)/g, (match, key) => { + return values[key] !== undefined ? values[key] : match; + }); +};