Sql 选择值等于给定值或小于给定值且最接近该值的行
很抱歉把标题弄混了。请告诉我,是否可以通过db请求进行。假设我们有下表Sql 选择值等于给定值或小于给定值且最接近该值的行,sql,database,sql-server-2008,Sql,Database,Sql Server 2008,很抱歉把标题弄混了。请告诉我,是否可以通过db请求进行。假设我们有下表 ind_id name value date ----------- -------------------- ----------- ---------- 1 a 10 2010-01-01 1 a 20 2010
ind_id name value date
----------- -------------------- ----------- ----------
1 a 10 2010-01-01
1 a 20 2010-01-02
1 a 30 2010-01-03
2 b 10 2010-01-01
2 b 20 2010-01-02
2 b 30 2010-01-03
2 b 40 2010-01-04
3 c 10 2010-01-01
3 c 20 2010-01-02
3 c 30 2010-01-03
3 c 40 2010-01-04
3 c 50 2010-01-05
4 d 10 2010-01-05
我需要查询所有行以包含给定日期的每个ind_id一次,如果给定日期没有ind_id,则取最近的较低日期,如果没有任何较低日期,则返回ind_id+name/ind_id对等于null。
例如,日期为2010-01-04,我希望得到以下结果:
ind_id name value date
----------- -------------------- ----------- ----------
1 a 30 2010-01-03
2 b 40 2010-01-04
3 c 40 2010-01-04
4 d NULL NULL
如果可能的话,如果有人帮我建立查询,我将非常感激。我使用的是SQL server 2008。您可以使用以下内容:
declare @date date = '2010-01-04'
;with ids as
(
select distinct ind_id
from myTable
)
,ranks as
(
select *
, ranking = row_number() over (partition by ind_id order by date desc)
from myTable
where date <= @date
)
select ids.ind_id
, ranks.value
, ranks.date
from ids
left join ranks on ids.ind_id = ranks.ind_id and ranks.ranking = 1
与前一个一样,最好通过连接到一个固定的数据表(如果可用)来获取ind_id/name信息。这不是确切的答案,但会给你一个概念,因为我只是快速地写下它,不需要任何测试
use
go
if
(Select value from table where col=@col1) is not null
--you code to get the match value
else if
(Select LOWER(Date) from table ) is not null
-- your query to get the nerst dtae record
else
--you query withh null value
end
更新尝试:
with cte as
(select m.*,
max(date) over (partition by ind_id) max_date,
max(case when date <= @date then date end) over
(partition by ind_id) max_acc_date
from myTable m)
select ind_id,
name,
case when max_acc_date is null then null else value end value,
max_acc_date date
from cte c
where date = coalesce(max_acc_date, max_date)
SQLFIDLE以下是一个查询,返回您要查找的结果:
SELECT
t1.ind_id
, CASE WHEN t1.date <= '2010-01-04' THEN t1.value ELSE null END
FROM test t1
WHERE t1.date=COALESCE(
(SELECT MAX(DATE)
FROM test t2
WHERE t2.ind_id=t1.ind_id AND t2.date <= '2010-01-04')
, t1.date)
其思想是在相关查询中选择一行,使其ID与当前行的ID匹配,并且该日期是目标日期“2010-01-04”之前的最高日期
如果该行不存在,则返回当前行的日期。此日期需要替换为空;这就是上面的案例陈述所做的
这是一张支票。检查一下
将选项与运算符一起使用
试一试
DECLARE @date DATETIME;
SET @date = '2010-01-04';
WITH temp1 AS
(
SELECT t.ind_id
, t.name
, CASE WHEN t.date <= @date THEN t.value ELSE NULL END AS value
, CASE WHEN t.date <= @date THEN t.date ELSE NULL END AS date
FROM test1 AS t
),
temp AS
(
SELECT *, ROW_NUMBER() OVER (PARTITION BY ind_id ORDER BY t.date DESC) AS rn
FROM temp1 AS t
WHERE t.date <= @date OR t.date IS NULL
)
SELECT *
FROM temp AS t
WHERE rn = 1
名称/标识id对相等-这是否意味着对于给定的标识,名称将始终相同?如果是这样,它代表数据库模式中的非规范化,除非底层数据来自多个表-显示的数据是来自单个表还是来自多个表?@Mark Bannister是的,我知道,这个表是另一个请求的结果:好的,它来自单个表-谢谢。谢谢,伙计们!如果我能接受所有的答案:感谢你的深刻见解,是的,前面的答案是错误的。Timofei没有要求maxvalue。我给出了答案和相应的演示。
with CTE_test
as
(
select int_id,
max(date) MaxDate
from test
where date<='2010-01-04 00:00:00:000'
group by int_id
)
select A.int_id, A.[Value], A.[Date]
from test A
inner join CTE_test B
on a.int_id=b.int_id
and a.date = b.Maxdate
union all
select int_id, null, null
from test
where int_id not in (select int_id from CTE_test)
DECLARE @date date = '20100104'
SELECT ind_id,
CASE WHEN date <= @date THEN value END AS value,
CASE WHEN date <= @date THEN date END AS date
FROM dbo.test57 t
WHERE EXISTS (
SELECT 1
FROM dbo.test57 t2
WHERE t.ind_id = t2.ind_id AND t2.date <= @date
HAVING ISNULL(MAX(t2.date), t.date) = t.date
)
DECLARE @date DATETIME;
SET @date = '2010-01-04';
WITH temp1 AS
(
SELECT t.ind_id
, t.name
, CASE WHEN t.date <= @date THEN t.value ELSE NULL END AS value
, CASE WHEN t.date <= @date THEN t.date ELSE NULL END AS date
FROM test1 AS t
),
temp AS
(
SELECT *, ROW_NUMBER() OVER (PARTITION BY ind_id ORDER BY t.date DESC) AS rn
FROM temp1 AS t
WHERE t.date <= @date OR t.date IS NULL
)
SELECT *
FROM temp AS t
WHERE rn = 1