在从存储过程执行的查询中添加列
Adding columns in a query executed from a stored procedure
我在如下存储过程中有一个查询
select x,y from table
结果如下所示
x y
1 a
1 b
2 a
2 b
3 a
3 b
当 x 的值发生如下变化时,我需要添加一个空白列或零
x y
1 a
1 b
0 0
2 a
2 b
0 0
3 a
3 b
这可以由 sql 完成吗,或者因为我正在使用 birt 报告的数据,这可以用 birt 完成吗?
这是工作示例:
DECLARE @DataSource TABLE
(
[x] TINYINT
,[y] CHAR(1)
);
INSERT INTO @DataSource ([x], [y])
VALUES (1, 'a')
,(1, 'b')
,(2, 'a')
,(2, 'b')
,(3, 'a')
,(3, 'b');
WITH DataSource AS
(
SELECT *
FROM @DataSource
UNION ALL
-- the NULL will be always displayed on the first position
SELECT DISTINCT [x]
,NULL
FROM @DataSource
)
SELECT IIF([Rank] = 1, 0, [x])
,IIF([Rank] = 1, 0, [x])
FROM
(
SELECT ROW_NUMBER() OVER(PARTITION BY [x] ORDER BY [y]) AS [Rank]
,[x]
,[y]
FROM DataSource
) DS
ORDER BY [x]
,[Rank]
一些重要说明:
- 每个
x
的 NULL
值将始终1
排名
- 最终结果集按
x
和rank
排序
你需要UNION ALL来添加额外的行,你还需要ORDER它们,DENSE_RANK是为了去掉额外的行。
这是如何完成的:
DECLARE @t table(x int, y char(1))
INSERT @t values
(1,'a'),(1,'b'),(2,'a'),
(2,'b'),(3,'a'),(3,'b')
;WITH CTE AS
(
SELECT
2 rn, x,y, x sort from @t
UNION ALL
SELECT
distinct dense_rank() over (order by x desc) rn, 0, '0', x+.1 sort
FROM @t
)
SELECT x,y
FROM CTE
WHERE rn > 1
ORDER BY sort, x
结果:
x y
1 a
1 b
0 0
2 a
2 b
0 0
3 a
3 b
declare @t table (X varchar(1),Y varchar(1))
insert into @t(X,y) values (1,'A'),
(1,'B'),
(2,'A'),
(2,'B'),
(3,'A'),
(3,'B')
;with CTE As(
select X,Y,ROW_NUMBER()OVER(PARTITION BY X,Y ORDER BY X)RN
from @t
CROSS APPLY
(
values
('',NULL),
('',NULL)
) C(R, N)),
CTE2 AS(
Select CASE WHEN RN > 1 THEN 0 ELSE X END X ,
CASE WHEN RN > 1 THEN CAST(0 AS VARCHAR) ELSE Y END ID
,ROW_NUMBER()OVER(PARTITION BY X ORDER BY (SELECT NULL)) R
FROM CTE
)
select X,ID from cte2 where R <> 2
我在如下存储过程中有一个查询
select x,y from table
结果如下所示
x y
1 a
1 b
2 a
2 b
3 a
3 b
当 x 的值发生如下变化时,我需要添加一个空白列或零
x y
1 a
1 b
0 0
2 a
2 b
0 0
3 a
3 b
这可以由 sql 完成吗,或者因为我正在使用 birt 报告的数据,这可以用 birt 完成吗?
这是工作示例:
DECLARE @DataSource TABLE
(
[x] TINYINT
,[y] CHAR(1)
);
INSERT INTO @DataSource ([x], [y])
VALUES (1, 'a')
,(1, 'b')
,(2, 'a')
,(2, 'b')
,(3, 'a')
,(3, 'b');
WITH DataSource AS
(
SELECT *
FROM @DataSource
UNION ALL
-- the NULL will be always displayed on the first position
SELECT DISTINCT [x]
,NULL
FROM @DataSource
)
SELECT IIF([Rank] = 1, 0, [x])
,IIF([Rank] = 1, 0, [x])
FROM
(
SELECT ROW_NUMBER() OVER(PARTITION BY [x] ORDER BY [y]) AS [Rank]
,[x]
,[y]
FROM DataSource
) DS
ORDER BY [x]
,[Rank]
一些重要说明:
- 每个
x
的NULL
值将始终1
排名 - 最终结果集按
x
和rank
排序
你需要UNION ALL来添加额外的行,你还需要ORDER它们,DENSE_RANK是为了去掉额外的行。
这是如何完成的:
DECLARE @t table(x int, y char(1))
INSERT @t values
(1,'a'),(1,'b'),(2,'a'),
(2,'b'),(3,'a'),(3,'b')
;WITH CTE AS
(
SELECT
2 rn, x,y, x sort from @t
UNION ALL
SELECT
distinct dense_rank() over (order by x desc) rn, 0, '0', x+.1 sort
FROM @t
)
SELECT x,y
FROM CTE
WHERE rn > 1
ORDER BY sort, x
结果:
x y
1 a
1 b
0 0
2 a
2 b
0 0
3 a
3 b
declare @t table (X varchar(1),Y varchar(1))
insert into @t(X,y) values (1,'A'),
(1,'B'),
(2,'A'),
(2,'B'),
(3,'A'),
(3,'B')
;with CTE As(
select X,Y,ROW_NUMBER()OVER(PARTITION BY X,Y ORDER BY X)RN
from @t
CROSS APPLY
(
values
('',NULL),
('',NULL)
) C(R, N)),
CTE2 AS(
Select CASE WHEN RN > 1 THEN 0 ELSE X END X ,
CASE WHEN RN > 1 THEN CAST(0 AS VARCHAR) ELSE Y END ID
,ROW_NUMBER()OVER(PARTITION BY X ORDER BY (SELECT NULL)) R
FROM CTE
)
select X,ID from cte2 where R <> 2