我有一个场景,我从多个表中提取数据,并且输出为固定宽度格式。固定宽度的输出如下所示:
当前输出:
1001RJOHNKEITH25 20181017 NA
1002CDWANEKANE36 20181010 RR
1003CMIKAYLAGN44 20181011 RR
所需的输出:
1001RJOHNKEITH25 20181017 NA
1002CDWANEKANE36 NA
1003RMIKAYLAGN44 20181010 RR
在此输出中,1001是人员ID,R / C是硬编码的指示器,然后是名称,年龄和注册日期,记录类型。注册日期有一个条件。如果记录指示符是R,则将显示注册日期。否则,它应该为null。我不确定如何根据固定宽度字段编写条件。
附件中的妊娠期演示:https://rextester.com/MKESI50760
有帮助吗?!
答案 0 :(得分:1)
您只需要更新查询中的一行:
LEFT(CONCAT(isnull(t.registrationdate,''),space(14)),14), -- Registration date should show up when record indicator is 'R'
成为
LEFT(CONCAT(isnull(CASE WHEN t.registeredonline = '1' and t.recordtype = 'NA' THEN CONVERT(char(10), t.registrationdate,126) ELSE NULL END,''),space(14)),14), -- Registration date should show up when record indicator is 'R'
当记录指示符的逻辑评估为“ R”时,这将检查您的日期字段并放入空格而不是日期
需要'convert'语句,否则NULL日期将最终显示为1900-01-01。
希望有帮助。
答案 1 :(得分:1)
行
LEFT(CONCAT(isnull(t.registrationdate,''),space(14)),14)
成为
CASE WHEN t.registeredonline = '1' and t.recordtype = 'NA' THEN LEFT(CONCAT(isnull(t.registrationdate,''),space(14)),14) ELSE SPACE(14) END, -- Registration date should show up when record indicator is 'R'
只需用条件将原始行括起来,看看结果是否为'R'。 该条件显示在您的链接的查询中。
答案 2 :(得分:1)
好的,这有点混乱。但是由于输出是固定宽度的,因此您始终可以将查询放入视图或CTE中(如下所示),然后通过SUBSTRING函数访问字符串中的特定位置。
这样做有很多缺点。如果有人更改了要连接的字段的顺序或大小,则一切都会中断。因此,本着回答您的问题的精神..这是一种解决方法。但是我认为这不是一个好方法。
WITH BaseQuery as
(
select
t.Cid,
cast
(
concat(
LEFT(CONCAT(isnull(t.Cid,''),space(5)),5), -- PersonID
LEFT(CONCAT(isnull
((case when t.registeredonline = '1' and t.recordtype = 'NA' then 'R'
else 'C' end),''),space(10)),10),-- Record Indicator
LEFT(CONCAT(isnull(t.name,''),space(14)),14), --name
LEFT(CONCAT(isnull(t.age,''),space(5)),5), --age
LEFT(CONCAT(isnull(t.registrationdate,''),space(14)),14), -- Registration date should show up when record indicator is 'R'
LEFT(CONCAT(isnull(t.recordtype,''),space(3)),3) --Record type
) as nvarchar(max)
) result
from #temp t
)
SELECT
CONCAT(
SUBSTRING(result, 1, 34) -- portion before the 'registration date' region
, CASE WHEN SUBSTRING (RESULT, 6, 1) = 'R' THEN SUBSTRING (RESULT, 35, 10) ELSE SPACE(10) END
, SUBSTRING (RESULT, 46, 5)
)
FROM
BaseQuery
这给出结果:
1001 R JOHNKEITH 25 2018-10-17 NA
1002 C DWANEKANE 36 RR
1003 C JOHNKEITH 44 RR
答案 3 :(得分:1)
使用固定宽度的数据进行处理:
固定宽度的文本文件或字符串中的数据按行排列, 列,每行一个条目。每列都有固定的宽度, 以字符指定,它确定最大数据量 它可以包含。没有定界符用于分隔字段中的字段 文件。
在T-SQL中解析该数据,您可以使用SUBSTRING
https://docs.microsoft.com/en-us/sql/t-sql/functions/substring-transact-sql?view=sql-server-2017
SUBSTRING ( expression ,start , length )
这是一个例子:
DECLARE @SampleData TABLE
(
[LineData] NVARCHAR(255)
);
INSERT INTO @SampleData (
[LineData]
)
VALUES ( '1001RJOHNKEITH25 20181017 NA' )
, ( '1002CDWANEKANE36 20181010 RR' )
, ( '1003CMIKAYLAGN44 20181011 RR' );
SELECT SUBSTRING([LineData], 1, 4) AS [PersonId]
, SUBSTRING([LineData], 5, 1) AS [Indicator]
, SUBSTRING([LineData], 6, 9) AS [Name]
, SUBSTRING([LineData], 15, 2) AS [Age]
, SUBSTRING([LineData], 18, 8) AS [RegDate]
, SUBSTRING([LineData], 27, 2) AS [RecordType]
, *
FROM @SampleData;
因此,在您的示例中,您需要评估“指标”是否为“ R”,您可以使用以下方法获得该值:
SUBSTRING([LineData], 5, 1)
不确定如何适应您的任务。根据其他评论,还有更多有关如何确定“指标”的信息。
不太理想,但是您可以解析所有字段,然后将它们放回去进行该指标字段的评估,或者在评估指标是否为R时使用case语句中的内容将日期替换为空白。
DECLARE @SampleData TABLE
(
[LineData] NVARCHAR(255)
);
INSERT INTO @SampleData (
[LineData]
)
VALUES ( '1001RJOHNKEITH25 20181017 NA' )
, ( '1002CDWANEKANE36 20181010 RR' )
, ( '1003CMIKAYLAGN44 20181011 RR' );
--We check for R using substring
--when not equal to R we replace where Registration date in the string was with blanks.
SELECT CASE WHEN SUBSTRING([LineData], 5, 1) = 'R' THEN [LineData]
ELSE STUFF([LineData], 18, 8, ' ')
END AS [LineData]
FROM @SampleData;
答案 4 :(得分:-1)
选择ColA,然后选择ColB(在此处为标准),然后以NULL ELSE ColB结尾,以ColB,ColC结尾