草庐IT

【SQL开发实战技巧】系列(三十六):数仓报表场景☞整理垃圾数据:查找数据的连续性时间和重叠时间的关系,初始化开始结束时间

赵延东的一亩三分地 2023-10-07 原文

系列文章目录

【SQL开发实战技巧】系列(一):关于SQL不得不说的那些事
【SQL开发实战技巧】系列(二):简单单表查询
【SQL开发实战技巧】系列(三):SQL排序的那些事
【SQL开发实战技巧】系列(四):从执行计划讨论UNION ALL与空字符串&UNION与OR的使用注意事项
【SQL开发实战技巧】系列(五):从执行计划看IN、EXISTS 和 INNER JOIN效率,我们要分场景不要死记网上结论
【SQL开发实战技巧】系列(六):从执行计划看NOT IN、NOT EXISTS 和 LEFT JOIN效率,记住内外关联条件不要乱放
【SQL开发实战技巧】系列(七):从有重复数据前提下如何比较出两个表中的差异数据及对应条数聊起
【SQL开发实战技巧】系列(八):聊聊如何插入数据时比约束更灵活的限制数据插入以及怎么一个insert语句同时插入多张表
【SQL开发实战技巧】系列(九):一个update误把其他列数据更新成空了?Merge改写update!给你五种删除重复数据的写法!
【SQL开发实战技巧】系列(十):从拆分字符串、替换字符串以及统计字符串出现次数说起
【SQL开发实战技巧】系列(十一):拿几个案例讲讲translate|regexp_replace|listagg|wmsys.wm_concat|substr|regexp_substr常用函数
【SQL开发实战技巧】系列(十二):三问(如何对字符串字母去重后按字母顺序排列字符串?如何识别哪些字符串中包含数字?如何将分隔数据转换为多值IN列表?)
【SQL开发实战技巧】系列(十三):讨论一下常用聚集函数&通过执行计划看sum()over()对员工工资进行累加
【SQL开发实战技巧】系列(十四):计算消费后的余额&计算银行流水累计和&计算各部门工资排名前三位的员工
【SQL开发实战技巧】系列(十五):查找最值所在行数据信息及快速计算总和百之max/min() keep() over()、fisrt_value、last_value、ratio_to_report
【SQL开发实战技巧】系列(十六):数据仓库中时间类型操作(初级)日、月、年、时、分、秒之差及时间间隔计算
【SQL开发实战技巧】系列(十七):数据仓库中时间类型操作(初级)确定两个日期之间的工作天数、计算—年中周内各日期出现次数、确定当前记录和下一条记录之间相差的天数
【SQL开发实战技巧】系列(十八):数据仓库中时间类型操作(进阶)INTERVAL、EXTRACT以及如何确定一年是否为闰年及周的计算
【SQL开发实战技巧】系列(十九):数据仓库中时间类型操作(进阶)如何一个SQL打印当月或一年的日历?如何确定某月内第一个和最后—个周内某天的日期?
【SQL开发实战技巧】系列(二十):数据仓库中时间类型操作(进阶)获取季度开始结束时间以及如何统计非连续性时间的数据
【SQL开发实战技巧】系列(二十一):数据仓库中时间类型操作(进阶)识别重叠的日期范围,按指定10分钟时间间隔汇总数据
【SQL开发实战技巧】系列(二十二):数仓报表场景☞ 从分析函数效率一定快吗聊一聊结果集分页和隔行抽样实现方式
【SQL开发实战技巧】系列(二十三):数仓报表场景☞ 如何对数据排列组合去重以及通过如何找到包含最大值和最小值的记录这个问题再次用执行计划给你证明分析函数性能不一定高
【SQL开发实战技巧】系列(二十四):数仓报表场景☞通过案例执行计划详解”行转列”,”列转行”是如何实现的
【SQL开发实战技巧】系列(二十五):数仓报表场景☞结果集中的重复数据只显示一次以及计算部门薪资差异高效的写法以及如何对数据进行快速分组
【SQL开发实战技巧】系列(二十六):数仓报表场景☞聊聊ROLLUP、UNION ALL是如何分别做分组合计的以及如何识别哪些行是做汇总的结果行
【SQL开发实战技巧】系列(二十七):数仓报表场景☞通过对移动范围进行聚集来详解分析函数开窗原理以及如何一个SQL打印九九乘法表
【SQL开发实战技巧】系列(二十八):数仓报表场景☞人员分布问题以及不同组(分区)同时聚集如何实现
【SQL开发实战技巧】系列(二十九):数仓报表场景☞简单的树形(分层)查询以及如何确定根节点、分支节点和叶子节点
【SQL开发实战技巧】系列(三十):数仓报表场景☞树形(分层)查询如何排序?以及如何在树形查询中正确的使用where条件
【SQL开发实战技巧】系列(三十一):数仓报表场景☞分层查询如何只查询树形结构某一个分支?如何剪掉一个分支?
【SQL开发实战技巧】系列(三十二):数仓报表场景☞对表中某个字段内的值去重
【SQL开发实战技巧】系列(三十三):数仓报表场景☞从不固定位置提取字符串的元素以及搜索满足字母在前数字在后等条件的数据
【SQL开发实战技巧】系列(三十四):数仓报表场景☞如何对数据分级并行转为列
【SQL开发实战技巧】系列(三十五):数仓报表场景☞根据条件返回不同列的数据以及Left /Full Join注意事项
【SQL开发实战技巧】系列(三十六):数仓报表场景☞整理垃圾数据:查找数据的连续性时间和重叠时间的关系,初始化开始结束时间


