在select查询中生成三行

时间:2017-07-24 12:07:22

标签: sql sql-server-2008-r2

我有下表

SELECT TableCode, Col1, Col2
FROM TableA
WHERE TableCode = 23

表格结果:

TableCode   |  Col1    |   Col1
23          | CustCode |    QS
23          | CatCode  |    QS

之后我在TableA上写了一个返回以下输出的查询

查询:

SELECT TableCode,x.ColCode,
       x.ColumnName + '_' + CONVERT(VARCHAR(5), ROW_NUMBER() OVER (PARTITION BY X.COL ORDER BY X.COL)) [ColumnName],X.Values,
       ROW_NUMBER() OVER (PARTITION BY X.COL ORDER BY X.COL) [RowNo]
FROM TableA a CROSS APPLY   
     (SELECT 1 ColCode,'ParaName' ColumnName,Col1 Values
      UNION ALL  
      SELECT 2,'ParaSource',Col2   
     ) x
WHERE TableCode = 23;

结果:

TableCode | ColCode | ColumnName | Values |   RowNo
23       |   1     | ParaName_1 | CustCode |    1
23       |   1     | ParaName_2  | CatCode |    2
23       |     2   | ParaSource_1 | QS     | 1 
23        |   2    | ParaSource_2 | QS     | 2

我需要以下输出:

必需输出:

TableCode | ColCode | ColumnName | Values |   RowNo
23       |   1     | ParaName_1 | CustCode |    1
23       |   1     | ParaName_2  | CatCode |    2
23       |   1     | ParaName_3  | Null |   3
23       |     2   | ParaSource_1 | QS     | 1 
23        |   2    | ParaSource_2 | QS     | 2
23        |   2    | ParaSource_3 | null   | 3

2 个答案:

答案 0 :(得分:1)

使用几个common table expressionsrow_number()以及table value constructor (values (...),(...))  到cross join数字1,2和3然后使用left joinTableCode返回3行,即使源表中没有三行也是如此。

;with numbered as (
  select *, rn = row_number() over (order by (select 1))
  from TableA
  where TableCode = 23
)
, cte as (
  select distinct tc.TableCode, a.Col1, a.Col2, v.rn
  from numbered tc 
    cross join (values (1),(2),(3)) v (rn)
    left join numbered a
      on a.TableCode = tc.TableCode
     and a.rn = v.rn
)
select 
    a.TableCode
  , x.ColCode
  , [ColumnName] = x.ColumnName + '_' + convert(varchar(5),a.rn)
  , X.Value
  ,[RowNo] = a.rn
from cte a
  cross apply (values (1,'ParaName',Col1),(2,'ParaSource',Col2)) 
    as x(ColCode, ColumnName, Value)
order by ColCode, RowNo;

rextester演示:http://rextester.com/CJU8986

返回:

+-----------+---------+--------------+----------+-------+
| TableCode | ColCode |  ColumnName  |  Value   | RowNo |
+-----------+---------+--------------+----------+-------+
|        23 |       1 | ParaName_1   | CustCode |     1 |
|        23 |       1 | ParaName_2   | CatCode  |     2 |
|        23 |       1 | ParaName_3   | NULL     |     3 |
|        23 |       2 | ParaSource_1 | QS       |     1 |
|        23 |       2 | ParaSource_2 | QS       |     2 |
|        23 |       2 | ParaSource_3 | NULL     |     3 |
+-----------+---------+--------------+----------+-------+

答案 1 :(得分:0)

这似乎可以满足您的需求:

SELECT TableCode, x.ColCode, v.*
FROM TableA a CROSS APPLY   
     (VALUES (1, 'ParaName-1', Col1, 1),
             (2, 'ParaName-2', Col2, 2),
             (3, 'ParaName-3', NULL, 2)
     ) v(ColCode, ColumnName, [Values], RowNo)
WHERE TableCode = 23;

当您只能读取正确的值时,我认为没有理由使用row_number()。此外,VALUES是一个SQL关键字,因此它是一个非常糟糕的列名。