将列转换为rowss [英] Convert the columns into rowss

查看:54
本文介绍了将列转换为rowss的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

 选择  1  convert  char  12 ),b.cbm_batch_start_dt, 106  as  Startdt,
convert char 12 ),b.cbm_batch_end_dt, 106 as Enddt,a.course as 课程来自 tb_rankwise_coursesettings as a,CO_BATCH_MASTER as b
其中 a.course = b.cmn_minor_code a.Rank = ' CHENGR' b.cbm_active< > ' d'
b.cbm_batch_start_dt ' 2015-08-01 00: 00:00.000' ' 2015- 12-30 00:00:00.000'
订单 b.cbm_batch_start_dt asc





当我按以下方式运行上述查询输出时

 Startdt Enddt课程
2015年8月10日2015年8月21日REO
2015年8月24日2015年9月4日REO
2015年12月14日2015年12月25日REO





但我希望输出如下

 REO 
2015年8月10日2015年8月21日
2015年8月24日2015年9月4日
2015年12月14日2015年12月25日





获取输出我必须做出的改变我上面的SQL查询。

解决方案

1。您帖子的标题与您想要的内容不符。 2.你真的不应该试图在SQL中显示结果 - 使用你的表示层来美化输出。

3.避免做CONVERT直到你绝对必须... 。即你的表示层。

4.从原始表中包含样本数据而不是查询的输出总是一个好主意(它可以帮助我们更快地帮助你)



问题是你有一行只包含一个字符串

 REO 



后跟n行包含字符串

 2015年8月10日2015年8月21日
2015年8月24日2015年9月4日
2015年12月14日2015年12月25日



SQL查询结果集中的所有行都是相同的,因此您将不得不摆弄它以便每一行包含两个字符列。

我能够使用此示例数据获取当前输出(注意我添加了额外的'课程')

 插入 进入 tb_rankwise_coursesettings  VALUES  
(< span class =code-string>' REO'' CHENGR'),
' XXX'' CHENGR'

INSERT INTO CO_BATCH_MASTER VALUES
' 2015年8月10日'' 2015年8月21日'' REO'' a'),
' 2015年8月24日'' 2015年9月4日'' REO'' a'),
' 2015年12月14日'' 2015年12月25日'' REO'' a'),
' 2015年8月10日'' 21 2015年8月'' XXX' ' a'),
' 2015年8月24日'' 2015年9月4日'' XXX'' < span class =code-string> a'),
' 2015年12月14日'' 2015年12月25日' ' XXX'' a'



然后我希望每个课程都有一行没有日期,然后每个课程的所有行都有一个行号(相对于课程名)。我选择这样做如下。注意我使用的是ANSI INNER JOIN,而不是您使用的旧语法。我也使用课程名称PARTION的ROW_NUMBER()函数:

 选择 a.course ,cbm_batch_start_dt,cbm_batch_end_dt,
ROW_NUMBER() OVER PARTITION BY a.course ORDER BY a.course,cbm_batch_start_dt) AS rn
来自 tb_rankwise_coursesettings as a
INNER JOIN CO_BATCH_MASTER as b ON a.course = b.cmn_minor_code
其中 a.Rank = ' CHENGR' b.cbm_active<> ' d'
b.cbm_batch_start_dt ' 2015-08-01 00: 00:00.000' ' 2015- 12-30 00:00:00.000'

UNION 所有

选择 DISTINCT a.course, null null 0 AS rn
FROM tb_rankwise_coursesettings
INNER JOIN CO_BATCH_MASTER as b ON a.co urse = b.cmn_minor_code
WHERE a.Rank = ' CHENGR' b.cbm_active<> ' d'
b.cbm_batch_start_dt ' 2015-08-01 00: 00:00.000' ' 2015- 12-30 00:00:00.000'

订单 当然, asc



这给了我以下结果

 课程Startdt EndDt rn  
REO NULL NULL 0
REO 2015-08-10 2015-08-21 1
REO 2015-08- 24 2015-09-04 2
REO 2015-12-14 2015-12-25 3
XXX NULL NULL 0
XXX 2015-08-10 2015-08-21 1
XXX 2015-08-24 2015-09-04 2
XXX 2015-12-14 2015-12-25 3



