Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 在oracle中,合并表中除生效日期外所有详细信息相同的两行_Sql_Oracle - Fatal编程技术网

Sql 在oracle中,合并表中除生效日期外所有详细信息相同的两行

Sql 在oracle中,合并表中除生效日期外所有详细信息相同的两行,sql,oracle,Sql,Oracle,我有一个表客户,下面有四列 customer_id customer_effective_date customer_term_date service 1 1/1/2017 1/31/2017 Bike 1 2/1/2017 12/31/2017 Bike 1 1/1/2018 1/31/2018

我有一个表客户,下面有四列

customer_id customer_effective_date customer_term_date service
1           1/1/2017                1/31/2017          Bike
1           2/1/2017                12/31/2017         Bike
1           1/1/2018                1/31/2018          Car
1           2/1/2018                2/28/2018          Car
1           3/1/2018                3/31/2018          Bike
1           4/1/2018                4/30/2018          Bike
我正在尝试将这些合并为以下内容:

1           1/1/2017                12/31/2017          Bike
1           1/1/2018                2/28/2018          Car
1           3/1/2018                4/30/2018          Bike
有谁能建议我们如何做到这一点。我试图分组,并采取最小和最大日期,但由于服务的第一个记录是自行车,我得到的结果如下

1           1/1/2017                4/30/2017         Bike
1           1/1/2018                2/28/2018          Car

我需要一些关于如何做到这一点的信息。

如果您也按年度分组,这将获得您想要的输出:

Oracle 11g R2架构设置

CREATE TABLE table_name (
  customer_id,
  customer_effective_date,
  customer_term_date,
  service
) AS
SELECT 1, DATE '2017-01-01', DATE '2017-01-31', 'Bike' FROM DUAL UNION ALL
SELECT 1, DATE '2017-02-01', DATE '2017-12-31', 'Bike' FROM DUAL UNION ALL
SELECT 1, DATE '2018-01-01', DATE '2018-01-31', 'Car' FROM DUAL UNION ALL
SELECT 1, DATE '2018-02-01', DATE '2018-02-28', 'Car' FROM DUAL UNION ALL
SELECT 1, DATE '2018-03-01', DATE '2018-03-31', 'Bike' FROM DUAL UNION ALL
SELECT 1, DATE '2018-04-01', DATE '2018-04-30', 'Bike' FROM DUAL;
SELECT customer_id,
       MIN( customer_effective_date ) AS customer_effective_date,
       MAX( customer_term_date ) AS customer_term_date,
       service
FROM   table_name
GROUP BY
       customer_id,
       service,
       TRUNC( customer_effective_date, 'YYYY' )
ORDER BY
       customer_effective_date
| CUSTOMER_ID | CUSTOMER_EFFECTIVE_DATE |   CUSTOMER_TERM_DATE | SERVICE |
|-------------|-------------------------|----------------------|---------|
|           1 |    2017-01-01T00:00:00Z | 2017-12-31T00:00:00Z |    Bike |
|           1 |    2018-01-01T00:00:00Z | 2018-02-28T00:00:00Z |     Car |
|           1 |    2018-03-01T00:00:00Z | 2018-04-30T00:00:00Z |    Bike |
| CUSTOMER_ID | CUSTOMER_EFFECTIVE_DATE |   CUSTOMER_TERM_DATE | SERVICE |
|-------------|-------------------------|----------------------|---------|
|           1 |    2017-01-01T00:00:00Z | 2017-12-31T00:00:00Z |    Bike |
|           1 |    2018-01-01T00:00:00Z | 2018-02-28T00:00:00Z |     Car |
|           1 |    2018-03-01T00:00:00Z | 2018-04-30T00:00:00Z |    Bike |
查询1

CREATE TABLE table_name (
  customer_id,
  customer_effective_date,
  customer_term_date,
  service
) AS
SELECT 1, DATE '2017-01-01', DATE '2017-01-31', 'Bike' FROM DUAL UNION ALL
SELECT 1, DATE '2017-02-01', DATE '2017-12-31', 'Bike' FROM DUAL UNION ALL
SELECT 1, DATE '2018-01-01', DATE '2018-01-31', 'Car' FROM DUAL UNION ALL
SELECT 1, DATE '2018-02-01', DATE '2018-02-28', 'Car' FROM DUAL UNION ALL
SELECT 1, DATE '2018-03-01', DATE '2018-03-31', 'Bike' FROM DUAL UNION ALL
SELECT 1, DATE '2018-04-01', DATE '2018-04-30', 'Bike' FROM DUAL;
SELECT customer_id,
       MIN( customer_effective_date ) AS customer_effective_date,
       MAX( customer_term_date ) AS customer_term_date,
       service
FROM   table_name
GROUP BY
       customer_id,
       service,
       TRUNC( customer_effective_date, 'YYYY' )
ORDER BY
       customer_effective_date
