我正在尝试解释在MSAccess中构建的查询,并将其转换为SQL Server的可用SQL。
以下是Access in SQL视图中的语句:
SELECT CUSTFILE.CUSTNUM,
Last(GENPOL.eff_date) AS LastOfeff_date,
First(GENPOL.appnum) AS FirstOfAPPNUM
FROM GENPOL INNER JOIN CUSTFILE ON GENPOL.entnum = CUSTFILE.ENTNUM
GROUP BY CUSTFILE.CUSTNUM
HAVING...
ORDER BY LastGENPOL.eff_date DESC;
我们知道First()
和Last()
函数在SQL Server中无效且不起作用,因此我尝试使用MIN()
和MAX()
函数,因为该表没有增量ID字段或任何内容。一个很大的问题是,例如,appnum可以在其字段中包含非常奇怪的数据,如:
MTP-021106
OR
HMTP-271103
因此,如果插入的最后一个appnum
为HMTP-271103
,并且像MTP-021106
这样的genpol表中有较早的条目作为其appnum
将返回MTP-021106
,因为M
大于H
。
此外,eff_date
可能会出现同样的问题,因为最新记录的日期可能早于最后一个记录。
Last(GENPOL.eff_date) AS LastOfeff_date,
最终,查询会为符合CUSTFILE.CUSTNUM
条件的每个HAVING
返回一行。
我认为可能是一个答案是使用ROW_NUMBER()
函数来获取我需要的结果,但却无法使用GROUP BY语句。
表格GENPOL:
(PK)appnum, varchar(13) eff_date, datetime ntnum, varchar(15)
表CUSTFILE:
(PK)CUSTNUM, varchar(8) ENTNUM, varchar(15)
样本数据
CUSTNUM | LastOfeff_date | FirstOfAppnum MI99103 | 2013-01-01 | MTP-991103 MI99104 | 2013-01-01 | MTP-991104 MI99105 | 2013-01-01 | MTP-991105
答案 0 :(得分:2)
编辑:修复了对其中一列的引用
根据您列出的内容,此类内容应该有效:
SELECT
cfile.CUSTNUM,
aGENPOL.eff_date [LastOfeff_date],
bGENPOL.appnum [FirstOfAPPNUM]
FROM CUSTFILE cfile
CROSS APPLY (
SELECT TOP 1 *
FROM (
SELECT ROW_NUMBER() OVER(PARTITION BY entnum ORDER BY entnum) row, eff_date
FROM GENPOL
WHERE entnum = cfile.entnum
) x
ORDER BY row DESC
) aGENPOL
CROSS APPLY (
SELECT TOP 1 *
FROM (
SELECT ROW_NUMBER() OVER(PARTITION BY entnum ORDER BY entnum) row, appnum
FROM GENPOL
WHERE entnum = cfile.entnum
) y
ORDER BY row
) bGENPOL
基本上,apply中的查询将通过按每个entnum对表进行分区,然后按行号排序(第一个升序,最后一个降序)来获取每个情境的最高记录。
由于联合查询相当复杂,我还选择使用CROSS APPLY
,因为它实际上是在进行连接之前过滤掉记录。