您的演示层可以采用此方式阙ry并且只显示 rn = 0 的课程名称,并且只显示 rn<> 0 的日期列,改变日期同时显示的方式。

但是,这里有一个例子说明如何在SQL中完成(可能不是应该是)使用公用表表达式

;   cte  AS  

选择 a.course,cbm_batch_start_dt,cbm_batch_end_dt,
ROW_NUMBER() OVER PARTITION BY a.course ORDER BY a.course,cbm_batch_start_dt) AS rn
< span class =code-keyword> from tb_rankwise_coursesettings as a
INNER JOIN CO_BATCH_MASTER as b ON a.course = b.cmn_minor_code
其中 a.Rank = ' CHENGR' b.cbm_active<> ' d'
b.cbm_batch_start_dt ' 2015-08-01 00: 00:00.000' ' 2015- 12-30 00:00:00.000'
UNION 所有
选择 DISTINCT a.course,' '' ' 0 AS rn
FROM tb_rankwise_coursesettings
INNER JOIN CO_BATCH_MASTER as b ON a.course = b.cmn_minor_code
WHERE a。 Rank = ' CHENGR' b。 cbm_active<> ' d'
b.cbm_batch_start_dt ' 2015-08-01 00: 00:00.000' ' 2015- 12-30 00:00:00.000'

SELECT course = CASE WHEN rn = 0 那么 course ELSE ' ' END
StartDt = CASE WHEN rn< ;> 0 THEN convert char 12 ),cbm_batch_start_dt, 106 ELSE ' ' END
EndDt = CASE WHEN rn<> 0 那么 convert char 12 ) ,cbm_batch_end_dt, 106 ELSE ' < span class =code-string>' END
FROM cte
ORDER BY cte.course,rn



给出结果

 当然StartDt EndDt  
REO
2015年8月10日2015年8月21日
2 2015年8月4日2015年9月4日
2015年12月14日2015年12月25日
XXX
2015年8月10日2015年8月21日
2015年8月24日2015年9月4日
2015年12月14日25日2015



警告:因为我使用了

 SELECT course = CASE WHEN rn = 0 THEN当然ELSE'' END,

我必须使用

  ORDER   BY   cte。当然,

因为该列具有相同的名称,否则排序顺序将所有具有空白日期的行推送到结果集的末尾


select 1, convert(char(12),b.cbm_batch_start_dt,106) as Startdt,
convert(char(12),b.cbm_batch_end_dt,106) as Enddt,a.course as Course from tb_rankwise_coursesettings as a,CO_BATCH_MASTER as b
where a.course = b.cmn_minor_code and a.Rank = 'CHENGR' and b.cbm_active <> 'd'  and  
b.cbm_batch_start_dt between '2015-08-01 00:00:00.000' and '2015-12-30 00:00:00.000'
order by b.cbm_batch_start_dt asc



When i run the above query output as follows

Startdt             Enddt             Course
10 Aug 2015         21 Aug 2015         REO
24 Aug 2015         04 Sep 2015         REO
14 Dec 2015         25 Dec 2015         REO



But i want the output as follows

      REO
10 Aug 2015         21 Aug 2015
24 Aug 2015         04 Sep 2015
14 Dec 2015         25 Dec 2015



for getting output what changes i have to made in my above sql query.

解决方案

1. The title of your post does not match up with what you are saying you want. 2. You really should not be attempting to "display" the results in SQL like that - use your presentation layer to "prettify" the output.
3. Avoid doing CONVERT until you absolutely have to ... i.e. in your presentation layer.
4. It's always a good idea to include sample data from the raw tables instead the output from your query (it helps us to help you quicker)

The problem is that you have a row that consists of just a string

REO


followed by n rows that consist of strings

10 Aug 2015 21 Aug 2015
24 Aug 2015 04 Sep 2015
14 Dec 2015 25 Dec 2015


