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

时间:2018-08-10 09:39:47

标签: sql-server

--ADB sample data
student_id  gender__id  year_of_birth   month_of_birth  day_of_birth
333423              2           2001            2             4
333503              2           2001            11            5
333243              2           NULL            NULL          NULL
333536              1           2001            7             25
333199              1           2001            1             1
333455              1           2001            11            23
338866              1           2001            12            30
339365              1           NULL            NULL          NULL

。 。

--BDB sample data
ID         sex      birthday
AB332748    2   1999-08-01
AB332804    1   1989-01-15
AB333152    1   24591
AB333455    1   2001-11-23

。 。

 --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

我使用两个不同数据类型的表制作了一些sql查询代码。 MSSQL版本是MSSQL Server 2017开发人员版本。

--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;

调试顶级代码后,出现类似此消息的问题。

nvarchar'AB332748'到数据类型int都没有改变。

您知道如何解决此问题吗?

2 个答案:

答案 0 :(得分:0)

我没有测试过,但是,这是我的猜测。这里没有预期的输出(OP已经确认了我的要求),也没有告知他们所拥有的SQL Server版本,所以我相信他们拥有SQl Server 2012+(如果他们使用的是2008或之前的版本,升级在“要做的事情”列表中应该很高。

如果这不起作用或无法提供预期的结果,请参见abvoe段落:

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;

请注意,我已经使用了INNER JOIN。使用LEFT JOIN,然后引用WHERE中的表而不应对NULL的情况,将联接变成隐式的INNER JOIN

答案 1 :(得分:0)

示例数据存在问题-假设ADB.dbo.PERSON映射到BDB.dbo.BASE_demo,则ADB.dbo.PERSON.student_idBDB.dbo.BASE_demo.ID中仅存在一条记录(ID:333455),只是在前面加上“ AB”(根据OP的查询似乎是这种情况)。因此,由于ADB.dbo.PERSON中没有ID为333152的记录,因此无法在提供的Expected结果中复制该行。

也就是说,我将使用CTE来相应地操纵BDB.ID,然后加入其中。这是我的完整副本:

-- 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

这是我的输出(格式很抱歉-我不知道如何使它看起来像您在最初的帖子中那样):

student_id gender_id year_of_birth month_of_birth day_of_birth time_of_birth ID sex birthday 333423 2 2001 2 4 NULL NULL NULL NULL 333503 2 2001 11 5 NULL NULL NULL NULL 333243 2 NULL NULL NULL NULL NULL NULL NULL 333536 1 2001 7 25 NULL NULL NULL NULL 333199 1 2001 1 1 NULL NULL NULL NULL 333455 1 2001 11 23 NULL 333455 1 2001-11-23 338866 1 2001 12 30 NULL NULL NULL NULL 339365 1 NULL NULL NULL NULL NULL NULL NULL