| CUSTOMER_ID | CUSTOMER_EFFECTIVE_DATE |   CUSTOMER_TERM_DATE | SERVICE |
|-------------|-------------------------|----------------------|---------|
|           1 |    2017-01-01T00:00:00Z | 2017-12-31T00:00:00Z |    Bike |
|           1 |    2018-01-01T00:00:00Z | 2018-02-28T00:00:00Z |     Car |
|           1 |    2018-03-01T00:00:00Z | 2018-04-30T00:00:00Z |    Bike |
| CUSTOMER_ID | CUSTOMER_EFFECTIVE_DATE |   CUSTOMER_TERM_DATE | SERVICE |
|-------------|-------------------------|----------------------|---------|
|           1 |    2017-01-01T00:00:00Z | 2017-12-31T00:00:00Z |    Bike |
|           1 |    2018-01-01T00:00:00Z | 2018-02-28T00:00:00Z |     Car |
|           1 |    2018-03-01T00:00:00Z | 2018-04-30T00:00:00Z |    Bike |

CREATE TABLE table_name (
  customer_id,
  customer_effective_date,
  customer_term_date,
  service
) AS
SELECT 1, DATE '2017-01-01', DATE '2017-01-31', 'Bike' FROM DUAL UNION ALL
SELECT 1, DATE '2017-02-01', DATE '2017-12-31', 'Bike' FROM DUAL UNION ALL
SELECT 1, DATE '2018-01-01', DATE '2018-01-31', 'Car' FROM DUAL UNION ALL
SELECT 1, DATE '2018-02-01', DATE '2018-02-28', 'Car' FROM DUAL UNION ALL
SELECT 1, DATE '2018-03-01', DATE '2018-03-31', 'Bike' FROM DUAL UNION ALL
SELECT 1, DATE '2018-04-01', DATE '2018-04-30', 'Bike' FROM DUAL;
SELECT customer_id,
       MIN( customer_effective_date ) AS customer_effective_date,
       MAX( customer_term_date ) AS customer_term_date,
       service
FROM   table_name
GROUP BY
       customer_id,
       service,
       TRUNC( customer_effective_date, 'YYYY' )
ORDER BY
       customer_effective_date
| CUSTOMER_ID | CUSTOMER_EFFECTIVE_DATE |   CUSTOMER_TERM_DATE | SERVICE |
|-------------|-------------------------|----------------------|---------|
|           1 |    2017-01-01T00:00:00Z | 2017-12-31T00:00:00Z |    Bike |
|           1 |    2018-01-01T00:00:00Z | 2018-02-28T00:00:00Z |     Car |
|           1 |    2018-03-01T00:00:00Z | 2018-04-30T00:00:00Z |    Bike |
| CUSTOMER_ID | CUSTOMER_EFFECTIVE_DATE |   CUSTOMER_TERM_DATE | SERVICE |
|-------------|-------------------------|----------------------|---------|
|           1 |    2017-01-01T00:00:00Z | 2017-12-31T00:00:00Z |    Bike |
|           1 |    2018-01-01T00:00:00Z | 2018-02-28T00:00:00Z |     Car |
|           1 |    2018-03-01T00:00:00Z | 2018-04-30T00:00:00Z |    Bike |
查询2

CREATE TABLE table_name (
  customer_id,
  customer_effective_date,
  customer_term_date,
  service
) AS
SELECT 1, DATE '2017-01-01', DATE '2017-01-31', 'Bike' FROM DUAL UNION ALL
SELECT 1, DATE '2017-02-01', DATE '2017-12-31', 'Bike' FROM DUAL UNION ALL
SELECT 1, DATE '2018-01-01', DATE '2018-01-31', 'Car' FROM DUAL UNION ALL
SELECT 1, DATE '2018-02-01', DATE '2018-02-28', 'Car' FROM DUAL UNION ALL
SELECT 1, DATE '2018-03-01', DATE '2018-03-31', 'Bike' FROM DUAL UNION ALL
SELECT 1, DATE '2018-04-01', DATE '2018-04-30', 'Bike' FROM DUAL;
SELECT customer_id,
       MIN( customer_effective_date ) AS customer_effective_date,
       MAX( customer_term_date ) AS customer_term_date,
       service
FROM   table_name
GROUP BY
       customer_id,
       service,
       TRUNC( customer_effective_date, 'YYYY' )
ORDER BY
       customer_effective_date
| CUSTOMER_ID | CUSTOMER_EFFECTIVE_DATE |   CUSTOMER_TERM_DATE | SERVICE |
|-------------|-------------------------|----------------------|---------|
|           1 |    2017-01-01T00:00:00Z | 2017-12-31T00:00:00Z |    Bike |
|           1 |    2018-01-01T00:00:00Z | 2018-02-28T00:00:00Z |     Car |
|           1 |    2018-03-01T00:00:00Z | 2018-04-30T00:00:00Z |    Bike |
| CUSTOMER_ID | CUSTOMER_EFFECTIVE_DATE |   CUSTOMER_TERM_DATE | SERVICE |
|-------------|-------------------------|----------------------|---------|
|           1 |    2017-01-01T00:00:00Z | 2017-12-31T00:00:00Z |    Bike |
|           1 |    2018-01-01T00:00:00Z | 2018-02-28T00:00:00Z |     Car |
|           1 |    2018-03-01T00:00:00Z | 2018-04-30T00:00:00Z |    Bike |
如果是孤岛和间隙问题,这也会合并组,并且不会进行聚合:

SELECT *
FROM   (
  SELECT customer_id,
         LAST_VALUE( customer_effective_date )
           IGNORE NULLS OVER (
             PARTITION BY customer_id, service
             ORDER BY COALESCE( customer_effective_date, customer_term_date )
           ) AS customer_effective_date,
         customer_term_date,
         service
  FROM   (
    SELECT customer_id,
           CASE
           WHEN customer_effective_date
                  = LAG( customer_term_date, 1 ) OVER (
                      PARTITION BY customer_id, service
                      ORDER BY customer_effective_date
                    ) + 1
           THEN NULL
           ELSE customer_effective_date
           END AS customer_effective_date,
           CASE
           WHEN customer_term_date
                  = LEAD( customer_effective_date, 1 ) OVER (
                      PARTITION BY customer_id, service
                      ORDER BY customer_effective_date
                    ) - 1
           THEN NULL
           ELSE customer_term_date
           END AS customer_term_date,
           service
    FROM   table_name
  )
)
WHERE  customer_term_date IS NOT NULL
ORDER BY customer_effective_date

CREATE TABLE table_name (
  customer_id,
  customer_effective_date,
  customer_term_date,
  service
) AS
SELECT 1, DATE '2017-01-01', DATE '2017-01-31', 'Bike' FROM DUAL UNION ALL
SELECT 1, DATE '2017-02-01', DATE '2017-12-31', 'Bike' FROM DUAL UNION ALL
SELECT 1, DATE '2018-01-01', DATE '2018-01-31', 'Car' FROM DUAL UNION ALL
SELECT 1, DATE '2018-02-01', DATE '2018-02-28', 'Car' FROM DUAL UNION ALL
SELECT 1, DATE '2018-03-01', DATE '2018-03-31', 'Bike' FROM DUAL UNION ALL
SELECT 1, DATE '2018-04-01', DATE '2018-04-30', 'Bike' FROM DUAL;
SELECT customer_id,
       MIN( customer_effective_date ) AS customer_effective_date,
       MAX( customer_term_date ) AS customer_term_date,
       service
FROM   table_name
GROUP BY
       customer_id,
       service,
       TRUNC( customer_effective_date, 'YYYY' )
ORDER BY
       customer_effective_date
| CUSTOMER_ID | CUSTOMER_EFFECTIVE_DATE |   CUSTOMER_TERM_DATE | SERVICE |
|-------------|-------------------------|----------------------|---------|
|           1 |    2017-01-01T00:00:00Z | 2017-12-31T00:00:00Z |    Bike |
|           1 |    2018-01-01T00:00:00Z | 2018-02-28T00:00:00Z |     Car |
|           1 |    2018-03-01T00:00:00Z | 2018-04-30T00:00:00Z |    Bike |
| CUSTOMER_ID | CUSTOMER_EFFECTIVE_DATE |   CUSTOMER_TERM_DATE | SERVICE |
|-------------|-------------------------|----------------------|---------|
|           1 |    2017-01-01T00:00:00Z | 2017-12-31T00:00:00Z |    Bike |
|           1 |    2018-01-01T00:00:00Z | 2018-02-28T00:00:00Z |     Car |
|           1 |    2018-03-01T00:00:00Z | 2018-04-30T00:00:00Z |    Bike |

这是一个缺口和岛屿问题。我不确定真正的逻辑是什么(日期是否必须重叠,就像问题中那样?),但一种方法是行号的差异:

select customer_id,
       min(customer_effective_date),
       max(customer_term_date),
       service
from (select t.*,
             row_number() over (partition by customerid order by customer_effective_date) as seqnum,
             row_number() over (partition by customerid, service order by customer_effective_date) as seqnum_s
      from t
     ) t
group by customer_id, (seqnum_s - seqnum), service
order by 2;

显示您当前的查询尝试!为什么您希望返回3行而不是2行?行合并的逻辑是什么?是什么定义了记录的顺序?客户的有效日期?这似乎是一个孤岛和缺口问题。其主要目的是清理中间不必要的记录。为此,我必须确保与生效日期保持相同的顺序。根据需要,我需要维护3条记录,这个解决方案更通用,不严格依赖日期。这很好。如果我们有很多列,例如:如果我们有service1,service2,service3,会怎么样?这怎么可能handled@Harikrishnamv . . . 我不明白这个评论。你应该问另一个问题,并提供样本数据和期望的结果。这个问题已经有了不止一个答案。更改它可能会使答案无效。