Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/76.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
替换SQL中文本字段的“不在”_Sql_Sql Server_Sql Server 2008 - Fatal编程技术网

替换SQL中文本字段的“不在”

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

我正在尝试检测文本字段的新值。我将主查询的值与旧值的子查询进行比较。因为字段是文本字段,所以我不能使用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'
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