All the rows in the result set of a SQL query will be the same, so you are going to have to fiddle with this so that every row consists of two character columns.
I was able to get your current output using this sample data (note I've added an extra 'course')

insert into tb_rankwise_coursesettings VALUES
('REO','CHENGR'),
('XXX','CHENGR')

INSERT INTO CO_BATCH_MASTER VALUES
('10 Aug 2015','21 Aug 2015','REO','a'),
('24 Aug 2015','04 Sep 2015','REO','a'),
('14 Dec 2015','25 Dec 2015','REO','a'),
('10 Aug 2015','21 Aug 2015','XXX','a'),
('24 Aug 2015','04 Sep 2015','XXX','a'),
('14 Dec 2015','25 Dec 2015','XXX','a')


I then wanted to get a row for each course with no dates on it then all of the rows for each course with a row number (relative to the course name). I chose to do that as follows. Note I'm using an ANSI INNER JOIN rather than the old syntax you used. I'm also using the ROW_NUMBER() function PARTIONed by the course name:

select a.course, cbm_batch_start_dt, cbm_batch_end_dt, 
	ROW_NUMBER() OVER(PARTITION BY a.course ORDER BY a.course, cbm_batch_start_dt) AS rn
from tb_rankwise_coursesettings as a
INNER JOIN CO_BATCH_MASTER as b ON a.course = b.cmn_minor_code 
where a.Rank = 'CHENGR' and b.cbm_active <> 'd'  and  
b.cbm_batch_start_dt between '2015-08-01 00:00:00.000' and '2015-12-30 00:00:00.000'

UNION ALL

select DISTINCT a.course,null,null, 0 AS rn
FROM tb_rankwise_coursesettings a
INNER JOIN CO_BATCH_MASTER as b ON a.course = b.cmn_minor_code 
WHERE a.Rank = 'CHENGR' and b.cbm_active <> 'd'  and  
b.cbm_batch_start_dt between '2015-08-01 00:00:00.000' and '2015-12-30 00:00:00.000'

order by course,rn asc


That gave me the following results

Course  Startdt         EndDt          rn
REO	NULL	        NULL	        0
REO	2015-08-10	2015-08-21	1
REO	2015-08-24	2015-09-04	2
REO	2015-12-14	2015-12-25	3
XXX	NULL	        NULL	        0
XXX	2015-08-10	2015-08-21	1
XXX	2015-08-24	2015-09-04	2
XXX	2015-12-14	2015-12-25	3


Your presentation layer could take this query and only display the course name where rn=0 and only display the date columns where rn<>0, changing the way the dates are displayed at the same time.
However, here is an example of how that could be done in SQL ("could be" not "should be") using a Common Table Expression

;with cte AS
(
	select a.course, cbm_batch_start_dt,cbm_batch_end_dt,
		ROW_NUMBER() OVER(PARTITION BY a.course ORDER BY a.course, cbm_batch_start_dt) AS rn
	from tb_rankwise_coursesettings as a
	INNER JOIN CO_BATCH_MASTER as b ON a.course = b.cmn_minor_code 
	where a.Rank = 'CHENGR' and b.cbm_active <> 'd'  and  
		b.cbm_batch_start_dt between '2015-08-01 00:00:00.000' and '2015-12-30 00:00:00.000'
	UNION ALL
	select DISTINCT a.course,'','', 0 AS rn
	FROM tb_rankwise_coursesettings a
	INNER JOIN CO_BATCH_MASTER as b ON a.course = b.cmn_minor_code 
	WHERE a.Rank = 'CHENGR' and b.cbm_active <> 'd'  and  
		b.cbm_batch_start_dt between '2015-08-01 00:00:00.000' and '2015-12-30 00:00:00.000'
)
SELECT course = CASE WHEN rn = 0 THEN course ELSE '' END,
StartDt = CASE WHEN rn<>0 THEN convert(char(12),cbm_batch_start_dt,106) ELSE '' END,
EndDt = CASE WHEN rn<>0 THEN convert(char(12),cbm_batch_end_dt,106) ELSE '' END
FROM cte
ORDER BY cte.course, rn


Which gives the results

course  StartDt         EndDt
REO		
	10 Aug 2015 	21 Aug 2015 
	24 Aug 2015 	04 Sep 2015 
	14 Dec 2015 	25 Dec 2015 
XXX		
	10 Aug 2015 	21 Aug 2015 
	24 Aug 2015 	04 Sep 2015 
	14 Dec 2015 	25 Dec 2015 


Word of warning: Because I used

SELECT course = CASE WHEN rn = 0 THEN course ELSE '' END,

I have to use

ORDER BY cte.course, rn

because the column has the same name, otherwise the sort order pushes all of the rows with blank dates to the end of the result set


这篇关于将列转换为rowss的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