Generate three lines in the selected query

I have the following table

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

      

Table result:

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

      

After that I wrote one query in TableA which returns the following output

Request:

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;

      

Result:

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

      

And I need the following output:

Desired output:

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

      

+3


source to share


2 answers


Using a couple of common table expressions and together with a table value constructor  for numbers 1, 2, and 3, then using to return 3 rows for even if you don't have three rows in the original table. row_number()

(values (...),(...))

cross join

left join

TableCode

;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;

      

registry: http://rextester.com/CJU8986



returns:

+-----------+---------+--------------+----------+-------+
| 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


source


This will apparently do what you want:

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;

      



I see no reason to use row_number()

when you can just read the correct values. Also, VALUES

is a SQL keyword, so this is a really bad column name.

0


source







All Articles