【发布时间】:2020-05-05 18:55:09
【问题描述】:
在此继续issue
主要代码:
CREATE TABLE params
(
id_param smallint PRIMARY KEY,
name varchar(50) NOT NULL
)
CREATE TABLE objects_params
(
id_object int,
id_param smallint NOT NULL,
cdate smalldatetime,
value int
)
INSERT INTO dbo.params (id_param, name)
VALUES (1, 'a'), (2, 'b'), (3, 'c'), (4, 'd'),
(5, 'e'), (6, 'f'), (7, 'g')
INSERT INTO dbo.objects_params (id_object, id_param, cdate, value)
VALUES (1, 1, '20191206',NULL), (1, 2,'20191212', 100), (1, 1, '20191201', 110),
(2, 4, '20191211',120), (2, 1,'20190101', 130), (2, 3, '20191212', 140),
(2, 4, '20191111',150), (2, 3,'20190201', 160), (2, 3, '20190312', 170),
(2, 3, '20191201', 175),(2, 3, '20191202', 180), (2, 3, '20191203', 185),
(2, 3, '20191204', 190)
然后我需要获取最接近给定日期的值列表:
DECLARE @userdate DATETIME
SET @userdate='20191202'
DECLARE @names as VARCHAR(MAX)
SELECT @names =
COALESCE(@names + ', ','') + QUOTENAME(name)
FROM
(SELECT distinct name
FROM objects_params
JOIN params ON objects_params.id_param = params.id_param
) AS B;
With t_sql as (
SELECT id_object, objects_params.id_param, name, cdate, value
FROM objects_params
JOIN params ON objects_params.id_param = params.id_param)
--Where value <> ''
SELECT id_object, id_param, name, cdate, value
FROM
(
SELECT RANK() OVER (PARTITION BY id_object, id_param ORDER BY abs(datediff(ss, @userdate,cdate)) ASC) AS DateRank, *
FROM t_sql
WHERE cdate < @userdate
)
AS DetailsRanking
WHERE DetailsRanking.DateRank=1
得到一个这样的表:
id_object id_param name cdate value
-----------------------------------------------
1 1 a 2019-12-01 110
2 1 a 2019-01-01 130
2 3 c 2019-12-01 175
2 4 d 2019-11-11 150
但是我怎样才能得到这种格式的结果:
id_object a b c d e f g
---------------------------------------------------------------
1 110 null null null null null null
2 130 null 175 150 null null null
我在这种情况下使用 pivot 的所有尝试都失败了。
更新
根据@Gordon Linoff 和@xXx 的建议,尝试重做代码以使用 Dinamic SQL,所以我们开始:
USE [DConturDb]
GO
DECLARE @userdate VARCHAR(MAX)
SET @userdate='20191202';
DECLARE @names as VARCHAR(MAX)
SELECT @names =
COALESCE(@names + ', ','') + QUOTENAME(name)
FROM
(SELECT name
FROM params
) AS B;
DECLARE @SQL as VARCHAR(MAX)
SET @SQL =
'WITH 操作为 ( 选择 op.id_object、op.id_param、名称、op.cdate、op.value、 ROW_NUMBER() OVER (PARTITION BY op.id_object, op.id_param ORDER BY op.cdate DESC) 作为 seqnum FROM objects_params 操作 JOIN 参数 p ON op.id_param = p.id_param
WHERE op.cdate <='''+ @userdate +'''
)
SELECT id_object, ' + @names + ' 从 ( 选择 id_object、值、名称 从操作 其中 seqnum=1 ) 作为 tbl 枢 ( (' + @names + ') 中的名称的最大值(值) ) piv'
execute(@SQL)
完成。
【问题讨论】:
-
这能回答你的问题吗? how to make your data horizontal
-
问题类似,但是,正如我在您的回答中所说,我想了解如何在此示例的上下文中使用它
标签: sql sql-server pivot