Sql server 如何使用MSSQL查询更改数据类型

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

。 .

。 .

我使用两个不同数据类型的表编写了一些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            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