文章目录


前言

本篇文章讲解的主要内容是:从整理人员签到信息记录表的垃圾数据来再次体会一下隐藏数据列信息以及查找数据的连续性时间和重叠时间的实战案例
【SQL开发实战技巧】这一系列博主当作复习旧知识来进行写作,毕竟SQL开发在数据分析场景非常重要且基础,面试也会经常问SQL开发和调优经验,相信当我写完这一系列文章,也能再有所收获,未来面对SQL面试也能游刃有余~。


一、整理垃圾数据:查找数据的连续性时间和重叠时间的关系,初始化开始结束时间

现在有下面一堆脏数据,是人员签到信息记录表,如下:

CREATE OR REPLACE VIEW people(人员编号,开始时间,结束时间,类型,数值id)AS
SELECT 11, to_date('201305', 'yyyymm'), to_date('201308', 'yyyymm'), 1, 1
  FROM dual
UNION ALL
SELECT 11, to_date('201307', 'yyyymm'), NULL, 1, 2
  FROM dual
UNION ALL
SELECT 11, to_date('201301', 'yyyymm'), NULL, -1, 3
  FROM dual
UNION ALL
SELECT 11, to_date('201312', 'yyyymm'), NULL, 1, 4
  FROM dual
UNION ALL
SELECT 22, to_date('201305', 'yyyymm'), to_date('201306', 'yyyymm'), 1, 1
  FROM dual
UNION ALL
SELECT 22, to_date('201308', 'yyyymm'), to_date('201309', 'yyyymm'), 1, 2
  FROM dual
UNION ALL
SELECT 22, to_date('201312', 'yyyymm'), to_date('201312', 'yyyymm'), -1, 3
  FROM dual
UNION ALL
SELECT 22, to_date('201403', 'yyyymm'), NULL, 1, 4
  FROM dual
UNION ALL
SELECT 22, to_date('201405', 'yyyymm'), NULL, -1, 4
  FROM dual
UNION ALL
SELECT 33, to_date('201305', 'yyyymm'), to_date('201305', 'yyyymm'), 1, 1
  FROM dual
UNION ALL
SELECT 33, to_date('201307', 'yyyymm'), to_date('201307', 'yyyymm'), 1, 2
  from dual
