oralce分類統計
14883 ワード
@Transactional
@Component("statisDAO")
@Scope("prototype")
public class StatisDAO extends AbstractDAO {
private static final String SQL_STATIS_CHANNELTYPE = "INSERT INTO channeltypestatis(uuid,counter,channeltype,accountarea,statistime,statisrange) " +
"SELECT DBMS_RANDOM.STRING('A', 32) AS uuid, count(*) AS counter, channeltype, accountarea,sysdate AS statistime,to_char(?)||'/'||to_char(?) AS STATISRANGE " +
"FROM ACTIVITY WHERE txtime>=? AND txtime<=? GROUP BY ROLLUP (channeltype,accountarea)";
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public boolean statisChanneltype(String startDateStr,String endDateStr) {
try {
DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date startDate=format.parse(startDateStr+" 00:00:00");
Date endDate=format.parse(endDateStr+" 23:59:59");
Object[] values = {startDateStr,endDateStr,startDate,endDate};
this.getSmartDAO().update("", SQL_STATIS_CHANNELTYPE, values);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public static void main(String[] args) {
ApplicationContext applicationContext = new FileSystemXmlApplicationContext("file:E:\\CommonContext.xml");
StatisDAO statisDAO = (StatisDAO) applicationContext.getBean("statisDAO");
System.out.println(statisDAO.statisChanneltype("2011-04-01", "2011-08-02"));
}
}
時間:
各期間のエントリ数を統計します.txtimeはdateタイプで、sqlは次のようになります.
時間別---select to_char(txtime, 'YYYY-MM-dd hh24') a,count(*) from mytable group by to_char(txtime,'YYYY-MM-dd hh24');
日を押す---select to_char(txtime, 'YYYY-MM-dd') a,count(*) from mytable group by to_char(txtime,'YYYY-MM-dd');
月別---select to_char(txtime, 'YYYY-MM') a,count(*) from mytable group by to_char(txtime,'YYYY-MM');
年ごと---select to_char(txtime, 'YYYY') a,count(*) from mytable group by to_char(txtime,'YYYY');
四半期別---select to_char(txtime, 'YYYY-q') a,count(*) from mytable group by to_char(txtime,'YYYY-q');
週別---select to_char(txtime, 'ww') a,count(*) from mytable group by to_char(txtime,'ww');
参照http://hi.baidu.com/qq5910225/blog/item/4a8c91d7ef0ec514a08bb74e.html
同じ文字列タイプの統計値
select SUM(CASEWHEN city='海口市'THEN 1 ELSE 0 END)haikou_num,SUM(CASEWHEN city='広州市'THEN 1 ELSE 0 END)guangzhou_numFROM ACTIVITY_HIS
decode方式
SQL> select id,num from test1; ID NUM-----------------1 3 3 1 4 2 5 3 1 3 8 6 rows selected SQL>select decode(grouping(id)、1,'合計',id)id,sum(num)num 2 from test 1 3 group by rollup(id);ID NUM----------------------------------------------------1 7 2 7 3 9合計23
最終大神:select count(*)、province,city from ACTIVITY_HIS where to_char(txtime, 'YYYY-MM-dd')='2011-06-01' group by rollup (province,city);
rollupはデータマイニングにおける上巻操作であり、実行効果のスクリーンショットである.
また、取り出したデータを直接テーブルに挿入します.
select ...intoはストレージプロセスに使用され、変数insertを保存します.selectは挿入文で、挿入された部分はテーブルのデータです.
例として、
Insertテーブルselect*fromテーブルの方法は主に2つあります:1、2つのテーブルが完全に同じである場合:insert into table 1 select*from table 2 where condition(条件)2、2つのテーブルフィールドが異なる場合:insert into table 1(フィールド1、フィールド2、フィールド3...)selectフィールド1、フィールド2、フィールド3....from table 2 where condition(条件)上記の2つの方法はvaluesを書く必要はない.
以上、私のsqlは:
INSERT INTO channeltypestatis(uuid,counter,channeltype,accountarea,statistime,statisrange)
SELECT DBMS_RANDOM.STRING('A', 32) AS uuid, count(*) AS counter, channeltype, accountarea,sysdate AS statistime,TO_CHAR(?,'yyyy-mm-dd') AS STATISRANGE
FROM ACTIVITY
WHERE where to_char(txtime, 'yyyy-mm-dd')>'?' AND TO_CHAR(txtime, 'yyyy-mm-dd')<'?'
GROUP BY ROLLUP (channeltype,accountarea)
channeltypestatisデータ辞書:
CHANNELTYPESTATIS UUID VARCHAR2CHANNELTYPESTATIS COUNTER NUMBERCHANNELTYPESTATIS CHANNELTYPE VARCHAR2CHANNELTYPESTATIS ACCOUNTAREA VARCHAR2CHANNELTYPESTATIS STATISTIME DATECHANNELTYPESTATIS STATISRANGE VARCHAR2
作成中に問題があります.
コードクリップ
@Transactional
@Component("statisDAO")
@Scope("prototype")
public class StatisDAO extends AbstractDAO {
private static final String SQL_STATIS_CHANNELTYPE = "INSERT INTO channeltypestatis(uuid,counter,channeltype,accountarea,statistime,statisrange) SELECT DBMS_RANDOM.STRING('A', 32) AS uuid, count(*) AS counter, channeltype, accountarea,sysdate AS statistime,TO_CHAR(?/?) AS STATISRANGE FROM ACTIVITY WHERE txtime>=to_date(?, 'yyyy-mm-dd') AND txtime<=to_date(?, 'yyyy-mm-dd') GROUP BY ROLLUP (channeltype,accountarea)";
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public boolean statisChanneltype(String startDate,String endDate) {
try {
Object[] values = {startDate,endDate,startDate,endDate};
this.getSmartDAO().update("", SQL_STATIS_CHANNELTYPE, values);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public static void main(String[] args) {
ApplicationContext applicationContext = new FileSystemXmlApplicationContext("file:E:\\CommonContext.xml");
StatisDAO statisDAO = (StatisDAO) applicationContext.getBean("statisDAO");
System.out.println(statisDAO.statisChanneltype("2011-04-01", "2011-08-02"));
}
}
レポートが無効なカラムインデックスの場合、sql文のためですか?以上のようにしてはいけない
しかし、上記のコードは依然としてエラーを報告しています.エラーのデジタルフォーマットは、私が2011-08-02パラメータを伝えたとき、sqlを解析すると、エラーが発生し、最終的に以下のフォーマットに変更されました.
@Transactional
@Component("statisDAO")
@Scope("prototype")
public class StatisDAO extends AbstractDAO {
private static final String SQL_STATIS_CHANNELTYPE = "INSERT INTO channeltypestatis(uuid,counter,channeltype,accountarea,statistime,statisrange) SELECT DBMS_RANDOM.STRING('A', 32) AS uuid, count(*) AS counter, channeltype, accountarea,sysdate AS statistime,TO_CHAR(?-?) AS STATISRANGE FROM ACTIVITY WHERE txtime>=to_date(?, 'yyyymmdd') AND txtime<=to_date(?, 'yyyymmdd') GROUP BY ROLLUP (channeltype,accountarea)";
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public boolean statisChanneltype(String startDate,String endDate) {
try {
Object[] values = {startDate,endDate,startDate,endDate};
this.getSmartDAO().update("", SQL_STATIS_CHANNELTYPE, values);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public static void main(String[] args) {
ApplicationContext applicationContext = new FileSystemXmlApplicationContext("file:E:\\CommonContext.xml");
StatisDAO statisDAO = (StatisDAO) applicationContext.getBean("statisDAO");
System.out.println(statisDAO.statisChanneltype("20110401", "20110802"));
}
}
でもTO_CHAR(?-?) この関数は数学記号に解析してくれた後、NNDを全部減算してくれたので、oracleの文字列でつなぎ合わせるべきだ.その他の一般的なoracle関数は次の編を参照してください.
つなぎ合わせることがあって、また時間に注意しなければならなくて、前のは当日の検索を満たすことができません
@Transactional
@Component("statisDAO")
@Scope("prototype")
public class StatisDAO extends AbstractDAO {
private static final String SQL_STATIS_CHANNELTYPE = "INSERT INTO channeltypestatis(uuid,counter,channeltype,accountarea,statistime,statisrange) " +
"SELECT DBMS_RANDOM.STRING('A', 32) AS uuid, count(*) AS counter, channeltype, accountarea,sysdate AS statistime,to_char(?)||'/'||to_char(?) AS STATISRANGE " +
"FROM ACTIVITY WHERE txtime>=? AND txtime<=? GROUP BY ROLLUP (channeltype,accountarea)";
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public boolean statisChanneltype(String startDateStr,String endDateStr) {
try {
DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date startDate=format.parse(startDateStr+" 00:00:00");
Date endDate=format.parse(endDateStr+" 23:59:59");
Object[] values = {startDateStr,endDateStr,startDate,endDate};
this.getSmartDAO().update("", SQL_STATIS_CHANNELTYPE, values);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public static void main(String[] args) {
ApplicationContext applicationContext = new FileSystemXmlApplicationContext("file:E:\\CommonContext.xml");
StatisDAO statisDAO = (StatisDAO) applicationContext.getBean("statisDAO");
System.out.println(statisDAO.statisChanneltype("2011-08-01", "2011-08-01"));
}
}
ただし上記sql文はSELECT DBMS_RANDOM.STRING('A',32)乱数の場合、これは同じである可能性があるのでsequenceを使用する必要がありますが、sequenceとgroupbyを一緒に使用するとエラーが発生します.ORA-02287:ここではシーケンス番号は許可されていません.
INSERT INTO channeltypestatis(uuid,counter,channeltype,accountarea,statistime,statisrange)
SELECT SEQ_PK.nextVal as uuid , count(*) AS counter, channeltype, accountarea,sysdate AS statistime,to_char('2011-08-01')||'/'||to_char('2011-08-01') AS STATISRANGE FROM ACTIVITY
WHERE txtime>=to_date('2011-08-01 00:00:00','yyyy-mm-dd hh24:mi:ss') AND txtime<=to_date('2011-08-01 23:59:59','yyyy-mm-dd hh24:mi:ss') GROUP BY ROLLUP (channeltype,accountarea)
エラー:oracle sequence ORA-02287:ここではシーケンス番号は許可されていません
採用する
INSERT INTO channeltypestatis(uuid,counter,channeltype,accountarea,statistime,statisrange)
SELECT SEQ_PK.nextVal as uuid , P.* from
(select count(*) AS counter, channeltype, accountarea,sysdate AS statistime,to_char('2011-08-01')||'/'||to_char('2011-08-01') AS STATISRANGE
FROM ACTIVITY WHERE txtime>=to_date('2011-08-01 00:00:00','yyyy-mm-dd hh24:mi:ss') AND txtime<=to_date('2011-08-01 23:59:59','yyyy-mm-dd hh24:mi:ss') GROUP BY ROLLUP (channeltype,accountarea)) P
使用すればよい
最終コード:
@Transactional
@Component("statisDAO")
@Scope("prototype")
public class StatisDAO extends AbstractDAO {
private static final String SQL_STATIS_CHANNELTYPE ="INSERT INTO channeltypestatis(uuid,counter,channeltype,accountarea,statistime,statisrange) " +
"SELECT SEQ_PK.nextVal as uuid , P.* from " +
"(select count(*) AS counter, channeltype, accountarea,sysdate AS statistime,to_char(?)||'/'||to_char(?) AS STATISRANGE " +
"FROM ACTIVITY WHERE txtime>=? AND txtime<=? " +
"GROUP BY ROLLUP (channeltype,accountarea)) P";
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public boolean statisChanneltype(String startDateStr,String endDateStr) {
try {
DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date startDate=format.parse(startDateStr+" 00:00:00");
Date endDate=format.parse(endDateStr+" 23:59:59");
Object[] values = {startDateStr,endDateStr,startDate,endDate};
this.getSmartDAO().update("", SQL_STATIS_CHANNELTYPE, values);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
}
ああ、また新しい問題が現れて、rollupで統計を行う時、もし元のデータの中にnullがあるならば、すべての時それは統計してもnullで、そこで杯具になって、最初の図のようで、検索を経て
上記のsqlを
INSERT INTO channeltypestatis(uuid,counter,channeltype,accountarea,statistime,statisrange)
SELECT SEQ_PK_CHANNELTYPESTATIS.nextVal as uuid , P.* from
(select count(*) AS counter, Decode(Grouping(channeltype),1,' ',channeltype) channeltype,Decode(Grouping(accountarea),1,' ',accountarea) accountarea,sysdate AS statistime,to_char('2011-08-01')||'/'||to_char('2011-08-01') AS STATISRANGE
FROM ACTIVITY WHERE txtime>=to_date('2011-08-01 00:00:00','yyyy-mm-dd hh24:mi:ss') AND txtime<=to_date('2011-08-01 23:59:59','yyyy-mm-dd hh24:mi:ss') GROUP BY ROLLUP (channeltype,accountarea)) P
検索結果を図2に示す
問題はまだあります:accountarea区域は合計することができなくて、北京のall値を求めることができなくて、そのためsqlは再び
INSERT INTO channeltypestatis(uuid,counter,channeltype,accountarea,statistime,statisrange)
SELECT SEQ_PK_CHANNELTYPESTATIS.nextVal AS uuid , P.* FROM
(SELECT count(*) AS counter, Decode(Grouping(channeltype),1,'ALL',channeltype) channeltype,Decode(Grouping(accountarea),1,'ALL',accountarea) accountarea,sysdate AS statistime,to_char('2011-08-01')||'/'||to_char('2011-08-01') AS STATISRANGE
FROM activity WHERE txtime>=to_date('2011-04-01','yyyy-mm-dd') AND txtime<=to_date('2011-08-01','yyyy-mm-dd')
GROUP BY CUBE (channeltype,accountarea)) P
注意rollupをcubeに変更すればよいので、cubeとrollupの違いについては以下を参照してください.
http://space.itpub.net/519536/viewspace-610997