SQL确定给定行上的多个列是否具有相同的值

SQL确定给定行上的多个列是否具有相同的值,sql,sql-server,Sql,Sql Server,我有一个SQL Server表,其中包含9列,用于指示在UI的一部分中包含或排除哪些内容。每列可以有值“A”、“X”或空白。每行在任何列中最多应有1个“A” 由于错误,许多列具有多个“A”值。我如何编写一个查询,返回每一个打破这个约束的行 我所拥有的只是这样的东西: SELECT PrimaryKey FROM Criteria C WHERE (C.First = 'A' AND C.Second = 'A') OR (C.First = 'A' AND C.Third = 'A')

我有一个SQL Server表,其中包含9列,用于指示在UI的一部分中包含或排除哪些内容。每列可以有值“A”、“X”或空白。每行在任何列中最多应有1个“A”

由于错误,许多列具有多个“A”值。我如何编写一个查询,返回每一个打破这个约束的行

我所拥有的只是这样的东西:

SELECT PrimaryKey
FROM Criteria C
WHERE (C.First = 'A' AND C.Second = 'A')
   OR (C.First = 'A' AND C.Third = 'A')
   OR (C.First = 'A' AND C.Fourth = 'A')
   ...
   OR (C.Eighth = 'A' AND C.Ninth = 'A')
有没有更干净或更优雅的方法来编写这段代码

SELECT *
FROM   MyTable
WHERE  LEN(CONCATENATE(C.First, C.... , C.Eighth)) - LEN(REPLACE(CONCATENATE(C.First, C.... , C.Eighth), 'A', '')) = 1 
例如,请尝试以下操作:

select 
* from YourTable
where REPLACE(TRIM('X' FROM col1),'A',1)
+ REPLACE(TRIM('X' FROM col2),'A',1)
+ REPLACE(TRIM('X' FROM col3),'A',1)
+ REPLACE(TRIM('X' FROM col4),'A',1)
+ REPLACE(TRIM('X' FROM col5),'A',1)
+ REPLACE(TRIM('X' FROM col6),'A',1)
+ REPLACE(TRIM('X' FROM col7),'A',1)
+ REPLACE(TRIM('X' FROM col8),'A',1)
+ REPLACE(TRIM('X' FROM col9),'A',1)> 1
select *
from YourTable
where replace(replace(concat(col1,col2,col3,col4,col5,col6,col7,col8,col9), 'X', ''), 'A', 1) > 1
我还使用了
TRIM
,它需要SQL Server 2017或更高版本

或以下各项:

select 
* from YourTable
where REPLACE(TRIM('X' FROM col1),'A',1)
+ REPLACE(TRIM('X' FROM col2),'A',1)
+ REPLACE(TRIM('X' FROM col3),'A',1)
+ REPLACE(TRIM('X' FROM col4),'A',1)
+ REPLACE(TRIM('X' FROM col5),'A',1)
+ REPLACE(TRIM('X' FROM col6),'A',1)
+ REPLACE(TRIM('X' FROM col7),'A',1)
+ REPLACE(TRIM('X' FROM col8),'A',1)
+ REPLACE(TRIM('X' FROM col9),'A',1)> 1
select *
from YourTable
where replace(replace(concat(col1,col2,col3,col4,col5,col6,col7,col8,col9), 'X', ''), 'A', 1) > 1

请参阅演示。

您可以使用
应用

SELECT C.*
FROM Criteria C CROSS APPLY
     (SELECT COUNT(*) as num_a_s
      FROM (VALUES (First), (Second), . . .  -- list all the columns here
           ) V(x)
      WHERE v.x = 'A'
     ) v
WHERE v.num_a_s >= 2;

注意:如果将这些值存储在列中而不是单独的行中,则数据模型可能有问题。

这里有一种方法可以做到这一点

  create table dbo.t1(x int, col1 varchar(10), col2 varchar(10))


  insert into dbo.t1 values(1,'A','A')
  insert into dbo.t1 values(2,'A','')
  insert into dbo.t1 values(3,'','')
  insert into dbo.t1 values(4,'','X')





  select x
         ,count(case when n='A' then 1 end) as cnt      
    from dbo.t1
cross apply(values ('col1',col1)
                  ,('col2',col2)
                  ---repeat this for columns up to col9...
           )x(m,n)
  group by x
  having count(case when n='A' then 1 end)>1

OP正在尝试查找与单个a的条件不匹配的记录。此查询仅获取单个a记录
CONCATENATE
不是t-SQL函数。CONCATENATE是TRANSACT-SQL和标准ISO/ANSI SQL函数。请读一下BOL<代码>CONCAT
@SQLpro。。。不连接
<代码>串联不是t-SQL函数。你引用的文档,并大声叫我读,告诉你,我被雇来解决问题,并最终重新设计数据库。我将把它添加到我的数据模型修复列表中,谢谢。