union all
SELECT 33, to_date('201310', 'yyyymm'), NULL, -1, 3
  FROM dual
UNION ALL
SELECT 33, to_date('201312', 'yyyymm'), NULL, 1, 4
  FROM dual;
SQL> select *from people;

      人员编号 开始时间    结束时间            类型       数值ID
---------- ----------- ----------- ---------- ----------
        11 2013-5-1    2013-8-1             1          1
        11 2013-7-1                         1          2
        11 2013-1-1                        -1          3
        11 2013-12-1                        1          4
        22 2013-5-1    2013-6-1             1          1
        22 2013-8-1    2013-9-1             1          2
        22 2013-12-1   2013-12-1           -1          3
        22 2014-3-1                         1          4
        22 2014-5-1                        -1          4
        33 2013-5-1    2013-5-1             1          1
        33 2013-7-1    2013-7-1             1          2
        33 2013-10-1                       -1          3
        33 2013-12-1                        1          4

13 rows selected

上面的数据是杂乱的,要求清洗上面数据,得到如下数据:

人员编号 区间
---------- ----------- 
11	201312--NULL
22	201305--201306
22	201308--201309
22	201403--201404
33	201305--201305
33	201307--201307
33	201312--NULL

由于上面数据质量不高,现在提出数据清洗规则需求如下:
1、当类型为"-1"时,数据丢弃。
2、当类型为"-1",且其前一行"结束时间"为空值时,"开始时间-1"当作其前一行的结束时间。
3、如果后面的时间比前面的时间早,则覆盖前面的时间,不能覆盖的时间要保留。
4、时段重叠的要合并为一行。
数据乱,需求也就复杂。
首先要取出对应的数据,刚开始写语句时可能不知道从何下手,没关系,我们一步步分析:

select 人员编号,
with t as (
select 人员编号,
       开始时间,
       min(开始时间) over(partition by 人员编号 order by 数值id rows between 1 following and unbounded following) as tmp开始时间,
       min(case
             when 类型 = -1 then
              add_months(开始时间, -1)
             else
              开始时间
           end) over(partition by 人员编号 order by 数值id rows between 1 following and unbounded following) as tmp_min开始时间,
       coalesce(min(case
                      when 类型 = -1 then
                       add_months(开始时间, -1)
                      else
                       开始时间
                    end)
                over(partition by 人员编号 order by 数值id rows between 1
                     following and unbounded following),
                开始时间 + 1) as min_开始时间,
       结束时间 as tmp_结束时间,
       case
         when 结束时间 is null and
              (lead(类型) over(partition by 人员编号 order by 数值id)) = -1 then
          add_months(lead(开始时间) over(partition by 人员编号 order by 数值id),
                     -1)
         else
          结束时间
       end as 结束时间,
       类型,
       数值ID,
       max(数值id) over(partition by 人员编号) as max_id
  from people
)
select * from t;

      人员编号 开始时间    TMP开始时间 TMP_MIN开始时间 MIN_开始时间 TMP_结束时间 结束时间            类型       数值ID     MAX_ID
---------- ----------- ----------- ----------- ----------- ----------- ----------- ---------- ---------- ----------
        11 2013-5-1    2013-1-1    2012-12-1   2012-12-1   2013-8-1    2013-8-1             1          1          4
        11 2013-7-1    2013-1-1    2012-12-1   2012-12-1               2012-12-1            1          2          4
        11 2013-1-1    2013-12-1   2013-12-1   2013-12-1                                   -1          3          4
        11 2013-12-1                           2013-12-2                                    1          4          4
        22 2013-5-1    2013-8-1    2013-8-1    2013-8-1    2013-6-1    2013-6-1             1          1          4
        22 2013-8-1    2013-12-1   2013-11-1   2013-11-1   2013-9-1    2013-9-1             1          2          4
        22 2013-12-1   2014-3-1    2014-3-1    2014-3-1    2013-12-1   2013-12-1           -1          3          4
        22 2014-3-1    2014-5-1    2014-4-1    2014-4-1                2014-4-1             1          4          4
        22 2014-5-1                            2014-5-2                                    -1          4          4
        33 2013-5-1    2013-7-1    2013-7-1    2013-7-1    2013-5-1    2013-5-1             1          1          4
        33 2013-7-1    2013-10-1   2013-9-1    2013-9-1    2013-7-1    2013-7-1             1          2          4
        33 2013-10-1   2013-12-1   2013-12-1   2013-12-1                                   -1          3          4
        33 2013-12-1                           2013-12-2                                    1          4          4

