Sql server 如何在SQLServer2008中进行布尔字符串比较
简单地说,我想将一些列的内容添加到一起,但前提是相关列包含特定值。要在MS Access中执行此操作,我使用以下方法:Sql server 如何在SQLServer2008中进行布尔字符串比较,sql-server,tsql,sql-server-2008,Sql Server,Tsql,Sql Server 2008,简单地说,我想将一些列的内容添加到一起,但前提是相关列包含特定值。要在MS Access中执行此操作,我使用以下方法: STRUint:(Abs(1*([Code01]='0192'))*[Code01int])+(Abs(1*([Code02]='0192'))*[Code02int])... 分解这个,如果Code01='0192'我得到的结果为真,我乘以1得到-1,并使用Abs转换为1。然后乘以Code01int,所以只有当Code01为'0192'时,我才有一个等于Code01int的
STRUint:(Abs(1*([Code01]='0192'))*[Code01int])+(Abs(1*([Code02]='0192'))*[Code02int])...
分解这个,如果Code01='0192'我得到的结果为真,我乘以1得到-1,并使用Abs转换为1。然后乘以Code01int,所以只有当Code01为'0192'时,我才有一个等于Code01int的整数,否则我就有零。该计算的结果将添加到序列中的下一个计算中,依此类推
该序列重复15次,将Code01int到Code15int中的整数相加,其中Code01到Code15的内容为“0192”
我个人认为在SQL中实现这一点的唯一方法是使用
UPDATE Table1
SET STRUint = 0
UPDATE Table1
SET STRUint = CASE
WHEN Code01='0192' THEN STRUint + Code01int
END
UPDATE Table1
SET STRUint = CASE
WHEN Code02='0192' THEN STRUint + Code02int
END
etc
这是实现我的目标的唯一途径吗,通过做很多更新?我对15组列执行此操作,并对不同的字符串内容重复5次,因此80次更新,包括初始设置为零
我希望有一种方法可以在不进行太多更新的情况下实现这一点,前提是最好不要进行太多更新。表中是否有任何ID? 如果是,您可以:
UPDATE A
SET STRUint = B.TOTAL
FROM TABLE1 A
INNER JOIN
(
SELECT ID,SUM(VALUE) AS TOTAL
FROM
(
SELECT ID,Code01int AS VALUE
FROM TABLE
WHERE Code01= '0192'
UNION ALL
SELECT ID,Code02int
FROM TABLE
WHERE Code02= '0192'
UNION ALL
SELECT ID,Code03int
FROM TABLE
WHERE Code03= '0192'
....
....
)A
GROUP BY ID
)B
ON A.ID = B.ID
你桌上有身份证吗? 如果是,您可以:
UPDATE A
SET STRUint = B.TOTAL
FROM TABLE1 A
INNER JOIN
(
SELECT ID,SUM(VALUE) AS TOTAL
FROM
(
SELECT ID,Code01int AS VALUE
FROM TABLE
WHERE Code01= '0192'
UNION ALL
SELECT ID,Code02int
FROM TABLE
WHERE Code02= '0192'
UNION ALL
SELECT ID,Code03int
FROM TABLE
WHERE Code03= '0192'
....
....
)A
GROUP BY ID
)B
ON A.ID = B.ID
有什么问题吗
UPDATE Table1 SET STRUint = 0;
UPDATE
Table1
SET
STRUint +=
CASE WHEN Code01='0192' THEN Code01int ELSE 0 END
+ CASE WHEN Code02='0192' THEN Code02int ELSE 0 END
+ CASE WHEN Code03='0192' THEN Code03int ELSE 0 END
etc.
有什么问题吗
UPDATE Table1 SET STRUint = 0;
UPDATE
Table1
SET
STRUint +=
CASE WHEN Code01='0192' THEN Code01int ELSE 0 END
+ CASE WHEN Code02='0192' THEN Code02int ELSE 0 END
+ CASE WHEN Code03='0192' THEN Code03int ELSE 0 END
etc.
最好是改变你桌子的设计。每当您觉得需要命名Code01、Code02等数字列时,您应该使用相关的边表 我的代码将使用APPLY with VALUES来创建所需的动态结构(类似于取消激励),然后分组并求和,以获得我认为您需要的内容
DECLARE @MockTable TABLE(ID INT IDENTITY
,Comment VARCHAR(100)
,Code01 VARCHAR(100),Code01int INT
,Code02 VARCHAR(100),Code02int INT
,Code03 VARCHAR(100),Code03int INT);
INSERT INTO @MockTable VALUES('One is a' ,'a',1,'b',1,'c',1)
,('All are a','a',1,'a',1,'a',1)
,('Two are a','b',1,'a',1,'a',1);
-我用“a”代替你的号码,但你会得到ghist
DECLARE @SearchCode VARCHAR(100)='a';
-询问
SELECT t.ID
,t.Comment
,SUM(A.Val) AS SumOfValuesForTheCode
FROM @MockTable t
CROSS APPLY (VALUES(1,Code01,Code01int)
,(2,Code02,Code02int)
,(3,Code03,Code03int))A(Indx,Code,Val)
WHERE A.Code=@SearchCode
GROUP BY t.ID,t.Comment
结果
1 One is a 1
2 All are a 3
3 Two are a 2
更新:完全通用方法:
这不会很快,但在某种程度上,它是美丽的:-
SELECT t.ID
,t.Comment
,RowAsXml.query('for $code in /row/*[string-length(local-name())=6
and substring(local-name(),1,4)="Code"
and text()=sql:variable("@SearchCode")]
return /row/*[local-name()=concat(local-name($code),"int")]')
.value('sum(*/text())','int')
FROM @MockTable t
CROSS APPLY(SELECT t.* FOR XML PATH('row'),TYPE) A(RowAsXml)
简而言之:
应用程序将创建一个表示整行的XML。针对这种XML,我们可以使用XQuery的FLWOR。给定的xquery将遍历节点并找到那些节点,其中名称的长度为6,以代码开头,文本=内容等于您要查找的值
知道fitting代码节点后,我们可以通过将列名与单词int连用来返回fitting值节点
有了这个,我们可以算出一个总数,瞧
中间XML看起来像每行一个
<row>
<Comment>One is a</Comment>
<Code01>a</Code01>
<Code01int>1</Code01int>
<Code02>b</Code02>
<Code02int>1</Code02int>
<Code03>c</Code03>
<Code03int>1</Code03int>
</row>
-检查结果
SELECT * FROM @MockTable
另一种方法使用可更新的CTE
最好是改变你桌子的设计。每当您觉得需要命名Code01、Code02等数字列时,您应该使用相关的边表 我的代码将使用APPLY with VALUES来创建所需的动态结构(类似于取消激励),然后分组并求和,以获得我认为您需要的内容
DECLARE @MockTable TABLE(ID INT IDENTITY
,Comment VARCHAR(100)
,Code01 VARCHAR(100),Code01int INT
,Code02 VARCHAR(100),Code02int INT
,Code03 VARCHAR(100),Code03int INT);
INSERT INTO @MockTable VALUES('One is a' ,'a',1,'b',1,'c',1)
,('All are a','a',1,'a',1,'a',1)
,('Two are a','b',1,'a',1,'a',1);
-我用“a”代替你的号码,但你会得到ghist
DECLARE @SearchCode VARCHAR(100)='a';
-询问
SELECT t.ID
,t.Comment
,SUM(A.Val) AS SumOfValuesForTheCode
FROM @MockTable t
CROSS APPLY (VALUES(1,Code01,Code01int)
,(2,Code02,Code02int)
,(3,Code03,Code03int))A(Indx,Code,Val)
WHERE A.Code=@SearchCode
GROUP BY t.ID,t.Comment
结果
1 One is a 1
2 All are a 3
3 Two are a 2
更新:完全通用方法:
这不会很快,但在某种程度上,它是美丽的:-
SELECT t.ID
,t.Comment
,RowAsXml.query('for $code in /row/*[string-length(local-name())=6
and substring(local-name(),1,4)="Code"
and text()=sql:variable("@SearchCode")]
return /row/*[local-name()=concat(local-name($code),"int")]')
.value('sum(*/text())','int')
FROM @MockTable t
CROSS APPLY(SELECT t.* FOR XML PATH('row'),TYPE) A(RowAsXml)
简而言之:
应用程序将创建一个表示整行的XML。针对这种XML,我们可以使用XQuery的FLWOR。给定的xquery将遍历节点并找到那些节点,其中名称的长度为6,以代码开头,文本=内容等于您要查找的值
知道fitting代码节点后,我们可以通过将列名与单词int连用来返回fitting值节点
有了这个,我们可以算出一个总数,瞧
中间XML看起来像每行一个
<row>
<Comment>One is a</Comment>
<Code01>a</Code01>
<Code01int>1</Code01int>
<Code02>b</Code02>
<Code02int>1</Code02int>
<Code03>c</Code03>
<Code03int>1</Code03int>
</row>
-检查结果
SELECT * FROM @MockTable
另一种方法使用可更新的CTE
样本数据最好作为+。请将您的问题包括在内,并提供您想要的结果。有关更多详细信息,@ZoharPeled,您是否要求我编辑我的问题,并在语句中包含CREATE TABLE和INSERT,以给出我的数据示例?是的,完全正确。这将使任何试图回答问题的人都能够将您的样本数据复制到测试环境中。@Lawrence在我的回答中,我是为您这样做的。我们的目标是一个独立的样本来重现你的问题,一个所谓的问题。我突然想到,在我提到我是如何试图解决我的问题的地方,我可能用我所问的误导了人们;SQL中有布尔表达式的概念吗?e、 g.'X'='Y'应返回FALSE或9>5应返回TRUE。当然,给出的答案达到了相同的最终结果,从我80年代编程的日子里,我学到布尔运算比IF..THEN..ELSE更快。这几天可能不是这样,在这种情况下,我应该忘记使用Boolean。请将您的问题包括在内,并提供您想要的结果。有关更多详细信息,@ZoharPeled,您是否要求我编辑我的问题,并在语句中包含CREATE TABLE和INSERT,以给出我的数据示例?是的,完全正确。这将使任何试图回答问题的人都能够将您的样本数据复制到测试环境中。@Lawrence在我的回答中,我是为您这样做的。目标是一个立场
-我突然想到,当我提到我是如何试图解决我的问题时,我所问的可能误导了人们;SQL中有布尔表达式的概念吗?e、 g.'X'='Y'应返回FALSE或9>5应返回TRUE。当然,给出的答案达到了相同的最终结果,从我80年代编程的日子里,我学到布尔运算比IF..THEN..ELSE更快。这几天可能不是这样,在这种情况下,我应该忘记使用布尔运算。非常感谢你的详尽回答。桌子的设计不是我的,不能更改,它符合设计规范的另一个目的,我同意你的看法。你提供的两个答案给出了我期望的结果。我该如何包装更新声明呢?@Lawrence,看看我的答案。您发现的两种方法都将使用这两种方法来计算值。感谢您的更新。我自己也尝试过更新,但在某个地方出错了,使用你的代码对我来说效果很好。我现在左右为难,因为这里的三个答案都有效,我只需要选择一个:我很想选择一个对我来说最简单的答案,但担心我可能会违反这里的规则或礼仪。@Lawrence你选择哪一个答案取决于你。。。没问题。快乐编码…@Lawrence一个小小的提示:这取决于你,你选择哪一个答案,但是你被要求选择一个来结束这个问题。非常感谢你的详尽回答。桌子的设计不是我的,不能更改,它符合设计规范的另一个目的,我同意你的看法。你提供的两个答案给出了我期望的结果。我该如何包装更新声明呢?@Lawrence,看看我的答案。您发现的两种方法都将使用这两种方法来计算值。感谢您的更新。我自己也尝试过更新,但在某个地方出错了,使用你的代码对我来说效果很好。我现在左右为难,因为这里的三个答案都有效,我只需要选择一个:我很想选择一个对我来说最简单的答案,但担心我可能会违反这里的规则或礼仪。@Lawrence你选择哪一个答案取决于你。。。没问题。快乐编码…@Lawrence一个小小的提示:这取决于你,你选择哪一个答案,但是你被要求选择一个来结束这个问题。谢谢你,Richard,我不知道+=在SQL中是一个东西,我从来没有想过要把一系列CASE语句串在一起。谢谢你Richard,我不知道+=在SQL中是一个东西,我从来没有想过要把一系列CASE语句串在一起。谢谢Danny,这确实给出了我期望的结果。谢谢Danny,这确实给出了我期望的结果。