在 Case When 函数中有非布尔结果
Have non-boolean result in Case When Function
我正在尝试创建一个将结果分成不同列的查询。我能找到的最佳公式是 Case When 函数,但它表示等式的 Then 部分必须是布尔值(或 true/false 结果)。例如,Then 有没有办法计算数字 3-1?
Case
when
DATEDIFF(day, T0.[DocDueDate], getdate()) > 0
AND DATEDIFF(day, T0.[DocDueDate], getdate()) < 30
then
(T0.[DocTotal] - T0.[PaidToDate])
else
' '
end
as "Greater than 1",
Case
when
DATEDIFF(day, T0.[DocDueDate], getdate()) > 30
AND DATEDIFF(day, T0.[DocDueDate], getdate()) < 60
then
(T0.[DocTotal] - T0.[PaidToDate])
else
' '
end
as "Greater than 30"
如果您使用 sql 服务器,那么您的代码片段将如下所示。
你必须在 then
和 else
之后保持相同的数据类型,因为你在使用 else 之后使用字符串类型,所以你必须在以后转换它 then
Case
when
DATEDIFF(day, T0.[DocDueDate], getdate()) > 0
AND DATEDIFF(day, T0.[DocDueDate], getdate()) < 30
then
( convert(varchar(255), T0.[DocTotal] - T0.[PaidToDate]))
else
' '
end
as Greater_than_1,
Case
when
DATEDIFF(day, T0.[DocDueDate], getdate()) > 30
AND DATEDIFF(day, T0.[DocDueDate], getdate()) < 60
then
(convert(varchar(255), T0.[DocTotal] - T0.[PaidToDate]))
else
' '
end
as Greater_than_30
您遇到了类型兼容性问题。我建议您只使用 NULL
表示不匹配:
(case when DATEDIFF(day, T0.[DocDueDate], getdate()) > 0 AND DATEDIFF(day, T0.[DocDueDate], getdate()) < 30
then (T0.[DocTotal] - T0.[PaidToDate])
end) as Greater_than_1,
(case when DATEDIFF(day, T0.[DocDueDate], getdate()) > 30 and DATEDIFF(day, T0.[DocDueDate], getdate()) < 60
then (T0.[DocTotal] - T0.[PaidToDate])
end) as Greater_than_30
我还猜测您打算 <= 30
作为第一个条件。
发现我需要将等式转换为整数,如下所示。
Case when
DATEDIFF(day, T0.[DocDueDate], getdate()) > 0
AND DATEDIFF(day, T0.[DocDueDate], getdate()) <30
then
cast( (T0.[DocTotal]-T0.[PaidToDate]) as varchar(12) )
else
' '
end as "Greater than 1"
以下是您可以使用多种方法执行此操作的方法。 TSET 只是生成从 6 月 1 日到今天的测试日期。
WITH tset(td)
AS (
SELECT CAST('2018-08-01' AS DATE) AS td
UNION ALL
SELECT DATEADD(d, -1, td)
FROM tset
WHERE td > CAST('2018-06-01' AS DATE))
-- Actual examples start here
SELECT td
-- Diff is just showing the difference in days so you can see the group assignements
, DATEDIFF(d, td, GETDATE()) AS diff
-- This column groups into < 30, 31-60, and > 60
, CASE
WHEN DATEDIFF(d, td, GETDATE()) < 30 THEN 1 ELSE CASE
WHEN DATEDIFF(d, td, GETDATE()) < 60 THEN 2 ELSE 3
END
END three_sets
-- this example will group into any number of 30 day sets.
, cast ( DATEDIFF(d, td, GETDATE()) as int) / 30 any_number_of_sets
FROM tset
ORDER BY td;
一些示例结果:
td diff three_sets any_number_of_sets
2018-06-01 66 3 2
2018-06-02 65 3 2
2018-06-03 64 3 2
. . .
2018-06-12 55 2 1
2018-06-13 54 2 1
2018-06-14 53 2 1
. . .
2018-07-09 28 1 0
2018-07-10 27 1 0
2018-07-11 26 1 0
我正在尝试创建一个将结果分成不同列的查询。我能找到的最佳公式是 Case When 函数,但它表示等式的 Then 部分必须是布尔值(或 true/false 结果)。例如,Then 有没有办法计算数字 3-1?
Case
when
DATEDIFF(day, T0.[DocDueDate], getdate()) > 0
AND DATEDIFF(day, T0.[DocDueDate], getdate()) < 30
then
(T0.[DocTotal] - T0.[PaidToDate])
else
' '
end
as "Greater than 1",
Case
when
DATEDIFF(day, T0.[DocDueDate], getdate()) > 30
AND DATEDIFF(day, T0.[DocDueDate], getdate()) < 60
then
(T0.[DocTotal] - T0.[PaidToDate])
else
' '
end
as "Greater than 30"
如果您使用 sql 服务器,那么您的代码片段将如下所示。
你必须在 then
和 else
之后保持相同的数据类型,因为你在使用 else 之后使用字符串类型,所以你必须在以后转换它 then
Case
when
DATEDIFF(day, T0.[DocDueDate], getdate()) > 0
AND DATEDIFF(day, T0.[DocDueDate], getdate()) < 30
then
( convert(varchar(255), T0.[DocTotal] - T0.[PaidToDate]))
else
' '
end
as Greater_than_1,
Case
when
DATEDIFF(day, T0.[DocDueDate], getdate()) > 30
AND DATEDIFF(day, T0.[DocDueDate], getdate()) < 60
then
(convert(varchar(255), T0.[DocTotal] - T0.[PaidToDate]))
else
' '
end
as Greater_than_30
您遇到了类型兼容性问题。我建议您只使用 NULL
表示不匹配:
(case when DATEDIFF(day, T0.[DocDueDate], getdate()) > 0 AND DATEDIFF(day, T0.[DocDueDate], getdate()) < 30
then (T0.[DocTotal] - T0.[PaidToDate])
end) as Greater_than_1,
(case when DATEDIFF(day, T0.[DocDueDate], getdate()) > 30 and DATEDIFF(day, T0.[DocDueDate], getdate()) < 60
then (T0.[DocTotal] - T0.[PaidToDate])
end) as Greater_than_30
我还猜测您打算 <= 30
作为第一个条件。
发现我需要将等式转换为整数,如下所示。
Case when
DATEDIFF(day, T0.[DocDueDate], getdate()) > 0
AND DATEDIFF(day, T0.[DocDueDate], getdate()) <30
then
cast( (T0.[DocTotal]-T0.[PaidToDate]) as varchar(12) )
else
' '
end as "Greater than 1"
以下是您可以使用多种方法执行此操作的方法。 TSET 只是生成从 6 月 1 日到今天的测试日期。
WITH tset(td)
AS (
SELECT CAST('2018-08-01' AS DATE) AS td
UNION ALL
SELECT DATEADD(d, -1, td)
FROM tset
WHERE td > CAST('2018-06-01' AS DATE))
-- Actual examples start here
SELECT td
-- Diff is just showing the difference in days so you can see the group assignements
, DATEDIFF(d, td, GETDATE()) AS diff
-- This column groups into < 30, 31-60, and > 60
, CASE
WHEN DATEDIFF(d, td, GETDATE()) < 30 THEN 1 ELSE CASE
WHEN DATEDIFF(d, td, GETDATE()) < 60 THEN 2 ELSE 3
END
END three_sets
-- this example will group into any number of 30 day sets.
, cast ( DATEDIFF(d, td, GETDATE()) as int) / 30 any_number_of_sets
FROM tset
ORDER BY td;
一些示例结果:
td diff three_sets any_number_of_sets
2018-06-01 66 3 2
2018-06-02 65 3 2
2018-06-03 64 3 2
. . .
2018-06-12 55 2 1
2018-06-13 54 2 1
2018-06-14 53 2 1
. . .
2018-07-09 28 1 0
2018-07-10 27 1 0
2018-07-11 26 1 0