Sql 组合2个案例查询并返回1或0

Sql 组合2个案例查询并返回1或0,sql,sql-server,case,Sql,Sql Server,Case,我在vb.net的两个单独函数中使用了两个验证查询。对于通过我的应用程序处理的每个订单号,都会调用这两个函数。我想将两个案例查询合并为一个,结果值为1或0。提前谢谢 第一个问题: select case when EXISTS ( select 1 from [Sonora].[dbo].[tbl_Informatics_Orders_Data] with (nolock) where segment IN ('PID','ZPI', 'ZRQ', 'ZSI') AND orde

我在vb.net的两个单独函数中使用了两个验证查询。对于通过我的应用程序处理的每个订单号,都会调用这两个函数。我想将两个案例查询合并为一个,结果值为1或0。提前谢谢

第一个问题:

select case when EXISTS (
select 1
    from [Sonora].[dbo].[tbl_Informatics_Orders_Data] with (nolock)
    where segment IN ('PID','ZPI', 'ZRQ', 'ZSI') AND order_num = '780630021555'
) then 1 else 0 end as [SegmentsExist]
第二个问题:

SELECT CASE
WHEN
(SELECT COUNT(*) As result_count FROM [Sonora].[dbo].[tbl_Informatics_Orders_Data] 
with (nolock) WHERE segment = 'OBR' AND order_num = '780630021555') 
= 
(SELECT COUNT(*) As result_count FROM [Sonora].[dbo].[tbl_Informatics_Orders_Data] 
with (nolock)   WHERE segment = 'OBX' AND order_num = '780630021555')
THEN 1
ELSE 0
End AS returnValue
如果逻辑为“或”,则可以执行以下操作:

select (case when EXISTS (select 1
                          from [Sonora].[dbo].[tbl_Informatics_Orders_Data] with (nolock)
                          where segment IN ('PID','ZPI', 'ZRQ', 'ZSI') AND
                                order_num = '780630021555'
                         )
             then 1
             when (SELECT COUNT(*) As result_count
                   FROM [Sonora].[dbo][tbl_Informatics_Orders_Data] with (nolock)
                   WHERE segment = 'OBR' AND order_num = '780630021555') =
                  (SELECT COUNT(*) As result_count
                   FROM [Sonora].[dbo].[tbl_Informatics_Orders_Data] with (nolock)
                   WHERE segment = 'OBX' AND order_num = '780630021555'
                  )
             then 1
             else 0
        end) as [SegmentsExist];
如果逻辑为“和”:

编辑:

您可以简化第二个条件,直接返回
1
0

                  (SELECT (case when sum(case when segment = 'OBR' then 1 else 0 end) =
                                     sum(case when segment = 'OBX' then 1 else 0 end)
                                then 1 else 0
                           end)
                   FROM [Sonora].[dbo][tbl_Informatics_Orders_Data] with (nolock)
                   WHERE segment IN ('OBR', 'OBX') AND order_num = '780630021555'
                  )

你从哪里得到订单号?如果它是基于对同一个数据库的查询,我宁愿采用完全不同的方法,让SQL Server以基于集合的方式执行评估,而不是试图加快函数调用的速度,然后仍然调用它几千次…

可能更大的问题是您的程序结构。您提到这些查询(或1个查询)将针对30k-40k订单运行。运行单个查询的次数太多了,特别是当您可以以基于集合的方式运行此查询时

我建议重构您的查询以运行整个数据集,将结果存储为VB中的数据集,然后在那里执行您将执行的操作。如果对数据库中的每一行运行基于查找/扫描的操作,而不是返回数据集,则永远不会获得良好的性能

编辑:关于数据集的更多信息

当您运行单个结果的查询(
其中order_num='780630021555'
)时,数据库必须查看表中的每一行,以确保找到order_num='780630021555'的所有记录。现在,你说有4万张唱片。。这意味着对于这40000次更新中的每一次更新,数据库都必须查看表中的每一条记录。对一个40000行的表进行40000次扫描,总共读取了大约16亿行。SQL将尝试进行优化,可能会减少对表的扫描,但这基本上就是您正在做的

理想的方法是返回整个表的数据。编写查询以返回所有订单号的1或0,然后从那里进行处理。这样,表中的40k行只读取一次。大概是这样的:

SELECT CASE
WHEN (segment IN ('PID','ZPI', 'ZRQ', 'ZSI') OR OBR_Count = OBX_Count) THEN 1 ELSE 0 END AS Valid_Record
FROM [Sonora].[dbo].[tbl_Informatics_Orders_Data] IOD with (nolock)
JOIN
(
    SELECT order_num, COUNT(segment) OBR_Count
    FROM [Sonora].[dbo].[tbl_Informatics_Orders_Data] with (nolock)
    WHERE segment = 'OBR'
    GROUP BY order_num
) OBR
ON IOD.order_num = OBR.order_num
JOIN
(
    SELECT order_num, COUNT(segment) OBX_Count
    FROM [Sonora].[dbo].[tbl_Informatics_Orders_Data] with (nolock)
    WHERE segment = 'OBX'
    GROUP BY order_num
) OBX
ON IOD.order_num = OBX.order_num
这将为表中的每个订单号返回一行。它将返回一个有效的_记录列,指示您指定的条件是真(1)还是假(0)。我尚未运行此查询,但它看起来是正确的。运行可能需要一段时间,可能需要一分钟,但我可以保证,您单独选择每个结果所执行的操作所花费的时间要长很多倍


我在SQL Server中使用了几个每天超过10亿行的表。在这些情况下,查询中非常小的更改会大大缩短查询时间。在最大行数为40k的表中,通过重构查询以提供数据集而不是提供40k次的单个结果,您将获得更高的性能

你有什么问题?到目前为止,您有什么经验?我正在尝试限制对服务器的函数调用量。这两个查询针对每个订单运行。订单数量在3万到4万之间。我正在努力提高这一过程的速度。是的,但到目前为止你做了哪些尝试?您是否有一个查询,您试图将两者结合起来?你在挣扎什么?我真的在寻找一个开始的地方。我已经看过case语句的例子,但是我很难找到两组标准和一个where子句的例子。组合它们的逻辑是什么?都是“1”还是“1”?谢谢你的例子。这正是我想要的。order_num从数组传递到函数。我不熟悉基于集合的方式,你的意思是什么?此应用程序正在创建段数据并插入到表中。我对新创建的数据运行评估,以确定它是否符合正确的标准。订单包括一组无法单独评估但作为整体评估的多个段。我不知道所有的细节,所以你必须做出最后的决定,在你的情况下什么是最好的。对于数据,最好从数据集的角度来考虑,对大数据组做很多事情,而不是一次对一行做一件事。
SELECT CASE
WHEN (segment IN ('PID','ZPI', 'ZRQ', 'ZSI') OR OBR_Count = OBX_Count) THEN 1 ELSE 0 END AS Valid_Record
FROM [Sonora].[dbo].[tbl_Informatics_Orders_Data] IOD with (nolock)
JOIN
(
    SELECT order_num, COUNT(segment) OBR_Count
    FROM [Sonora].[dbo].[tbl_Informatics_Orders_Data] with (nolock)
    WHERE segment = 'OBR'
    GROUP BY order_num
) OBR
ON IOD.order_num = OBR.order_num
JOIN
(
    SELECT order_num, COUNT(segment) OBX_Count
    FROM [Sonora].[dbo].[tbl_Informatics_Orders_Data] with (nolock)
    WHERE segment = 'OBX'
    GROUP BY order_num
) OBX
ON IOD.order_num = OBX.order_num