SQL move data from rows to cols

為{幸葍}努か 提交于 2019-12-11 02:40:47

问题


Sorry for the bad title - I simply do not know what to call the thing I want to do.

Here it goes:

In MS SQL Server 2008

I have a temp table with 4000+ rows created with the WITH statement looking like this:

ID (varchar) DATE (int)

AB1135000097 | 20151221
AB1135000097 | 20160119
AB1135000097 | 20160219
AB1135001989 | 20120223
AB1135001989 | 20120323
AB1135001989 | 20120423
.
.
.

I want to pair the data in date-ranges based on DATE.

AB1135000097 | 20151221 | 20160119
AB1135000097 | 20160119 | 20160219
AB1135001989 | 20120223 | 20120323
AB1135001989 | 20120323 | 20120423

Does this action have a name ? (I will add tags to the post when I know what I'm asking for)


回答1:


Assumed schema

I am assuming that your table is like:

CREATE TABLE "TABLE"
(
    tag     CHAR(1) NOT NULL,
    value   INTEGER NOT NULL,
    PRIMARY KEY(tag, value)
);

I really shouldn't have to guess the schema though.

Possible answer

Superficially, you might be after:

SELECT t1.tag, t1.value, t2.value
  FROM "TABLE" AS t1
  JOIN "TABLE" AS t2
    ON t1.tag = t2.tag AND t2.value = t1.value + 1
 ORDER BY t1.tag, t1.value;

This joins the table with itself, combining rows where the tag column values (A, B, ...) are the same, and where the value column in one row is one more than the value column in the other.

On the other hand, if you add a row ('A', 5) to the table and expect it to appear in the output as part of a row ('A', 3, 5), then the query is much harder to write without using OLAP features.




回答2:


if you are using Oracle database then you can refer following query to solve this question -

with t as
(
SELECT 'A' Col1, 1 Col2
  FROM Dual
UNION ALL
SELECT 'A' Col1, 2 Col2
  FROM Dual
UNION ALL
SELECT 'A' Col1, 3 Col2
  FROM Dual
UNION ALL
SELECT 'B' Col1, 4 Col2
  FROM Dual
UNION ALL
SELECT 'B' Col1, 5 Col2
  FROM Dual
UNION ALL
SELECT 'B' Col1, 6 Col2 FROM Dual
)
SELECT *
  FROM (SELECT Col1,
               Col2,
               Lead(Col1) Over(ORDER BY Col1, Col2) Col3,
               Lead(Col2) Over(ORDER BY Col1, Col2) Col4
          FROM t  --(your table name)
         ORDER BY Col1, Col2)
 WHERE Col1 = Col3

as I don't have your table name and table structure I have created one temp table in Query itself.

you need to change From t to From with your table name . .. please change col1 and col2 column name also accordingly.




回答3:


I found a solution to my problem. Inspired by Jonathan Leffler's solution. Thanks a lot!

It is based on adding row-numbers to the table ordered by ID and DATE, and then self-join with ROW+1 to get the next date as a second date column.

with 
SCHEDULE as
( -- remove duplicates and NULL entries

    select DISTINCT ID, DATE from TABLE1
    where DATE IS NOT NULL
),

SCHEDULE_WITH_ROW as
(
select * from (
    select DISTINCT ROW_NUMBER()
        OVER (ORDER BY ID, DATE) AS
        ROW, ID, DATE 
    from SCHEDULE) AS SCHED
)

select 
    S1.ID
    , S1.DATE
    , S2.DATE
from SCHEDULE_WITH_ROW S1
    join SCHEDULE_WITH_ROW S2 on S2.ID = S1.ID and S1.ROW + 1 = S2.ROW 


来源:https://stackoverflow.com/questions/11311549/sql-move-data-from-rows-to-cols

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!