根据受试者,我对查询有问题。发生问题是因为表不归一化。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 APPLY
和LEFT 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