在 Select 中使用 Cast 作为 Decimal 和 Mod
Using Cast as Decimal and Mod in Select
我的 objective 是对两个 selected 字段执行两次计算。 formActionDate
是一个像 YYYMMDD
这样的整数,reminderFrequency
也是一个整数(代表天数的整数)。我想将整数日期除以天数。使用 mod(我认为这是最好的方法)我将决定是否需要发送电子邮件。例如,如果有剩余则不要发送电子邮件,或者如果没有剩余则电子邮件会消失。使用 SQL 2008 R2 我的 select:
SELECT
CAST(wfi.formActionDate/wf.reminderFrequency AS DECIMAL(18,1)) AS divCalc,
formActionDate%reminderFrequency AS modCalc
FROM (webFormsInstances AS wfi
Note - The query is running no problem but the calculations are both
out. Have I used them correctly?
第一个:
CAST(wfi.formActionDate/wf.reminderFrequency AS DECIMAL(18,3)) AS divCalc
正在这样做:
结果: 20150123 / 14
应该是 1439294.5
但它是 1439294.0
和 20150115 / 14
应该是 1439293.9
坚果它的 1439293.0
然后是第二个::
formActionDate%reminderFrequency AS modCalc
要使用上面相同的例子:
结果:20150123%14
应该是 5
但它是 13
和 20150115%14
应该是 9
但它是 7
我做错了什么?如果有帮助,这是我的完整查询:
SELECT
wfi.WebFormsInstanceID,
wfi.WebFormsIndexID,
wfi.FormStage,
wfi.FormAction,
wfi.FormActionDate,
wf.WebFormsIndexID,
wf.reminderFrequency,
CAST(wfi.formActionDate/wf.reminderFrequency AS DECIMAL(18,1)) AS divCalc,
formActionDate%reminderFrequency AS modCalc
FROM (webFormsInstances AS wfi
LEFT OUTER JOIN WebFormsIndex AS wf ON wfi.WebFormsIndexID = wf.WebFormsIndexID)
WHERE (wfi.formStage <> 'Complete' AND wfi.FormStage <> 'Terminated')
AND wfi.formActionDate < CONVERT(int, CONVERT(varchar(8), dateAdd(day,-14, getdate()), 112))
ORDER BY wfi.WebFormsInstanceID DESC;
谢谢你...
已编辑。感谢 Rigel1121 和 Dave G 现在在我的 select 中的两个解决方案是:
DATEDIFF(day, CAST(CAST(wfi.formActionDate AS VARCHAR(8)) AS DATE),CAST(GETDATE() AS DATE)) AS theDateDiffCalc,
和:
DATEDIFF(day, CAST(CAST(wfi.formActionDate AS VARCHAR(8)) AS DATE),CAST(GETDATE() AS DATE)) % wf.reminderFrequency AS theModCalc
尝试在除法之前做演员表,而不是之后。而不是
CAST(wfi.formActionDate/wf.reminderFrequency AS DECIMAL(18,1))
使用
wfi.formActionDate/CAST(wf.reminderFrequency AS DECIMAL(18,1))
两个整数相除得到一个整数(截去任何小数部分)。例如,SELECT 5 / 2;
是 2
(不是 2.5
)。如果将除法 (2
) 的结果转换为 DECIMAL(3,1)
,您将得到 2.0
,因为截断是除法的一部分。
但是,如果您在除法之前将其中一个操作数转换为小数,则除法的结果将不是整数,也不会丢失小数部分。 SELECT 5 / CAST(2 as DECIMAL(3,1));
是 2.5
.
对于 mod,20150123 % 14
应该得到 7 而 20150115 % 14
应该得到 13,在我的测试中他们确实如此。
当您将 int
与另一个 int
相除时,结果也将是 int
。您需要先将其中一个或两个参数都转换为 decimal
。例如:
SELECT CAST(wfi.formActionDate AS DECIMAL(18,1)) /
CAST(wf.reminderFrequency AS DECIMAL(18,1)) as divCalc
...snip...
关于 mod
计算,您的数学不适用于该格式的日期。您需要将 int
转换为真实的 datetime
值,获取与基准日期的差值,然后对该值使用 mod
。例如,要将该值作为日期,您可以先将其转换为 varchar
,然后将其转换为 date
:
DECLARE @datevalue int = 20150209
SELECT DATEDIFF(DAY, '2000-01-01', CAST(CAST(@datevalue AS VARCHAR(8)) AS DATE))%14
通过检查您的查询,发现有一个不必要的括号。所以我删除了它。我还修改了如何获取 divCalc
的值。我 CAST
分子和分母,我把它放在 CASE
语句中,以防止 wf.reminderFrequency
的值为零时出现 SQL 错误。我还使用 DATEDIFF
函数来获取 modCalc
。见下文:
SELECT
wfi.WebFormsInstanceID,
wfi.WebFormsIndexID,
wfi.FormStage,
wfi.FormAction,
wfi.FormActionDate,
wf.WebFormsIndexID,
wf.reminderFrequency,
CASE WHEN CAST(wf.reminderFrequency AS DECIMAL(18,1))=0.0 THEN 0.0 ELSE CAST(wfi.formActionDate AS DECIMAL(18,1)) / CAST(wf.reminderFrequency AS DECIMAL(18,1)) END as divCalc,
DATEDIFF(DAY, '2000-01-01', CAST(CAST(wfi.formActionDate AS VARCHAR(8)) AS DATE)%wf.reminderFrequency as modCalc
FROM webFormsInstances as wfi
LEFT OUTER JOIN WebFormsIndex as wf ON wfi.WebFormsIndexID = wf.WebFormsIndexID
WHERE (wfi.formStage <> 'Complete' AND wfi.FormStage <> 'Terminated')
AND wfi.formActionDate < CONVERT(int, CONVERT(varchar(8), dateAdd(day,-14, getdate()), 112))
ORDER BY wfi.WebFormsInstanceID DESC;
我的 objective 是对两个 selected 字段执行两次计算。 formActionDate
是一个像 YYYMMDD
这样的整数,reminderFrequency
也是一个整数(代表天数的整数)。我想将整数日期除以天数。使用 mod(我认为这是最好的方法)我将决定是否需要发送电子邮件。例如,如果有剩余则不要发送电子邮件,或者如果没有剩余则电子邮件会消失。使用 SQL 2008 R2 我的 select:
SELECT
CAST(wfi.formActionDate/wf.reminderFrequency AS DECIMAL(18,1)) AS divCalc,
formActionDate%reminderFrequency AS modCalc
FROM (webFormsInstances AS wfi
Note - The query is running no problem but the calculations are both out. Have I used them correctly?
第一个:
CAST(wfi.formActionDate/wf.reminderFrequency AS DECIMAL(18,3)) AS divCalc
正在这样做:
结果: 20150123 / 14
应该是 1439294.5
但它是 1439294.0
和 20150115 / 14
应该是 1439293.9
坚果它的 1439293.0
然后是第二个::
formActionDate%reminderFrequency AS modCalc
要使用上面相同的例子:
结果:20150123%14
应该是 5
但它是 13
和 20150115%14
应该是 9
但它是 7
我做错了什么?如果有帮助,这是我的完整查询:
SELECT
wfi.WebFormsInstanceID,
wfi.WebFormsIndexID,
wfi.FormStage,
wfi.FormAction,
wfi.FormActionDate,
wf.WebFormsIndexID,
wf.reminderFrequency,
CAST(wfi.formActionDate/wf.reminderFrequency AS DECIMAL(18,1)) AS divCalc,
formActionDate%reminderFrequency AS modCalc
FROM (webFormsInstances AS wfi
LEFT OUTER JOIN WebFormsIndex AS wf ON wfi.WebFormsIndexID = wf.WebFormsIndexID)
WHERE (wfi.formStage <> 'Complete' AND wfi.FormStage <> 'Terminated')
AND wfi.formActionDate < CONVERT(int, CONVERT(varchar(8), dateAdd(day,-14, getdate()), 112))
ORDER BY wfi.WebFormsInstanceID DESC;
谢谢你...
已编辑。感谢 Rigel1121 和 Dave G 现在在我的 select 中的两个解决方案是:
DATEDIFF(day, CAST(CAST(wfi.formActionDate AS VARCHAR(8)) AS DATE),CAST(GETDATE() AS DATE)) AS theDateDiffCalc,
和:
DATEDIFF(day, CAST(CAST(wfi.formActionDate AS VARCHAR(8)) AS DATE),CAST(GETDATE() AS DATE)) % wf.reminderFrequency AS theModCalc
尝试在除法之前做演员表,而不是之后。而不是
CAST(wfi.formActionDate/wf.reminderFrequency AS DECIMAL(18,1))
使用
wfi.formActionDate/CAST(wf.reminderFrequency AS DECIMAL(18,1))
两个整数相除得到一个整数(截去任何小数部分)。例如,SELECT 5 / 2;
是 2
(不是 2.5
)。如果将除法 (2
) 的结果转换为 DECIMAL(3,1)
,您将得到 2.0
,因为截断是除法的一部分。
但是,如果您在除法之前将其中一个操作数转换为小数,则除法的结果将不是整数,也不会丢失小数部分。 SELECT 5 / CAST(2 as DECIMAL(3,1));
是 2.5
.
对于 mod,20150123 % 14
应该得到 7 而 20150115 % 14
应该得到 13,在我的测试中他们确实如此。
当您将 int
与另一个 int
相除时,结果也将是 int
。您需要先将其中一个或两个参数都转换为 decimal
。例如:
SELECT CAST(wfi.formActionDate AS DECIMAL(18,1)) /
CAST(wf.reminderFrequency AS DECIMAL(18,1)) as divCalc
...snip...
关于 mod
计算,您的数学不适用于该格式的日期。您需要将 int
转换为真实的 datetime
值,获取与基准日期的差值,然后对该值使用 mod
。例如,要将该值作为日期,您可以先将其转换为 varchar
,然后将其转换为 date
:
DECLARE @datevalue int = 20150209
SELECT DATEDIFF(DAY, '2000-01-01', CAST(CAST(@datevalue AS VARCHAR(8)) AS DATE))%14
通过检查您的查询,发现有一个不必要的括号。所以我删除了它。我还修改了如何获取 divCalc
的值。我 CAST
分子和分母,我把它放在 CASE
语句中,以防止 wf.reminderFrequency
的值为零时出现 SQL 错误。我还使用 DATEDIFF
函数来获取 modCalc
。见下文:
SELECT
wfi.WebFormsInstanceID,
wfi.WebFormsIndexID,
wfi.FormStage,
wfi.FormAction,
wfi.FormActionDate,
wf.WebFormsIndexID,
wf.reminderFrequency,
CASE WHEN CAST(wf.reminderFrequency AS DECIMAL(18,1))=0.0 THEN 0.0 ELSE CAST(wfi.formActionDate AS DECIMAL(18,1)) / CAST(wf.reminderFrequency AS DECIMAL(18,1)) END as divCalc,
DATEDIFF(DAY, '2000-01-01', CAST(CAST(wfi.formActionDate AS VARCHAR(8)) AS DATE)%wf.reminderFrequency as modCalc
FROM webFormsInstances as wfi
LEFT OUTER JOIN WebFormsIndex as wf ON wfi.WebFormsIndexID = wf.WebFormsIndexID
WHERE (wfi.formStage <> 'Complete' AND wfi.FormStage <> 'Terminated')
AND wfi.formActionDate < CONVERT(int, CONVERT(varchar(8), dateAdd(day,-14, getdate()), 112))
ORDER BY wfi.WebFormsInstanceID DESC;