13 rows selected

上面标识了"开始时间"(见第三条)与"结束时间"(见第二条)分别处理的过程。

with t as (
select 人员编号,
       开始时间,
       min(开始时间) over(partition by 人员编号 order by 数值id rows between 1 following and unbounded following) as tmp开始时间,
       min(case
             when 类型 = -1 then
              add_months(开始时间, -1)
             else
              开始时间
           end) over(partition by 人员编号 order by 数值id rows between 1 following and unbounded following) as tmp_min开始时间,
       coalesce(min(case
                      when 类型 = -1 then
                       add_months(开始时间, -1)
                      else
                       开始时间
                    end)
                over(partition by 人员编号 order by 数值id rows between 1
                     following and unbounded following),
                开始时间 + 1) as min_开始时间,--当前人员的最小日期,覆盖用
       结束时间 as tmp_结束时间,
       case
         when 结束时间 is null and
              (lead(类型) over(partition by 人员编号 order by 数值id)) = -1 then
          add_months(lead(开始时间) over(partition by 人员编号 order by 数值id),
                     -1)
         else
          结束时间
       end as 结束时间,
       类型,
       数值ID,
       max(数值id) over(partition by 人员编号) as max_id
  from people
)
select 人员编号,
       开始时间,
       min_开始时间,
       结束时间,
       类型,
       数值ID,
       max_id,
       case--生成区间是否重叠的标识,合并时段时用
         when (lag(结束时间) over(partition by 人员编号 order by 数值id)) <
              add_months(开始时间, -1) then
          1
         when (lag(类型) over(partition by 人员编号 order by 数值id)) = 1 then
          null
         else
          1
       end as so
  from t;
      人员编号 开始时间    MIN_开始时间 结束时间            类型       数值ID     MAX_ID         SO
---------- ----------- ----------- ----------- ---------- ---------- ---------- ----------
        11 2013-5-1    2012-12-1   2013-8-1             1          1          4          1
        11 2013-7-1    2012-12-1   2012-12-1            1          2          4 
        11 2013-1-1    2013-12-1                       -1          3          4 
        11 2013-12-1   2013-12-2                        1          4          4          1
        22 2013-5-1    2013-8-1    2013-6-1             1          1          4          1
        22 2013-8-1    2013-11-1   2013-9-1             1          2          4          1
        22 2013-12-1   2014-3-1    2013-12-1           -1          3          4          1
        22 2014-3-1    2014-4-1    2014-4-1             1          4          4          1
        22 2014-5-1    2014-5-2                        -1          4          4 
        33 2013-5-1    2013-7-1    2013-5-1             1          1          4          1
        33 2013-7-1    2013-9-1    2013-7-1             1          2          4          1
        33 2013-10-1   2013-12-1                       -1          3          4          1
        33 2013-12-1   2013-12-2                        1          4          4          1

13 rows selected

生成分组标识,如果后录入的数据开始时间更早,就说明前面录入的是无用的数据,要丢弃,如果范围重叠,就修正前面的结束时间。

