使用SQL将关系表的内容转换为指定的表单

时间:2013-05-19 20:37:19

标签: sql postgresql

我有一个包含以下列的数据库:

key arg1 arg2 arg3 timebegin                     timeend
#1  a    b    c    1942-06-18 05:30:00+05:30     1945-06-18 05:30:00+05:30
#2  d    e    f    1940-10-09 05:53:20+05:53:20  1948-10-09 05:53:20+05:53:20
#3  w    x    y    

键的类型arg1,arg2,arg3是字符变化(255),timebegin的类型和timeend是带时区的时间戳。

现在我想将关系表转换为下面给出的格式:

<1> <a> <b> <c>                              //key,arg1,arg2,agr3
<2> <d> <e> <f>
<3> <w> <x> <y>
<1> <a> <b> 1942-06-18 05:30:00+05:30       //With columns containing time attributes just key, arg1, arg2, timebegin are copied.
<1> <a> <b> 1945-06-18 05:30:00+05:30
<1> <d> <e> 1940-10-09 05:53:20+05:53:20
<1> <d> <e> 1948-10-09 05:53:20+05:53:20

是否可以使用SQL将关系表转换为上面给出的格式。我知道可以将关系表的内容转储为csv格式。但是也可以将关系表的内容转换为上面给出的指定形式。我的数据库是postgres 9.1

**

* GT;编辑:规则:

  

1。首先从所有行键,arg1,arg2,arg3复制然后   2.对于包含NOT NULL timebegin和timeend值的所有行:key,arg1,arg2,timebegin和key,arg1,arg2,timeend被复制*

**

注意:“&lt;&gt;”对我来说无关紧要放置与否。

1 个答案:

答案 0 :(得分:0)

这两个关键部分 - 假设您绝对必须将其转换为SQL查询而不是更广泛的后处理 - 1)选择以您喜欢的方式格式化为字符串的相应列,以及2)选择所有立即生成结果,而不是运行多个SQL查询。

第一部分要求将数据转换为字符串类型,并将它们与适当的分隔符连接在一起。在PostgreSQL(和SQL标准,但不是所有其他DBMS)中,字符串连接运算符是||。我也喜欢用于类型转换的非标准PostgreSQL语法,column::type,尽管Cast(column as type)会更便携。

对于第二部分,您需要SQL UNION运算符,它结合了两个具有相同数量和类型的列的结果集。需要记住一些繁琐的位 - UNION将删除重复的行,UNION ALL可以避免这些行;并且您无法在联合的两个查询中直接使用ORDER BY

这是一个示例查询,似乎可以提供您想要的内容。请注意,尽管在简单示例中这似乎排序正确,但我认为在所有结果一起UNION之后,它应该在最后严格地有一个ORDER BY

此处的互动演示:http://sqlfiddle.com/#!1/7f754/5/0

Select string
From
(
  Select
    '<' || key::text || '> ' 
    || '<' || arg1 || '> '
    || '<' || arg2 || '> '
    || '<' || arg3 || '>' as string
  From
    Foo
  Order by key
) as x

Union All

Select string
From
(
  Select
    key,
    '<' || key::text || '> ' 
    || '<' || arg1 || '> '
    || '<' || arg2 || '> '
    || timebegin::text as string
  From
    Foo
  Where
    timebegin Is Not Null
    And
    timeend Is Not Null

  Union All

  Select
    key,
    '<' || key::text || '> ' 
    || '<' || arg1 || '> '
    || '<' || arg2 || '> '
    || timebegin::text as string
  From
    Foo
  Where
    timebegin Is Not Null
    And
    timeend Is Not Null

  Order by key
) as x