Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 在查询中联接表值函数_Sql Server_Sql Server 2008_Sql Server 2005_Sql Server 2008 R2 - Fatal编程技术网

Sql server 在查询中联接表值函数

Sql server 在查询中联接表值函数,sql-server,sql-server-2008,sql-server-2005,sql-server-2008-r2,Sql Server,Sql Server 2008,Sql Server 2005,Sql Server 2008 R2,我有一张桌子。我想用表值函数fnuserrankuserID连接这个表。所以我需要交叉应用表值函数: SELECT * FROM vwuser AS a CROSS APPLY fnuserrank(a.userid) 它为每个用户标识生成多条记录。我只希望每个empid的最后一条记录没有终止的秩。我该怎么做 数据: 必须从该第二条记录和第四条记录中进行选择。在SQL Server 2005+中,您可以使用此公用表表达式通过MonitorDate确定排名不为“Term”的最新记录: WITH

我有一张桌子。我想用表值函数fnuserrankuserID连接这个表。所以我需要交叉应用表值函数:

SELECT *
FROM vwuser AS a
CROSS APPLY fnuserrank(a.userid)
它为每个用户标识生成多条记录。我只希望每个empid的最后一条记录没有终止的秩。我该怎么做

数据:


必须从该第二条记录和第四条记录中进行选择。

在SQL Server 2005+中,您可以使用此公用表表达式通过MonitorDate确定排名不为“Term”的最新记录:

WITH EmployeeData AS
(
   SELECT *
      , ROW_NUMBER() OVER (PARTITION BY empId, ORDER BY MonitorDate DESC) AS RowNumber
   FROM vwuser AS a
   CROSS APPLY fnuserrank(a.userid)
   WHERE Rank != 'Term'
)
SELECT *
FROM EmployeeData AS ed
WHERE ed.RowNumber = 1;

注意:此CTE之前的语句需要以分号结尾。正因为如此,我看到很多人都这样写;将EmployeeData设置为…

时,您必须使用此功能。在sqlfiddle上模拟模式时遇到问题

Select bar.*
from 
(
SELECT *
FROM vwuser AS a
CROSS APPLY fnuserrank(a.userid)
where rank != 'TERM'
) foo
left join 
(
SELECT *
FROM vwuser AS b
CROSS APPLY fnuserrank(b.userid)
where rank != 'TERM'
) bar
on foo.empId = bar.empId
  and foo.MonitorDate > bar.MonitorDate
where bar.empid is null
我总是需要在日期更高的时候测试一下左撇子。它的工作方式是你做一个左外翻。除每用户一行外,每行都有具有更高监视日期的行。那一排就是你想要的。我通常使用代码中的示例,但我用错了笔记本电脑。要使其工作,您可以选择foo.,bar。然后查看结果,找出所需的行,并使条件正确

你也可以这样做,这样更容易记住

SELECT *
FROM vwuser AS a
CROSS APPLY fnuserrank(a.userid)
) foo
join 
(
select empid, max(monitordate) maxdate
FROM vwuser AS b
CROSS APPLY fnuserrank(b.userid)
 where rank != 'TERM'
) bar
on foo.empid = bar.empid
and foo.monitordate = bar.maxdate
与聚合函数相比,我通常更喜欢使用基于集合的逻辑,但不管什么都可以。您还可以通过将TVF联接的结果缓存到表变量中来调整它

编辑: -我在这里模拟了你的TVF。显然sqlfiddle不喜欢去

select foo.*, bar.*
from 
(
SELECT f.*
FROM vwuser AS a
join fnuserrank f
  on a.empid = f.empid
where rank != 'TERM'
) foo
left join 
(
SELECT f1.empid [barempid], f1.monitordate [barmonitordate]
FROM vwuser AS b
join fnuserrank f1
  on b.empid = f1.empid
where rank != 'TERM'
) bar
on foo.empId = bar.barempid
  and foo.MonitorDate > bar.barmonitordate
where bar.barempid is  null  

你用什么标准来决定最后一个记录?有一个监视器日期列,它一定是Maximum我在我的问题中也给出了数据,我想要什么?你不想要第三个和第四个记录吗,因为第三个监视器的日期是10月,第二个记录的日期是9月?不,我只想要第二个和第四个记录。这是因为我不想要终止的记录。在这之前我想要唱片。i、 e最后一条活动记录实际上,我认为您不必使用CTE。您可以只使用一个嵌套的SELECT,如SELECT t1.*从xyz t1中选择a、b、c。但是,ROW_NUMBER语句确实需要SQL Server 2005或更高版本。编辑:我相信这也适用。@BaconBits您是正确的,您不必使用CTE。不过,我更喜欢它们在嵌套选择上的外观,这就是为什么我在回答问题时使用它们,因为OP Tags SQL Server 2005+在这种情况下,两个选项的功能都是一样的。顺便说一句,对于SQL Server查询,你可以在SQL Fiddle中使用所有大写字母-大写字母对这一点有多奇怪。是的,我可以放宽案例要求,我想。也许我会把它加到我的待办事项清单上。我的印象是,人们总是用所有的大写字母,所以它以前从未出现过。这需要紧迫的转换。整个额外的按键!我懒得这么做:嘿,sqlfiddle的大道具!好消息,Brian-通过我们的聊天,我已经修复了代码,不再区分大小写。走,走,走,走-谢谢!
select foo.*, bar.*
from 
(
SELECT f.*
FROM vwuser AS a
join fnuserrank f
  on a.empid = f.empid
where rank != 'TERM'
) foo
left join 
(
SELECT f1.empid [barempid], f1.monitordate [barmonitordate]
FROM vwuser AS b
join fnuserrank f1
  on b.empid = f1.empid
where rank != 'TERM'
) bar
on foo.empId = bar.barempid
  and foo.MonitorDate > bar.barmonitordate
where bar.barempid is  null