with t as (
select 人员编号,
       开始时间,
       min(开始时间) over(partition by 人员编号 order by 数值id rows between 1 following and unbounded following) as tmp开始时间,
       min(case
             when 类型 = -1 then
              add_months(开始时间, -1)
             else
              开始时间
           end) over(partition by 人员编号 order by 数值id rows between 1 following and unbounded following) as tmp_min开始时间,
       coalesce(min(case
                      when 类型 = -1 then
                       add_months(开始时间, -1)
                      else
                       开始时间
                    end)
                over(partition by 人员编号 order by 数值id rows between 1
                     following and unbounded following),
                开始时间 + 1) as min_开始时间,--当前人员的最小日期,覆盖用
       结束时间 as tmp_结束时间,
       case
         when 结束时间 is null and
              (lead(类型) over(partition by 人员编号 order by 数值id)) = -1 then
          add_months(lead(开始时间) over(partition by 人员编号 order by 数值id),
                     -1)
         else
          结束时间
       end as 结束时间,
       类型,
       数值ID,
       max(数值id) over(partition by 人员编号) as max_id
  from people
),
t1 as (
select 人员编号,
       开始时间,
       min_开始时间,
       结束时间,
       类型,
       数值ID,
       max_id,
       case--生成区间是否重叠的标识,合并时段时用
         when (lag(结束时间) over(partition by 人员编号 order by 数值id)) <
              add_months(开始时间, -1) then
          1
         when (lag(类型) over(partition by 人员编号 order by 数值id)) = 1 then
          null
         else
          1
       end as so
  from t)
  select 人员编号,
         数值ID,
         max_id,
         类型,
         sum(so) over(partition by 人员编号 order by 数值id) as so,/*累加标识,生成分组合并依据*/
         开始时间,
         min_开始时间,
         case/*根据最前面生成的时间覆盖对应的时段*/
           when min_开始时间 < 结束时间 and min_开始时间 >= 开始时间 then
            min_开始时间
           else
            结束时间
         end as 结束时间
    from t1
   where 类型 = 1
   /*如果开始时间比这还小,就丢弃吧*/
     and 开始时间 <= min_开始时间;
  
      人员编号       数值ID     MAX_ID         类型         SO 开始时间    MIN_开始时间 结束时间
---------- ---------- ---------- ---------- ---------- ----------- ----------- -----------
        11          4          4          1          1 2013-12-1   2013-12-2   
        22          1          4          1          1 2013-5-1    2013-8-1    2013-6-1
        22          2          4          1          2 2013-8-1    2013-11-1   2013-9-1
        22          4          4          1          3 2014-3-1    2014-4-1    2014-4-1
        33          1          4          1          1 2013-5-1    2013-7-1    2013-5-1
        33          2          4          1          2 2013-7-1    2013-9-1    2013-7-1
        33          4          4          1          3 2013-12-1   2013-12-2   

7 rows selected

合并数据,语句如下:

/*人员编号 NUMBER Y 
开始时间 DATE   Y 
结束时间 DATE   Y 
类型 NUMBER Y   
数值ID NUMBER Y 
1、当类型为"-l"时,数据丢弃。
2、当类型为"-1",且其前一行"结束时间"为空值时,"开始时间-1"当作其前一行的结束时间。
3、如果后面的时间比前面的时间早,则覆盖前面的时间,不能覆盖的时间要保留。
5、时段重叠的要合并为一行。

*/


