我正在使用SQL Server 2014.我相信我的要求相当简单。我有一个表包含一个字段,其中包含一个存储为VARCHAR
的日期值,另一个表包含一个字段,其中包含一个存储为INT
的日期值。
VARCHAR
字段中的日期值存储如下: 2015M01
INT
字段中的数据值存储如下: 201501
我需要使用EXCEPT
将这些表格相互比较。我的思考过程是以某种方式从VARCHAR
值中提取或修剪“M”,看看它是否会让我比较两者。如果有人有更好的想法,例如使用CAST来更改日期格式,或者可以随意提出建议。
我还担心即使从VARCHAR
中提取“M”也可能会阻止比较,因为仍然会保留VARCHAR
而另一个仍为INT
。如果可能,通过T-SQL查询即时转换,这也是很好的建议。 :)
答案 0 :(得分:2)
SELECT A.*, B.*
FROM TableA A
INNER JOIN
(SELECT intField
FROM TableB
) as B
ON CONVERT(INT, REPLACE(A.varcharField, 'M', '')) = B.intField
答案 1 :(得分:1)
如果您希望第一个表中的所有内容都不在第二个表中,您可能会考虑这样的事情:
select t1.*
from t1
where not exists (select 1
from t2
where cast(replace(t1.varcharfield, 'M', '') as int) = t2.intfield
);
为了您的目的,这应该足够接近except
。
我应该补充一点,您可能需要在where
语句中包含其他列。但是,这个问题只提到了一个专栏,所以我不知道那些是什么。
答案 2 :(得分:1)
由于您说您已经拥有查询并且正在使用EXCEPT
,因此您只需在包含VARCHAR
值的查询中更改该“date”字段的定义,以使其与INT
匹配{1}}其他查询的格式。例如:
SELECT Field1, CONVERT(INT, REPLACE(VarcharDateField, 'M', '')) AS [DateField], Field3
FROM TableA
EXCEPT
SELECT Field1, IntDateField, Field3
FROM TableB
但是,虽然我意识到这可能不可行,但如果你能做到这一点,你最好的选择就是改变表中VARCHAR
字段的数据的存储方式,以便它是实际上是INT
格式与表格相同,数据已存储为INT
。那么你就不必担心像这样的情况。
含义:
INT
字段向表中添加VARCHAR
字段。UPDATE
,将INT
字段设置为删除了M
的字符串值。M
删除逻辑。然后您不必更改任何应用程序代码INSERTs和UPDATEs。你甚至不需要告诉任何你这样做的人。INT
转换为VARCHAR
并添加M
出去的路上。然后,您不必更改从数据库获取数据的任何应用程序代码。你甚至不需要告诉任何你这样做的人。这是为您的数据库提供存储过程API非常方便的众多原因之一。我想ORM可以重建,但是你仍然需要重新编译,即使所有的代码引用都是自动更新的。但是使数据类型更改(甚至将字段移动到另一个表,甚至用简单的CASE
语句替换一个字段)“在幕后”并屏蔽它,以便控制之外的任何代码都不会知道发生了变化,并不像大多数人想象的那么困难。我已经完成了所有这些操作(数据类型更改,将字段移动到不同的表,用简单的逻辑替换字段等等),它会花费你很多时间,直到应用程序代码可以更新。那可能是另一个处理这个问题的团队。也许他们的日程安排不允许在该区域进行任何更改(加上测试)3个月。好。它们准备就绪时会在那里等待它们。如果有几个区域要更新,那么它们可以一次完成一个。您甚至可以为任何更新的应用程序代码创建并行运行的新存储过程,以使正确的INT
数据类型作为输入参数。一旦所有对VARCHAR
值的引用都消失了,就删除这些存储过程的原始版本。
答案 3 :(得分:0)
您可以使用char列在表上创建持久化视图,并使用计算列删除M
。然后,您可以JOIN
查看包含INT
列的表格。
CREATE VIEW dbo.PersistedView
WITH SCHEMA_BINDING
AS
SELECT ConvertedDateCol = CONVERT(INT, REPLACE(VarcharCol, 'M', ''))
--, other columns including the PK, etc
FROM dbo.TablewithCharColumn;
CREATE CLUSTERED INDEX IX_PersistedView
ON dbo.PersistedView(<the PK column>);
SELECT *
FROM dbo.PersistedView pv
INNER JOIN dbo.TableWithIntColumn ic ON pv.ConvertedDateCol = ic.IntDateCol;
如果您提供两个表的实际详细信息,我将编辑我的答案以使其更清晰。
与每次运行{SELECT
和CONVERT
相比,加入两列的REPLACE
语句中包含计算列的持久视图的效果会更好1}}陈述。
但是,持久化视图会略微减慢插入基础表的速度,并且会阻止您对基础表进行DDL更改。
如果您希望不通过模式绑定视图保留值,则可以在表本身上创建非持久计算列,然后在该列上创建非聚集索引。如果您使用SELECT
或WHERE
条款中的计算列,您可能会看到一些好处。
举例来说:
JOIN
结果: