替换SQL中文本字段的“不在”
我正在尝试检测文本字段的新值。我将主查询的值与旧值的子查询进行比较。因为字段是文本字段,所以我不能使用NOT IN子句 以下是数据:替换SQL中文本字段的“不在”,sql,sql-server,sql-server-2008,Sql,Sql Server,Sql Server 2008,我正在尝试检测文本字段的新值。我将主查询的值与旧值的子查询进行比较。因为字段是文本字段,所以我不能使用NOT IN子句 以下是数据: On Day 1: infoField: Text1, Text2, Text3 On Day 2: infoField: Text1, Text2, Text3, Text4 在我的查询中,我想返回Text4,因为它是新的。 我的问题是: SELECT * FROM myLog WHERE eventDate > '2017-03-28 00:00:00
On Day 1:
infoField: Text1, Text2, Text3
On Day 2:
infoField: Text1, Text2, Text3, Text4
在我的查询中,我想返回Text4,因为它是新的。
我的问题是:
SELECT *
FROM myLog
WHERE eventDate > '2017-03-28 00:00:00'
AND entryText LIKE 'Text%'
AND NOT EXISTS
(SELECT *
FROM myLog
WHERE entryText LIKE 'Text%'
AND eventDate > '2017-03-27 00:00:00'
AND eventDate < '2017-03-28 00:00:00'
此查询没有返回任何内容。有什么方法可以对文本字段执行此类型的查询吗?我不理解您的问题,但此查询也可以编写得很好
SELECT *
FROM myLog ml
WHERE eventDate > '2017-03-28 00:00:00'
AND entryText LIKE 'Text%'
AND ml.idField not in
(SELECT idField
FROM myLog
WHERE entryText LIKE 'Text%'
AND eventDate > '2017-03-27 00:00:00'
AND eventDate < '2017-03-28 00:00:00'
)
或者,您可以左键联接两个表,并获得所需的结果,如下所示
SELECT *
FROM myLog m1
WHERE eventDate > '2017-03-28 00:00:00'
AND entryText LIKE 'Text%'
left join
(SELECT *
FROM myLog
WHERE entryText LIKE 'Text%'
AND eventDate > '2017-03-27 00:00:00'
AND eventDate < '2017-03-28 00:00:00'
) m2 on m1.idField =m2.IdField
where m1.idField is null
我不理解你的问题,但这个问题也可以写得很好
SELECT *
FROM myLog ml
WHERE eventDate > '2017-03-28 00:00:00'
AND entryText LIKE 'Text%'
AND ml.idField not in
(SELECT idField
FROM myLog
WHERE entryText LIKE 'Text%'
AND eventDate > '2017-03-27 00:00:00'
AND eventDate < '2017-03-28 00:00:00'
)
或者,您可以左键联接两个表,并获得所需的结果,如下所示
SELECT *
FROM myLog m1
WHERE eventDate > '2017-03-28 00:00:00'
AND entryText LIKE 'Text%'
left join
(SELECT *
FROM myLog
WHERE entryText LIKE 'Text%'
AND eventDate > '2017-03-27 00:00:00'
AND eventDate < '2017-03-28 00:00:00'
) m2 on m1.idField =m2.IdField
where m1.idField is null
啊,我明白了。您希望比较后期和前期的确切文本。您只需要一个关联子句:
SELECT l.*
FROM myLog l
WHERE l.eventDate >= '2017-03-28' AND l. entryText LIKE 'Text%' AND
NOT EXISTS (SELECT 1
FROM myLog l2
WHERE l2.entryText = l.EntryText AND
l2.eventDate >= '2017-03-27' AND
l2.eventDate < '2017-03-28'
);
我怀疑你的数据有问题。一种可能性是eventDate实际上是一个没有时间成分的日期。如果是这样,子查询将不会返回任何行,因为您使用了“2017-03-27”。啊,我明白了。您希望比较后期和前期的确切文本。您只需要一个关联子句:
SELECT l.*
FROM myLog l
WHERE l.eventDate >= '2017-03-28' AND l. entryText LIKE 'Text%' AND
NOT EXISTS (SELECT 1
FROM myLog l2
WHERE l2.entryText = l.EntryText AND
l2.eventDate >= '2017-03-27' AND
l2.eventDate < '2017-03-28'
);
我怀疑你的数据有问题。一种可能性是eventDate实际上是一个没有时间成分的日期。如果是这样,子查询将不会返回任何行,因为您使用了>'2017-03-27'。我得到了文本4,以这种方式出现
SELECT *
FROM myLog l1
WHERE l1.eventDate > '2017-03-28 00:00:00'
AND l1.entryText LIKE 'Text%'
AND CAST(l1.entryText as varchar(8000) NOT IN
(SELECT CAST(l2.entryText as varchar(8000)
FROM myLog l2
WHERE l2.entryText LIKE 'Text%'
AND l2.eventDate > '2017-03-27 00:00:00'
AND l2.eventDate < '2017-03-28 00:00:00')
不确定将来它是否会坏掉…我把text4放在这里
SELECT *
FROM myLog l1
WHERE l1.eventDate > '2017-03-28 00:00:00'
AND l1.entryText LIKE 'Text%'
AND CAST(l1.entryText as varchar(8000) NOT IN
(SELECT CAST(l2.entryText as varchar(8000)
FROM myLog l2
WHERE l2.entryText LIKE 'Text%'
AND l2.eventDate > '2017-03-27 00:00:00'
AND l2.eventDate < '2017-03-28 00:00:00')
不确定它是否会在将来中断…有许多问题需要回答,以获得完整的解决方案,但我将尽可能地解决它们,并努力解决它们 假设 MyLogtable有一个公共标识符字段,而不是文本字段。这可以用来确定应该比较哪些记录的文本字段,而不是检查所有文本字段是否匹配 数据仅附加到文本字段。它永远不会被删除,就像运行的交互日志一样 如果这些假设中的任何一个不正确,请纠正我 问题 本例中使用的SQL Server的具体版本是什么?SQL Server 2000及以前的版本将无法使用以前的解决方案 解决方案 最简单的方法是将文本字段强制转换为varcharMAX字段以进行所有比较。如果需要,这允许非内部构造。此外,您可能希望使用CTE简化查询,尤其是因为文本字段上的比较效率低下,例如
;WITH RecsToCheck as (
SELECT
RecIDField,
CommonField,
OtherField,
eventDate,
Cast(entryText as varchar(MAX)) as entryText
FROM myLog
WHERE eventDate > '2017-03-27 00:00:00'
AND entryText LIKE 'Text%'
)
SELECT *
FROM RecsToCheck rc1
LEFT JOIN RecsToCheck rc2
ON rc1.CommonField=rc2.CommonField
AND rc1.entryText != rc2.entryText
WHERE rc1.eventDate < '20170327'
AND rc2.eventDate >= '20170328'
有许多问题需要回答,以获得完整的解决方案,但我将尽我所能解决这些问题,并努力解决这些问题 假设 MyLogtable有一个公共标识符字段,而不是文本字段。这可以用来确定应该比较哪些记录的文本字段,而不是检查所有文本字段是否匹配 数据仅附加到文本字段。它永远不会被删除,就像运行的交互日志一样 如果这些假设中的任何一个不正确,请纠正我 问题 本例中使用的SQL Server的具体版本是什么?SQL Server 2000及以前的版本将无法使用以前的解决方案 解决方案 最简单的方法是将文本字段强制转换为varcharMAX字段以进行所有比较。如果需要,这允许非内部构造。此外,您可能希望使用CTE简化查询,尤其是因为文本字段上的比较效率低下,例如
;WITH RecsToCheck as (
SELECT
RecIDField,
CommonField,
OtherField,
eventDate,
Cast(entryText as varchar(MAX)) as entryText
FROM myLog
WHERE eventDate > '2017-03-27 00:00:00'
AND entryText LIKE 'Text%'
)
SELECT *
FROM RecsToCheck rc1
LEFT JOIN RecsToCheck rc2
ON rc1.CommonField=rc2.CommonField
AND rc1.entryText != rc2.entryText
WHERE rc1.eventDate < '20170327'
AND rc2.eventDate >= '20170328'
您可以确保将这些值放入值列表中,并通过将字符串拆分为某些值(如逗号)来检查其是否不在值列表中。entryText是否包含多个值?自2005年以来,文本数据类型已被弃用,取而代之的是varcharmax…也许您需要停止使用文本数据类型。是,entryText中有多个值。那么,您最好做两件事:1:规范化数据库。2:停止使用文本数据类型。您可以确保将这些值放入值列表中,并通过将字符串拆分为某些值来检查其是否不在值列表中,像逗号一样。entryText是否包含多个值?自2005年以来,文本数据类型已被弃用,取而代之的是varcharmax…也许您需要停止使用文本数据类型。是的,entryText中有多个值。好吧,您最好做两件事:1:规范化数据库。2:停止使用文本数据类型。文本字段不允许NOT INI强烈反对在子查询中使用NOT IN。虽然在这种情况下可能是正确的,但如果子查询中的任何行返回空值,则WHERE子句的计算结果永远不会为true。这通常不是预期的逻辑。好的,如果您取消组织not in,那么您可以加入表,因为我的第二个optiontext字段不允许not INI强烈反对在子查询中使用not in。虽然有问题
在这种情况下,如果子查询中的任何行返回空值,则WHERE子句的计算结果永远不会为true。这通常不是预期的逻辑。好的,如果您取消组织不在,那么您可以加入表作为我的第二个选项。选中,eventDate是一个datetime列。我在子查询中得到Test1-3,在主查询中得到Test1-4。这很神秘。不知道如何比较entryText列?@JeanneLane。我认为你的评论澄清了这个问题。子查询中需要一个关联子句。仅当l2.entryText(如l.EntryTextI)处于选中状态时,eventDate才是datetime列。我在子查询中得到Test1-3,在主查询中得到Test1-4。这很神秘。不知道如何比较entryText列?@JeanneLane。我认为你的评论澄清了这个问题。子查询中需要一个correlation子句。仅与l2.entryText类似,如l.entryText