我很难将我想要的东西翻译成函数式编程,因为我认为是命令式的。基本上,我有一张表格和一张期望表。在期望视图中,我希望它查看表单表并告诉我是否每个人都找到了匹配项。但是,当我尝试使用连接来完成此操作时,当两个或多个表单匹配时,连接会将行添加到 Expectation 表中。我不想要这个。
以一种命令式的方式,我想要这样的等价物:
ForEach (row in Expectation table)
{
if (any form in the Form table matches the criteria)
{
MatchID = form.ID;
SignDate = form.SignDate;
...
}
}
我在 SQL 中拥有的是:
SELECT
e.*, match.ID, match.SignDate, ...
FROM
POFDExpectation e LEFT OUTER JOIN
(SELECT MIN(ID) as MatchID, MIN(SignDate) as MatchSignDate,
COUNT(*) as MatchCount, ...
FROM Form f
GROUP BY (matching criteria columns)
) match
ON (form.[match criteria] = expectation.[match criteria])
哪个工作正常,但速度很慢,每次有两个匹配项时,都会在期望结果中添加一行。从数学上讲,我知道连接是交叉乘法,这是意料之中的,但我不确定没有它们如何做到这一点。也许是子查询?
我无法提供有关实施的更多详细信息,但我很乐意尝试任何建议并用结果做出回应。我有 880 个期望行,并返回 942 个结果。如果我只允许匹配一种形式的结果,我会得到 831 个结果。两者都不是可取的,所以如果你的让我正好达到 880,那么你的就是公认的答案。
编辑:我使用的是 SQL Server 2008 R2,但最好使用通用解决方案。
示例代码:
--DROP VIEW ExpectationView; DROP TABLE Forms; DROP TABLE Expectations;
--Create Tables and View
CREATE TABLE Forms (ID int IDENTITY(1,1) PRIMARY KEY, ReportYear int, Name varchar(100), Complete bit, SignDate datetime)
GO
CREATE TABLE Expectations (ID int IDENTITY(1,1) PRIMARY KEY, ReportYear int, Name varchar(100))
GO
CREATE VIEW ExpectationView AS select e.*, filed.MatchID, filed.SignDate, ISNULL(filed.FiledCount, 0) as FiledCount, ISNULL(name.NameCount, 0) as NameCount from Expectations e LEFT OUTER JOIN
(select MIN(ID) as MatchID, ReportYear, Name, Complete, Min(SignDate) as SignDate, COUNT(*) as FiledCount from Forms f GROUP BY ReportYear, Name, Complete) filed
on filed.ReportYear = e.ReportYear AND filed.Name like '%'+e.Name+'%' AND filed.Complete = 1 LEFT OUTER JOIN
(select MIN(ID) as MatchID, ReportYear, Name, COUNT(*) as NameCount from Forms f GROUP BY ReportYear, Name) name
on name.ReportYear = e.ReportYear AND name.Name like '%'+e.Name+'%'
GO
--Insert Text Data
INSERT INTO Forms (ReportYear, Name, Complete, SignDate)
SELECT 2011, 'Bob Smith', 1, '2012-03-01' UNION ALL
SELECT 2011, 'Bob Jones', 1, '2012-10-04' UNION ALL
SELECT 2011, 'Bob', 1, '2012-07-20'
GO
INSERT INTO Expectations (ReportYear, Name)
SELECT 2011, 'Bob'
GO
SELECT * FROM ExpectationView --Should only return 1 result, returns 9
'filed' 表明他们已经完成了一个表格,'name' 表明他们可能已经开始了一个但没有完成它。我的观点有四种不同的“匹配标准”——每一种都更严格一些,而且每一种都算数。'Name Only Matches'、'Loose Matches'、'Matches'(默认)、'Tight Matches'(在有多个默认匹配时使用。