从组合字符串中获取组最大值

时间:2017-02-23 09:10:13

标签: sql postgresql aggregate greatest-n-per-group string-parsing

我有一个包含列code的表,其中包含多个数据:

001/2017/TT/000001
001/2017/TT/000002
001/2017/TN/000003
001/2017/TN/000001
001/2017/TN/000002
001/2016/TT/000001
001/2016/TT/000002
001/2016/TT/000001
002/2016/TT/000002

001/2016/TT/000001中有4个项目:0012016TT000001
如何为前3个项目形成的每个组提取最大值?我想要的结果是:

001/2017/TT/000003
001/2017/TN/000002
001/2016/TT/000002
002/2016/TT/000002

修改

  • 子字段分隔符为/,子字段的长度可能会有所不同。
  • 我使用PostgreSQL 9.3。

3 个答案:

答案 0 :(得分:1)

使用LEFTRIGHT功能。

SELECT MAX(RIGHT(code,6)) AS MAX_CODE
FROM yourtable
GROUP BY LEFT(code,12)

答案 1 :(得分:1)

显然,您应该规范化表并将组合后的字符串拆分为具有适当数据类型的4列。如果分隔符'/'在字符串中是常量且长度可以变化,则函数split_part()是首选工具。

CREATE TABLE tbl_better AS 
SELECT split_part(code, '/', 1)::int AS col_1  -- better names?
     , split_part(code, '/', 2)::int AS col_2
     , split_part(code, '/', 3)      AS col_3  -- text?
     , split_part(code, '/', 4)::int AS col_4
FROM   tbl_bad
ORDER  BY 1,2,3,4  -- optionally cluster data.

然后这项任务很简单:

SELECT col_1, col_2, col_3, max(col_4) AS max_nr
FROM   tbl_better
GROUP  BY 1, 2, 3;

相关:

当然,你也可以动态地做。对于不同的子字段长度,您可以将substring()与正则表达式一起使用,如下所示:

SELECT max(substring(code, '([^/]*)$')) AS max_nr
FROM   tbl_bad
GROUP  BY substring(code, '^(.*)/');

相关(正则表达式的基本解释):

或者只获得完整的字符串:

SELECT DISTINCT ON (substring(code, '^(.*)/'))
       code
FROM   tbl_bad
ORDER  BY substring(code, '^(.*)/'), code DESC;

关于DISTINCT ON

请注意,投射到合适类型的数据项可能与其字符串表示形式不同。 9000011000001的最大值为900001的{​​{1}}和text的{​​{1}} ...

答案 2 :(得分:0)

检查一下,可能有帮助

class YourClass
{

   private static $base_url = 'http://localhost/projects/';
   private static $key = 'your_key';
   private static $secret = 'your_secret';

   public static function yourMethodName($id = '', $fields = '', $is_return_transfer = 0)
   {

      if (is_array($fields))
      {
         $fields_str = http_build_query($fields, '', '&');
      } else
      {
         $fields_str = $fields;
      }
      $fields_str = $fields_str . "&key=" . self::$key . "&secret=" . self::$secret;
      $id_str = ($id != '') ? "/$id" : "";
      $url = self::$base_url . $id_str;

      $ch = curl_init();
      curl_setopt($ch, CURLOPT_URL, $url);
      curl_setopt($ch, CURLOPT_POST, count($fields));
      curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_str);
      if ($is_return_transfer == 1)
      {
         curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
      }
      $result = curl_exec($ch);
      curl_close($ch);
      return $result;
   }

}