将一列分成多列 - SQL

发布于 2024-12-10 01:40:43 字数 834 浏览 0 评论 0原文

我有一个名为 @months 的列,它以这种格式存储月份

@month = '01-03-05-11-12'

我想要一个 SELECT 查询,将此列分为 12 个,使其成为一月、二月、三月

我的每条记录都有此列在前。因此,如果记录中包含 @month = '01-03',它将显示在 1 月和 3 月下。这样的事情可以做吗?或者任何接近的东西就足够了。

我使用了 case 语句,但无法得出结果。


如果有人想尝试,请代码

create table recs(
id int not null primary key,
cust_name varchar(20),
callmonth varchar(36)
)

insert into recs values(1,'john','01-12')
insert into recs values(2,'Jessica','02-06')
insert into recs values(3,'Charlie','01-06')
insert into recs values(4,'steale','03-04')
insert into recs values(5,'Silica','01-02-03-04-05-06-07-08-09-10-11-12')
insert into recs values(6,'Luder','01-03-05-07-09-11-12')
insert into recs values(7,'Panther','01-06-12')
insert into recs values(8,'Dinky','03-04-15')

I have a column called @months which stores months in this format

@month = '01-03-05-11-12'

I would like to have a SELECT query that divides this column into 12, making it Jan, Feb, March

Each of my record has this column in front. So if a record has @month = '01-03' in it, it shows under January and March. Can something like that be done? Or anything close is good enough.

I played with case statement but could not produce the results.


Code if anyone wants to try

create table recs(
id int not null primary key,
cust_name varchar(20),
callmonth varchar(36)
)

insert into recs values(1,'john','01-12')
insert into recs values(2,'Jessica','02-06')
insert into recs values(3,'Charlie','01-06')
insert into recs values(4,'steale','03-04')
insert into recs values(5,'Silica','01-02-03-04-05-06-07-08-09-10-11-12')
insert into recs values(6,'Luder','01-03-05-07-09-11-12')
insert into recs values(7,'Panther','01-06-12')
insert into recs values(8,'Dinky','03-04-15')

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

尐籹人 2024-12-17 01:40:43

我可能不清楚您要做什么,但您可以使用以下命令将其分为 12 个表:

INSERT INTO January_table
SELECT *
FROM Original_table
WHERE month LIKE '%01%';

对每个月执行此操作,它应该为您提供 12 个仅包含该月值的表。然后您可以使用视图来组合它们。

或者,如果您正在查找一个查询,则可以使用如下所示的 case 语句:

INSERT INTO table
SELECT *
    CASE
    WHEN month LIKE '%01%' THEN 'True'
    ELSE 'False'
    END,
    CASE
    WHEN month LIKE '%02%' THEN 'True'
    ...
FROM Original_table;

这将生成一个表,其中包含原始表中的所有字段,后跟 12 个“每月列”,每个列都有 true 或 false表示该月是否存在于该行中。

I may be unclear about what you are trying to do, but you can devide into 12 tables using the following:

INSERT INTO January_table
SELECT *
FROM Original_table
WHERE month LIKE '%01%';

Do this for each month and it should give you 12 tables containing only the values that have that month. You could then use a view to combine them.

Alternatively, if you are looking for one query, you might be able to use a case statement like the one below:

INSERT INTO table
SELECT *
    CASE
    WHEN month LIKE '%01%' THEN 'True'
    ELSE 'False'
    END,
    CASE
    WHEN month LIKE '%02%' THEN 'True'
    ...
FROM Original_table;

This will yield a table with all fields from the original table, followed by 12 "monthly columns" each with a true or false representing whether that month is present in that row.

居里长安 2024-12-17 01:40:43

我同意其他海报 - 你应该改变你的桌子设计 - 因为你有它,它的形式非常糟糕。

您的案例陈述通常应采用以下形式:

case when instr(month,'01') > 0 then 'Jan'

i agree with other posters - you should change your table design -as you have it it is very poor form.

your case statement should generally be of this form:

