Sql server 如何使用MSSQL查询更改数据类型
。 . 。 . 我使用两个不同数据类型的表编写了一些sql查询代码。MSSQL版本为MSSQL server 2017开发者版Sql server 如何使用MSSQL查询更改数据类型,sql-server,Sql Server,。 . 。 . 我使用两个不同数据类型的表编写了一些sql查询代码。MSSQL版本为MSSQL server 2017开发者版 --Expected result student_id gender__id year_of_birth month_of_birth day_of_birth time_of_birth ID sex birthday 332748 2 200
--Expected result
student_id gender__id year_of_birth month_of_birth day_of_birth time_of_birth ID sex birthday
332748 2 2001 2 4 NULL 332748 2 1999-08-01
332804 2 2001 11 5 NULL 332804 1 1989-01-15
333152 2 NULL NULL NULL NULL 333152 1 24591
333455 1 2001 7 25 NULL 333455 1 2001-11-23
333593 1 2001 1 1 NULL 333593 2 1943-05-26
333693 1 2001 11 23 NULL 333693 2 1939-02-25
334304 1 2001 12 30 NULL 334304 2 1956-03-07
334326 1 NULL NULL NULL NULL 334326 2 1963-04-04
在调试top代码之后,出现了一些类似于此消息的问题
没有从nvarchar
值'AB332748'
更改为数据类型int
你知道如何解决这个问题吗?我还没有测试过这个,但这是我的猜测。这里没有预期的输出(OP已经承认我要求的),他们也没有告知他们有什么版本的SQL Server,所以我相信他们有SQL Server 2012+(如果他们使用2008或之前的版本,那么升级应该在“要做的事”列表中占据很高的位置) 如果这不起作用,或无法提供预期结果,请参见abvoe段落:
--problem sqlquery source code
SELECT ID,
sex,
birthday,
student_id,
gender_id,
year_of_birth,
month_of_birth,
day_of_birth,
time_of_birth
FROM ADB.dbo.PERSON
LEFT JOIN BDB.dbo.BASE_demo ON CAST(ADB.dbo.PERSON.student_id AS INT) = CAST(REPLACE(BDB.dbo.B_demo.ID, 'AB', '') AS int)
AND ADB.dbo.PERSON.student_id = BDB.dbo.BASE_demo.ID
WHERE BDB.dbo.BASE_demo.ID LIKE 'AB%'
AND ISNUMERIC(REPLACE(BDB.dbo.BASE_demo.ID, 'AB', '')) = 1;
请注意,我使用了
内部联接
。使用左联接
,然后引用中的表,其中
不处理NULL
s,将联接转换为隐式内部联接
样本数据存在问题-在ADB.dbo.PERSON
和BDB.dbo.BASE_demo
中只存在一条记录(ID:333455),假设ADB.dbo.PERSON.student_ID
映射到BDB.dbo.BASE_demo.ID
,只是在前面加了“AB”(根据OP的查询,情况似乎是这样)。因此,由于在ADB.dbo.PERSON
中没有ID为333152的记录,因此无法在提供的预期结果中复制该行
也就是说,我会使用CTE来相应地操作BDB.ID
,然后加入到该操作中。这是我的全部报告:
SELECT ID, --Missing Table Alias
sex, --Missing Table Alias
birthday, --Missing Table Alias
student_id, --Missing Table Alias
gender_id, --Missing Table Alias
year_of_birth, --Missing Table Alias
month_of_birth, --Missing Table Alias
day_of_birth, --Missing Table Alias
time_of_birth --Missing Table Alias
FROM ADB.dbo.PERSON P
JOIN BDB.dbo.BASE_demo B ON P.student_id TRY_CONVERT(int,STUFF(B.ID,1,2,'')) --This is non-SARGable
WHERE B.ID LIKE 'AB%'
AND TRY_CONVERT(int,STUFF(B.ID,1,2,'')) IS NOT NULL;
这是我的输出(对格式设置表示歉意-我不知道如何使它看起来像你在最初的帖子中所做的那样):
学生身份证性别身份证年份出生月份出生日期出生时间出生身份证性别生日
333423 2 2001 2 4无效无效无效无效
333503 2 2001 11 5无效无效无效无效
333243 2空空空空空空空空
33353612001 725无效无效无效无效
333199 1 2001 1 1空空空空空空空
33345512001 1123无效33345512001-11-23
338866 1 2001 12 30零零零零零零零零零零零
339365 1 NULL
您已经问过这个问题(虽然现在已删除)。您希望如何将“AB”转换为INT
?也许你需要提取数字部分,然后尝试转换。我对你的另一个重复(和删除)主题发表了评论。他们没变。@Honeybager是的。我知道。但我再次在这个网站上发帖,因为我的问题是“不能发表我的评论吗?”?你少了一个动词。@platanus是的,我知道。我在回答中提到了这一点。引用我自己的话:“如果这不起作用,或者不能提供预期的结果,请参阅abvoe段落”@platanus然后发布预期的结果,就像我已经要求了4次一样。谢谢。布莱恩。但是我测试了你们给出的代码,测试结果如下。我不能在BDB上确认身份证,性别,生日。BDB值都为空。正如我所说的,我现在没有可用的实例进行测试。明天早上我会看一看。@platanus,我在测试后更新了我的答案。我发现了一个多余的逗号,我把它去掉了。谢谢你对我的问题感兴趣。多亏了你,我解决了我的问题。很高兴听到这个消息,非常欢迎你。这就是我们来这里的原因。
--problem sqlquery source code
SELECT ID,
sex,
birthday,
student_id,
gender_id,
year_of_birth,
month_of_birth,
day_of_birth,
time_of_birth
FROM ADB.dbo.PERSON
LEFT JOIN BDB.dbo.BASE_demo ON CAST(ADB.dbo.PERSON.student_id AS INT) = CAST(REPLACE(BDB.dbo.B_demo.ID, 'AB', '') AS int)
AND ADB.dbo.PERSON.student_id = BDB.dbo.BASE_demo.ID
WHERE BDB.dbo.BASE_demo.ID LIKE 'AB%'
AND ISNUMERIC(REPLACE(BDB.dbo.BASE_demo.ID, 'AB', '')) = 1;
SELECT ID, --Missing Table Alias
sex, --Missing Table Alias
birthday, --Missing Table Alias
student_id, --Missing Table Alias
gender_id, --Missing Table Alias
year_of_birth, --Missing Table Alias
month_of_birth, --Missing Table Alias
day_of_birth, --Missing Table Alias
time_of_birth --Missing Table Alias
FROM ADB.dbo.PERSON P
JOIN BDB.dbo.BASE_demo B ON P.student_id TRY_CONVERT(int,STUFF(B.ID,1,2,'')) --This is non-SARGable
WHERE B.ID LIKE 'AB%'
AND TRY_CONVERT(int,STUFF(B.ID,1,2,'')) IS NOT NULL;
-- set up tables
Create Table ADB
(
Student_ID Int
, Gender_ID TinyInt
, Year_of_Birth Int
, Month_of_Birth Int
, Day_of_Birth Int
)
Create Table BDB
(
ID Varchar(20)
, Sex TinyInt
, Birthday Varchar(20)
)
Insert Into dbo.ADB
(
Student_ID
, Gender_ID
, Year_of_Birth
, Month_of_Birth
, Day_of_Birth
)
Select 333423, 2, 2001, 2, 4
Union All Select 333503, 2, 2001, 11, 5
Union All Select 333243, 2, NULL, NULL, NULL
Union All Select 333536, 1, 2001, 7, 25
Union All Select 333199, 1, 2001, 1, 1
Union All Select 333455, 1, 2001, 11, 23
Union All Select 338866, 1, 2001, 12, 30
Union All Select 339365, 1, NULL, NULL, Null
Insert Into dbo.BDB
(
ID
, Sex
, Birthday
)
Select 'AB332748', 2, '1999-08-01'
Union All Select 'AB332804', 1, '1989-01-15'
Union All Select 'AB333152', 1, '24591'
Union All Select 'AB333455', 1, '2001-11-23'
-- here's the code. I was on SQL 2012, so no Try_Cast()
;with CTE_bdb as
(
Select
Cast(Replace(ID, 'AB', '') as Int) As ID,
sex,
birthday
From dbo.BDB
Where ID LIKE 'AB%'
And IsNumeric(Replace(ID, 'AB', '')) = 1
)
Select
a.student_id,
a.gender_id,
a.year_of_birth,
a.month_of_birth,
a.day_of_birth,
Null as time_of_birth,
b.ID,
b.sex,
b.birthday
From dbo.ADB As a
Left Outer Join CTE_bdb as b
On A.student_id = b.ID