Sql 获取最近的记录,如果最近的记录不符合条件,则获取以前的记录
我是sql新手,在我的一个sql查询中遇到了一个问题。我的问题是,一个人有多个就诊日期,他必须符合某些条件。我必须退出最近一次符合条件的就诊,如果最近一次就诊不符合条件,则应选择符合条件的前一次就诊。 例: 在上述示例中,qe需要如下输出: 预期产出:Sql 获取最近的记录,如果最近的记录不符合条件,则获取以前的记录,sql,sql-server,Sql,Sql Server,我是sql新手,在我的一个sql查询中遇到了一个问题。我的问题是,一个人有多个就诊日期,他必须符合某些条件。我必须退出最近一次符合条件的就诊,如果最近一次就诊不符合条件,则应选择符合条件的前一次就诊。 例: 在上述示例中,qe需要如下输出: 预期产出: name | visit_dt | x | y | z A 04/27/'17 1 1 0 B 04/24/'17 1 1 0 C 04/23/'17 1 0 0 这里的条件是,我们应
name | visit_dt | x | y | z
A 04/27/'17 1 1 0
B 04/24/'17 1 1 0
C 04/23/'17 1 0 0
这里的条件是,我们应该提取最新的“X”。如果最新的“X”在“Y”中没有1,那么它应该查找以前的记录,其中Y为1,如果该特定人员的所有记录都没有Y为1,那么它应该选择最新的“X”。
我想我的问题很清楚。如果有人能帮我,那就太好了。我想你可以试试这个:
SELECT NAME
,VISIT_DT
,X
,Y
,Z
FROM (
SELECT *
,ROW_NUMBER() OVER (
PARTITION BY NAME ORDER BY X + Y DESC
,VISIT_DT DESC
) AS RN
FROM MYTABLE
) B
WHERE RN = 1
使用示例数据输出:
NAME VISIT_DT X Y Z
--------------------------- ----------------------- ----------- ----------- -----------
A 2017-04-27 00:00:00.000 1 1 0
B 2017-04-24 00:00:00.000 1 1 0
C 2017-04-23 00:00:00.000 1 0 0
您可以按Y描述订购,访问_dt desc并使用交叉应用解决方案:
select distinct(v1.name), v2.visit_dt, v2.x, v2.y, v2.z
from visits v1
cross apply (select top(1) name, visit_dt, x, z, y
from visits
where name = v1.name
order by y desc, visit_dt desc) v2;
结果是一样的:
| name | visit_dt | x | y | z |
|------|---------------------|---|---|---|
| A | 27.04.2017 00:00:00 | 1 | 1 | 0 |
| B | 24.04.2017 00:00:00 | 1 | 1 | 0 |
| C | 23.04.2017 00:00:00 | 1 | 0 | 0 |
性能取决于索引
Rextester
< P>那么考虑x,y,z,然后VisIT.dT?使用行号对记录进行排名:这真的是访问的形式吗?那个字段是什么数据类型?你说我想我的问题很清楚。。。也许你是有意的我希望我的问题是清楚的请标记你正在使用的SQL Server版本。非常感谢你花时间回答我的问题非常感谢你花时间帮助我回答你的问题。没问题,我的朋友@Mamtha:你应该考虑投票回答任何解决你问题的人。
| name | visit_dt | x | y | z |
|------|---------------------|---|---|---|
| A | 27.04.2017 00:00:00 | 1 | 1 | 0 |
| B | 24.04.2017 00:00:00 | 1 | 1 | 0 |
| C | 23.04.2017 00:00:00 | 1 | 0 | 0 |
SELECT
[name]
,[visit_dt]
,[x]
,[y]
,[z]
--,[RowNumber] (for testing)
FROM
(
SELECT
[name]
,CONVERT(DATE,REPLACE([visit_dt],'''',''),1) AS [visit_dt]
,[x]
,[y]
,[z]
,ROW_NUMBER() OVER (PARTITION BY [name] ORDER BY (CASE WHEN [y] = 1 THEN [y] END) DESC, CONVERT(DATE,REPLACE([visit_dt],'''',''),1) DESC) AS [RowNumber]
FROM
[DB].[dbo].[Stack]
WHERE
[x] = 1
) AS [Visits]
WHERE
[Visits].[RowNumber] = 1
select name, visit_dt, x, y, z
from
(
select
mytable.*,
row_number() partition by name order by x desc, y desc, z desc visit_dt desc) as rn
from mytable
) ranked
where rn = 1
order by name;