我已经发布了一些有关我要编写的系统的问题,对问这么多问题感到很沮丧。但是,对于SQL Server的高级元素,我还是一个新手(或者是几年前的重访),所以请原谅并帮助我!
我已将数据从JSON导入到表中,该表中包含许多不同的信息,其中之一是随着时间的推移记录的人的体重。我有以下代码来生成此代码:
SELECT ServiceUserID, PersonID, ServiceUser, DateDone, [Weight]
FROM
( SELECT ServiceUserID, PersonID, ServiceUser, DateDone, LEFT(SUBSTRING(cn.Fragment, PATINDEX('%[0-9.-]%', cn.Fragment), 8000),
PATINDEX('%[^0-9.-]%', SUBSTRING(cn.Fragment, PATINDEX('%[0-9.-]%', cn.Fragment), 8000) + 'X') -1) AS [Weight], ra.ScoreMeaning
FROM [JSONCareNotes-HOME] cn
LEFT OUTER JOIN [JSONRAs-HOME] ra ON ra.PersonID = cn.ServiceUserID
WHERE cn.SliderData LIKE '%weigh%'
and cn.Fragment NOT LIKE '%weighed%'
) AS SubQueryAlias
WHERE NOT ([Weight] IS NULL OR [Weight] = ' ')
ORDER BY ServiceUser, DateDone DESC
我从中得到的是(一个样本):
7e54d569-0ad2-43a9-aada-5f37480fdfd4 NULL Resident 1 2019-11-16 83.1
19e0d4b1-8fe4-4480-b99b-5d067123121e NULL Resident 2 2019-11-16 63.8
ba2a406f-2e28-4186-a5a0-95d93bb20ca9 NULL Resident 3 2019-11-10 54
ecfa663b-3dd2-4aef-b25c-e43dd6b82ebb NULL Resident 4 2019-11-16 81.5
8a5880af-1d7f-4b96-ae28-4de4fb1a4685 NULL Resident 5 2019-11-28 60.9
8a5880af-1d7f-4b96-ae28-4de4fb1a4685 NULL Resident 5 2019-11-21 61
8a5880af-1d7f-4b96-ae28-4de4fb1a4685 NULL Resident 5 2019-11-01 62.05
91495cd7-054d-47d5-9be0-dd3123342f19 NULL Resident 6 2019-11-16 52.9
be79adef-01c2-4fe9-86b1-9d42fe9fe012 NULL Resident 7 2019-11-28 45.8
我想要下面的输出,以居民5为例:
Resident Name Date Value %age Change
Resident 5 2019-11-01 62.05 n/a
2019-11-21 61 -1.69
2019-11-28 60.9 -1.85
最终,我希望能够说出从第一个日期,或者从通过变量输入的日期到最后一个日期或另一个定义的结束日期变量,列表中每个居民的百分比变化。大多数居民都会有很多条目,我只是想举一个例子。
如果这是在Delphi之类的地方(我知道是旧学校),那么这将相对容易。但是,出于清楚的原因,我正在尝试在SQL Server中进行尽可能多的处理。谁能提供任何指导?我知道使用LAG可能会找到上一行用作比较,但是我发现很难一次遍历整个EACH居民的整个表,然后生成那种列表以上。或者,最好只是遍历整个表,然后为每个人运行一个理货(这似乎是一条更为复杂的路线)。
谢谢蚂蚁
编辑(20/12)
感谢@Zhorov,我现在非常亲密。但是,虽然在div / 0出现之前我似乎无法获得多达10个条目的准确结果,但现在我的得分很高,我敢肯定,这是因为我搞砸了实施您的建议的方法。现在的代码是
;WITH cte AS (SELECT ServiceUserID, ra.PersonID, ServiceUser, cn.DateDone, TRY_CAST((LEFT(SUBSTRING(cn.Fragment, PATINDEX('%[0-9.-]%', cn.Fragment), 8000),
PATINDEX('%[^0-9.-]%', SUBSTRING(cn.Fragment, PATINDEX('%[0-9.-]%', cn.Fragment), 8000) + 'X') -1)) AS REAL) AS [Weight], ra.ScoreMeaning
FROM [JSONCareNotes-HOME] cn
LEFT OUTER JOIN [JSONRAs-HOME] ra ON ra.PersonID = cn.ServiceUserID
WHERE cn.SliderData LIKE '%weigh%'
AND cn.Fragment NOT LIKE '%weighed%'
)
SELECT
ServiceUser,
DateDone,
[Weight],
CASE
WHEN FIRST_VALUE([Weight] ) OVER (PARTITION BY [ServiceUser] ORDER BY DateDone ASC) = 0 THEN 0
ELSE CONVERT(
numeric(10, 2),
[Weight] - FIRST_VALUE([Weight]) OVER (PARTITION BY [ServiceUser] ORDER BY DateDone ASC) /
FIRST_VALUE([Weight]) OVER (PARTITION BY [ServiceUser] ORDER BY DateDone ASC) *
100.0
)
END
AS [Percentage]
FROM cte
WHERE NOT([Weight] IS NULL) OR [Weight] = ' '
ORDER BY ServiceUser, DateDone ASC
这给了我以下结果:
Resident 1 2019-11-16 83.1 -16.90
Resident 2 2019-11-16 63.8 -36.20
Resident 3 2019-11-10 54 -46.00
Resident 4 2019-11-16 81.5 -18.50
Resident 5 2019-11-01 62.05 -37.95
Resident 5 2019-11-21 61 -39.00
Resident 5 2019-11-28 60.9 -39.10
Resident 6 2019-11-16 52.9 -47.10
Resident 7 2019-11-14 40 -60.00
Resident 7 2019-11-21 42 -58.00
Resident 7 2019-11-28 45.8 -54.20
Resident 8 2019-11-21 48.1 -51.90
Resident 8 2019-11-28 50.2 -49.80
我在某处想念东西!谁能为我找到它?我认为不是每个新居民都会重置吗?
更新:
看来,您的[Weight]列将数字保存为文本。尝试使用TRY_CONVERT()(numeric(10, 2)只是测试数据类型,请使用适当的数字数据类型)转换这些值。一种可能的方法是:
SELECT ServiceUserID, PersonID, ServiceUser, DateDone, [Weight]
FROM (
SELECT
ServiceUserID,
PersonID,
ServiceUser,
DateDone,
TRY_CONVERT(
numeric(10, 2),
LEFT(SUBSTRING(cn.Fragment, PATINDEX('%[0-9.-]%', cn.Fragment), 8000), PATINDEX('%[^0-9.-]%', SUBSTRING(cn.Fragment, PATINDEX('%[0-9.-]%', cn.Fragment), 8000) + 'X') -1)
) AS [Weight],
ra.ScoreMeaning
FROM [JSONCareNotes-HOME] cn
LEFT OUTER JOIN [JSONRAs-HOME] ra ON ra.PersonID = cn.ServiceUserID
WHERE cn.SliderData LIKE '%weigh%' and cn.Fragment NOT LIKE '%weighed%'
) AS SubQueryAlias
WHERE [Weight] IS NOT NULL
ORDER BY ServiceUser, DateDone DESC
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。