替换为" NOT IN"用于SQL中的文本字段

时间:2017-03-28 16:06:56

标签: sql sql-server sql-server-2008

我正在尝试检测文本字段的新值。我将主查询的值与旧值的子查询进行比较。由于该字段是文本字段,因此我无法使用" NOT IN"子句。

这是数据:

if/else

在我的查询中,我想返回Text4,因为它是新的 这是我的疑问:

On Day 1:
infoField: Text1, Text2, Text3
On Day 2:
infoField: Text1, Text2, Text3, Text4

此查询没有返回任何内容 - 有没有办法在文本字段上执行此类查询?

4 个答案:

答案 0 :(得分:2)

我不明白你的问题,但这个查询可以写得很好

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

答案 1 :(得分:1)

啊,我明白了。您希望将后期中的完全文本与之前的时间段进行比较。你只需要一个关联条款:

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实际上是date,没有时间成分。如果是这样,子查询将不返回任何行,因为您使用了> '2017-03-27'

答案 2 :(得分:1)

对于完整的解决方案,有许多问题需要解决,但我会尽可能地解决这些问题并做出解决方案。

<强>假设

MyLog表具有除文本字段之外的公共标识符字段。这可用于识别应比较哪个记录的文本字段,而不是检查匹配的所有文本字段。

数据仅附加到文本字段。它永远不会删除(类似于交互的运行日志)。

如果这些假设中的任何一个不正确,请纠正我。

<强>问题

在这种情况下使用的SQL Server的具体版本是什么? SQL Server 2000和之前的版本无法使用该解决方案。

<强>解决方案

最简单的方法是将文本字段转换为varchar(MAX)字段以进行所有比较。如果需要,这允许NOT IN构造。此外,您可能希望使用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'

答案 3 :(得分:0)

我得到了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')

不确定将来是否会破裂......