with t as (
select 人员编号,
       开始时间,
       min(开始时间) over(partition by 人员编号 order by 数值id rows between 1 following and unbounded following) as tmp开始时间,
       min(case
             when 类型 = -1 then
              add_months(开始时间, -1)
             else
              开始时间
           end) over(partition by 人员编号 order by 数值id rows between 1 following and unbounded following) as tmp_min开始时间,
       coalesce(min(case
                      when 类型 = -1 then
                       add_months(开始时间, -1)
                      else
                       开始时间
                    end)
                over(partition by 人员编号 order by 数值id rows between 1
                     following and unbounded following),
                开始时间 + 1) as min_开始时间,--当前人员的最小日期,覆盖用
       结束时间 as tmp_结束时间,
       case
         when 结束时间 is null and
              (lead(类型) over(partition by 人员编号 order by 数值id)) = -1 then
          add_months(lead(开始时间) over(partition by 人员编号 order by 数值id),
                     -1)
         else
          结束时间
       end as 结束时间,
       类型,
       数值ID,
       max(数值id) over(partition by 人员编号) as max_id
  from people
),
t1 as (
select 人员编号,
       开始时间,
       min_开始时间,
       结束时间,
       类型,
       数值ID,
       max_id,
       case--生成区间是否重叠的标识,合并时段时用
         when (lag(结束时间) over(partition by 人员编号 order by 数值id)) <
              add_months(开始时间, -1) then
          1
         when (lag(类型) over(partition by 人员编号 order by 数值id)) = 1 then
          null
         else
          1
       end as so
  from t),
t2 as (
  select 人员编号,
         数值ID,
         max_id,
         类型,
         sum(so) over(partition by 人员编号 order by 数值id) as so,/*累加标识,生成分组合并依据*/
         开始时间,
         min_开始时间,
         case/*根据最前面生成的时间覆盖对应的时段*/
           when min_开始时间 < 结束时间 and min_开始时间 >= 开始时间 then
            min_开始时间
           else
            结束时间
         end as 结束时间
    from t1
   where 类型 = 1
   /*如果开始时间比这还小,就丢弃吧*/
     and 开始时间 <= min_开始时间)
     select 人员编号,
            max_id,
            max(数值ID) as max_id2,
            sum(类型) as 类型,
            min(开始时间) keep(dense_rank first order by 数值id) as 开始时间,
            max(开始时间) keep(dense_rank last order by 数值id) as 结束时间
       from t2
      group by 人员编号, so, max_id;
      人员编号     MAX_ID    MAX_ID2         类型 开始时间    结束时间
---------- ---------- ---------- ---------- ----------- -----------
        11          4          4          1 2013-12-1   2013-12-1
        22          4          1          1 2013-5-1    2013-5-1
        22          4          2          1 2013-8-1    2013-8-1
        22          4          4          1 2014-3-1    2014-3-1
        33          4          1          1 2013-5-1    2013-5-1
        33          4          2          1 2013-7-1    2013-7-1
        33          4          4          1 2013-12-1   2013-12-1

7 rows selected

最后一步是过滤,语句如下:

with t as (
select 人员编号,
       开始时间,
       min(开始时间) over(partition by 人员编号 order by 数值id rows between 1 following and unbounded following) as tmp开始时间,
       min(case
             when 类型 = -1 then
              add_months(开始时间, -1)
             else
              开始时间
           end) over(partition by 人员编号 order by 数值id rows between 1 following and unbounded following) as tmp_min开始时间,
       coalesce(min(case
                      when 类型 = -1 then
                       add_months(开始时间, -1)
                      else
                       开始时间
                    end)
                over(partition by 人员编号 order by 数值id rows between 1
                     following and unbounded following),
                开始时间 + 1) as min_开始时间,--当前人员的最小日期,覆盖用
       结束时间 as tmp_结束时间,
       case
         when 结束时间 is null and
              (lead(类型) over(partition by 人员编号 order by 数值id)) = -1 then
          add_months(lead(开始时间) over(partition by 人员编号 order by 数值id),
                     -1)
         else
          结束时间
       end as 结束时间,
       类型,
       数值ID,
       max(数值id) over(partition by 人员编号) as max_id
  from people
),
t1 as (
select 人员编号,
       开始时间,
       min_开始时间,
       结束时间,
       类型,
       数值ID,
       max_id,
       case--生成区间是否重叠的标识,合并时段时用
         when (lag(结束时间) over(partition by 人员编号 order by 数值id)) <
              add_months(开始时间, -1) then
          1
         when (lag(类型) over(partition by 人员编号 order by 数值id)) = 1 then
          null
         else
          1
       end as so
  from t),
t2 as (
  select 人员编号,
         数值ID,
         max_id,
         类型,
         sum(so) over(partition by 人员编号 order by 数值id) as so,/*累加标识,生成分组合并依据*/
         开始时间,
         min_开始时间,
         case/*根据最前面生成的时间覆盖对应的时段*/
           when min_开始时间 < 结束时间 and min_开始时间 >= 开始时间 then
            min_开始时间
           else
            结束时间
         end as 结束时间
    from t1
   where 类型 = 1
   /*如果开始时间比这还小,就丢弃吧*/
     and 开始时间 <= min_开始时间),
     t3 as (
     select 人员编号,
            max_id,
            max(数值ID) as max_id2,
            sum(类型) as 类型,
            min(开始时间) keep(dense_rank first order by 数值id) as 开始时间,
            max(开始时间) keep(dense_rank last order by 数值id) as 结束时间
       from t2
      group by 人员编号, so, max_id)
      select 人员编号,to_char(开始时间,'yyyymm')||'--'||to_char(结束时间,'yyyymm') as str
      from t3
      where (max_id=max_id2 or 开始时间<=结束时间)
      and 类型>-1;
            人员编号 STR
---------- --------------------------------------------------------------------------------
        11 201312--201312
        22 201305--201305
        22 201308--201308
        22 201403--201403
        33 201305--201305
        33 201307--201307
        33 201312--201312

7 rows selected

到这一步就可以了。整理数据是最考验耐心的工作,特别是需求还不确定的时候。


总结

本篇文章讲解的主要内容是:从整理人员签到信息记录表的垃圾数据来再次体会一下隐藏数据列信息以及查找数据的连续性时间和重叠时间的实战案例

