--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
都没有改变。
您知道如何解决此问题吗?
答案 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_id
和BDB.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