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 . . . 我不明白这个评论。你应该问另一个问题,并提供样本数据和期望的结果。这个问题已经有了不止一个答案。更改它可能会使答案无效。