有关【SQL开发实战技巧】系列(三十六):数仓报表场景☞整理垃圾数据:查找数据的连续性时间和重叠时间的关系,初始化开始结束时间的更多相关文章

  1. ruby - 如何以所有可能的方式将字符串拆分为长度最多为 3 的连续子字符串? - 2

    我试图获取一个长度在1到10之间的字符串,并输出将字符串分解为大小为1、2或3的连续子字符串的所有可能方式。例如:输入:123456将整数分割成单个字符,然后继续查找组合。该代码将返回以下所有数组。[1,2,3,4,5,6][12,3,4,5,6][1,23,4,5,6][1,2,34,5,6][1,2,3,45,6][1,2,3,4,56][12,34,5,6][12,3,45,6][12,3,4,56][1,23,45,6][1,2,34,56][1,23,4,56][12,34,56][123,4,5,6][1,234,5,6][1,2,345,6][1,2,3,456][123

  2. ruby-on-rails - 未初始化的常量 Psych::Syck (NameError) - 2

    在我的gem中,我需要yaml并且在我的本地计算机上运行良好。但是在将我的gem推送到ruby​​gems.org之后,当我尝试使用我的gem时,我收到一条错误消息=>"uninitializedconstantPsych::Syck(NameError)"谁能帮我解决这个问题?附言RubyVersion=>ruby1.9.2,GemVersion=>1.6.2,Bundlerversion=>1.0.15 最佳答案 经过几个小时的研究,我发现=>“YAML使用未维护的Syck库,而Psych使用现代的LibYAML”因此,为了解决

  3. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  4. ruby-on-rails - 未在 Ruby 中初始化的对象 - 2

    我在Rails工作并有以下类(class):classPlayer当我运行时bundleexecrailsconsole然后尝试:a=Player.new("me",5.0,"UCLA")我回来了:=>#我不知道为什么Player对象不会在这里初始化。关于可能导致此问题的操作/解释的任何建议?谢谢,马里奥格 最佳答案 havenoideawhythePlayerobjectwouldn'tbeinitializedhere它没有初始化很简单,因为你还没有初始化它!您已经覆盖了ActiveRecord::Base初始化方法,但您没有调

  5. ruby-on-rails - Ruby 检查日期时间是否为 iso8601 并保存 - 2

    我需要检查DateTime是否采用有效的ISO8601格式。喜欢:#iso8601?我检查了ruby​​是否有特定方法,但没有找到。目前我正在使用date.iso8601==date来检查这个。有什么好的方法吗?编辑解释我的环境,并改变问题的范围。因此,我的项目将使用jsapiFullCalendar,这就是我需要iso8601字符串格式的原因。我想知道更好或正确的方法是什么,以正确的格式将日期保存在数据库中,或者让ActiveRecord完成它们的工作并在我需要时间信息时对其进行操作。 最佳答案 我不太明白你的问题。我假设您想检查

  6. ruby - 当使用::指定模块时,为什么 Ruby 不在更高范围内查找类? - 2

    我刚刚被困在这个问题上一段时间了。以这个基地为例:moduleTopclassTestendmoduleFooendend稍后,我可以通过这样做在Foo中定义扩展Test的类:moduleTopmoduleFooclassSomeTest但是,如果我尝试通过使用::指定模块来最小化缩进:moduleTop::FooclassFailure这失败了:NameError:uninitializedconstantTop::Foo::Test这是一个错误,还是仅仅是Ruby解析变量名的方式的逻辑结果? 最佳答案 Isthisabug,or

  7. ruby-on-rails - ActionController::RoutingError: 未初始化常量 Api::V1::ApiController - 2

    我有用于控制用户任务的Rails5API项目,我有以下错误,但并非总是针对相同的Controller和路由。ActionController::RoutingError:uninitializedconstantApi::V1::ApiController我向您描述了一些我的项目,以更详细地解释错误。应用结构路线scopemodule:'api'donamespace:v1do#=>Loginroutesscopemodule:'login'domatch'login',to:'sessions#login',as:'login',via::postend#=>Teamroutessc

  8. ruby - Ruby 有 `Pair` 数据类型吗? - 2

    有时我需要处理键/值数据。我不喜欢使用数组,因为它们在大小上没有限制(很容易不小心添加超过2个项目,而且您最终需要稍后验证大小)。此外,0和1的索引变成了魔数(MagicNumber),并且在传达含义方面做得很差(“当我说0时,我的意思是head...”)。散列也不合适,因为可能会不小心添加额外的条目。我写了下面的类来解决这个问题:classPairattr_accessor:head,:taildefinitialize(h,t)@head,@tail=h,tendend它工作得很好并且解决了问题,但我很想知道:Ruby标准库是否已经带有这样一个类? 最佳

  9. ruby-on-rails - 将 Ruby 中的日期/时间格式化为 YYYY-MM-DD HH :MM:SS - 2

    这个问题在这里已经有了答案:Railsformattingdate(4个答案)关闭4年前。我想格式化Time.Now函数以显示YYYY-MM-DDHH:MM:SS而不是:“2018-03-0909:47:19+0000”该函数需要放在时间中.现在功能。require‘roo’require‘roo-xls’require‘byebug’file_name=ARGV.first||“Template.xlsx”excel_file=Roo::Spreadsheet.open(“./#{file_name}“,extension::xlsx)xml=Nokogiri::XML::Build

  10. ruby - 查找字符串中的内容类型(数字、日期、时间、字符串等) - 2

    我正在尝试解析一个CSV文件并使用SQL命令自动为其创建一个表。CSV中的第一行给出了列标题。但我需要推断每个列的类型。Ruby中是否有任何函数可以找到每个字段中内容的类型。例如,CSV行:"12012","Test","1233.22","12:21:22","10/10/2009"应该产生像这样的类型['integer','string','float','time','date']谢谢! 最佳答案 require'time'defto_something(str)if(num=Integer(str)rescueFloat(s

随机推荐