选择行如何包含至少一个值的行,而不是相等的行?TSQL



根据受试者,我对查询有问题。发生问题是因为表不归一化。DB的模式看起来像:

表A列:

ID - A,A,B,B,C,D (not unique)
AR - "N10 N12", "N1 N2 N3", "N1"

AR在表中是char(100)

AWS表中的干旱是char(6)

SubSelect的结果是一列,带有一行字符。它可以插入临时表中,但我想任何其他变量类型都无法存储。

这是简化的示例,我想选择AR至少包含N1的所有行。实际上,从其他表中,我在AR列中可以找到很多值。

我尝试了:

包含 - 它将起作用,但是@Table变量不能与此语句一起使用

查询中的内在加入和子查询 - 通常可以工作,但这是问题,它仅返回值平等的行。例如,当我选择N1时,它将被返回,但是" N1 N2 N3"不在结果中。

我的实际查询:

select * 
from A 
where AR in (select ARID 
             From AWS 
             group by ARID 
             having count(*)>2) 
order by EvaluationTime desc

谢谢,问候,b。

给定两个表具有您提供的值的表(请告诉我是否有更多),您首先需要一种将A.AR中值分为可管理的字符串中的方法。我使用此用户定义的函数:

CREATE FUNCTION [dbo].[UDF_StringDelimiter]
/*********************************************************
**  Takes Parameter "LIST" and transforms it for use    **
**  to select individual values or ranges of values.    **
**                                                      **
**  EX: 'This,is,a,test' = 'This' 'Is' 'A' 'Test'       **
*********************************************************/
    (
          @LIST             VARCHAR(8000)
         ,@DELIMITER        VARCHAR(255)
    )
RETURNS @TABLE TABLE 
    ( 
         [RowID] INT IDENTITY
        ,[Value] VARCHAR(255)
    )
WITH SCHEMABINDING  
AS 
BEGIN
    DECLARE 
         @LISTLENGTH AS SMALLINT
        ,@LISTCURSOR AS SMALLINT
        ,@VALUE AS VARCHAR(255)
    ;
    SELECT 
         @LISTLENGTH = LEN(@LIST) - LEN(REPLACE(@LIST,@DELIMITER,'')) + 1
        ,@LISTCURSOR = 1
        ,@VALUE = ''
    ;
    WHILE @LISTCURSOR <= @LISTLENGTH
    BEGIN
        INSERT INTO @TABLE (Value)
        SELECT 
            CASE
                WHEN @LISTCURSOR < @LISTLENGTH
                    THEN SUBSTRING(@LIST,1,PATINDEX('%' + @DELIMITER + '%',@LIST) - 1)
                ELSE SUBSTRING(@LIST,1,LEN(@LIST))
            END
        ;
        SET @LIST = STUFF(@LIST,1,PATINDEX('%' + @DELIMITER + '%',@LIST),'')
        ;       
        SET @LISTCURSOR = @LISTCURSOR + 1
        ;
    END
    ;
    RETURN
    ;
END
;

然后,用这两个表:

DECLARE @TABLE TABLE (ID CHAR(1), AR VARCHAR(55));
INSERT INTO @TABLE VALUES ('A','N1 N3 N4');
INSERT INTO @TABLE VALUES ('B','N2');
INSERT INTO @TABLE VALUES ('C','N1');
INSERT INTO @TABLE VALUES ('D','N5');
INSERT INTO @TABLE VALUES ('E','N2 N1');
DECLARE @TABLE2 TABLE (RowID INT IDENTITY, ARID VARCHAR(55));
INSERT INTO @TABLE2 (ARID) VALUES ('N1');

使用CROSS APPLYLEFT JOIN,我得到响应:

SELECT A.ID AS [A.ID], A.AR AS [A.AR],B.ARID AS [B.ARID]
FROM @TABLE A
CROSS APPLY dbo.UDF_StringDelimiter(A.AR,' ') X
INNER JOIN @TABLE2 B
    ON B.ARID = X.Value
ORDER BY ID
;

返回:

A.ID     A.AR       B.ARID
-----------------------------------
A       N1 N3 N4     N1
C       N1           N1
E       N2 N1        N1

当然,您也可以将其分组,将其归还为划界列表,等等。给我更多详细信息,也许我可以给您更好的答复。

如果您使用的是2个表,则交叉应用是您的朋友。

create  table #ARID(id varchar(10), ar varchar(100));
insert into #ARID values
('a', 'n1 n2'),
('a', 'n10 n11'),
('b', 'n1'),
('b', 'n11 n13 15'),
('c', 'n3'),
('c', 'n14 n12');

这是包含要搜索的值的表:

create table #TO_SEARCH(val varchar(10))
insert into #TO_SEARCH values ('n10'), ('n11');

此简单查询返回每行,其中包含以下值之一:

SELECT ca.*
FROM   #TO_SEARCH ts
CROSS APPLY  (SELECT id, ar
              FROM   #ARID
              WHERE ar LIKE ('%' + ts.val + '%')
             ) ca

您可以倒转表,结果是相同的:

SELECT id, ar
FROM   #ARID
CROSS APPLY  (SELECT val from #TO_SEARCH) ts
WHERE ar LIKE ('%' + ts.val + '%')
+----+------------+
| id | ar         |
+----+------------+
| a  | n10 n11    |
+----+------------+
| a  | n10 n11    |
+----+------------+
| b  | n11 n13 15 |
+----+------------+

可以在这里检查:http://rextester.com/cueu92118

最新更新