case when instr(month,'01') > 0 then 'Jan'
浅笑依然 2024-12-17 01:40:43

您应该用“-”分隔这些值 - 然后您将拥有一个表

,然后您应该查看该值是否在该表及其字符串名称中。

ps

你必须有一个像这样的表:

01 - jan
02 - feb
...
...

比方说:
表月份 (TBLMNTH) 将具有 ( id , name )

例如:

1 |   jan  
2 |   feb
select name from  TBLMNTH where @month CHARINDEX(name , @month)>-1

you should split the values by '-' - and then youll have a table

and then you should see if that value is inside this table + its string name.

p.s.

You have to hav a table like this :

01 - jan
02 - feb
...
...

let say :
table months ( TBLMNTH) will have ( id , name )

e.g. :

1 |   jan  
2 |   feb
select name from  TBLMNTH where @month CHARINDEX(name , @month)>-1
奶茶白久 2024-12-17 01:40:43

创建 SPLIT 函数并将其与 DATENAME 一起使用,如下所示,您可以获取字符串格式的月份列表。我认为这会解决您的部分问题。

select  DATENAME(month, DATEADD(month, convert(int, val) , -1 )) AS month_str 
from  SPLIT('01-03-05-11-12', '-')

结果将是(在 mssql 服务器中测试;它正在工作)

January
March
May
November
December

UDF

CREATE FUNCTION SPLIT
(
 @s nvarchar(max),
 @splitChar nchar(1)
)
returns @t table (id int identity(1,1), val nvarchar(max))
as
begin

declare @i int, @j int
select @i = 0, @j = (len(@s) - len(replace(@s,@splitChar,'')))

;with cte 
as
(
 select
  i = @i + 1,
  s = @s, 
  n = substring(@s, 0, charindex(@splitChar, @s)),
  m = substring(@s, charindex(@splitChar, @s)+1, len(@s) - charindex(@splitChar, @s))

 union all

 select 
  i = cte.i + 1,
  s = cte.m, 
  n = substring(cte.m, 0, charindex(@splitChar, cte.m)),
  m = substring(
   cte.m,
   charindex(@splitChar, cte.m) + 1,
   len(cte.m)-charindex(@splitChar, cte.m)
 )
 from cte
 where i <= @j
)
insert into @t (val)
select pieces
from 
(
 select 
 ltrim(rtrim(case when i <= @j then n else m end)) pieces
 from cte
) t
where
 len(pieces) > 0
option (maxrecursion 0)

return

end

GO

Create SPLIT function and use it with DATENAME as below , you can get list of months in string format..I think this will solve part of your problem.

select  DATENAME(month, DATEADD(month, convert(int, val) , -1 )) AS month_str 
from  SPLIT('01-03-05-11-12', '-')

Result will be (tested in mssql server;it's working)

January
March
May
November
December

UDF

CREATE FUNCTION SPLIT
(
 @s nvarchar(max),
 @splitChar nchar(1)
)
returns @t table (id int identity(1,1), val nvarchar(max))
as
begin

declare @i int, @j int
select @i = 0, @j = (len(@s) - len(replace(@s,@splitChar,'')))

;with cte 
as
(
 select
  i = @i + 1,
  s = @s, 
  n = substring(@s, 0, charindex(@splitChar, @s)),
  m = substring(@s, charindex(@splitChar, @s)+1, len(@s) - charindex(@splitChar, @s))

 union all

 select 
  i = cte.i + 1,
  s = cte.m, 
  n = substring(cte.m, 0, charindex(@splitChar, cte.m)),
  m = substring(
   cte.m,
   charindex(@splitChar, cte.m) + 1,
   len(cte.m)-charindex(@splitChar, cte.m)
 )
 from cte
 where i <= @j
)
insert into @t (val)
select pieces
from 
(
 select 
 ltrim(rtrim(case when i <= @j then n else m end)) pieces
 from cte
) t
where
 len(pieces) > 0
option (maxrecursion 0)

return

end

GO
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文