我正在尝试解决一个我似乎找不到简单解决方案的问题。我正在尝试编写一个查询,该查询使用 case when 语句根据某些计数返回值。在同一个查询中,我还需要返回一个 orderid,因为我需要利用它返回的数据进行另一个查询。
下面是查询:
select CASE WHEN count(name) = 0 THEN '1' ELSE CONVERT(varchar,count(name) + 1) END AS box
, orderid
from order
where len(name) = 7
and orderid = 'XYZ'
group by orderid
上面的问题是,正如您可以想象的那样,仅当数据中存在长度为 7 的名称时,才会返回一行。无论如何,我需要此查询返回有效值。
查询应返回:1, XYZ
,当不存在长度为 7 的名称时。当存在有效的 7 长度名称时,查询确实有效。
处理此问题的最佳方法是什么?请注意,数据可以包含长度小于 7 的多个名称。然后,这些名称将在交易发生后更改为长度 7。
以下是示例数据和所需结果:
NAME ORDERID
ABC 001
XYZ 001
123 001
OOP 002
LMT 002
当我运行orderid = '1'
查询时,查询应返回1, 001
。数据将不断变化,因此最初如上图所示。随着事务的发生,数据将更改为:
NAME ORDERID
ABCABCABC 001
XYZ 001
123 001
OOP 002
LMT 002
此时,我不必担心上面的查询,因为它将返回有效行:2, 001
问题是当名称列的长度不正确时,查询不返回任何内容。
你可能想要这个:
select convert(varchar(255),
sum(case when len(name) = 7 and orderid = 'XYZ' then 1 else 0 end) + 1
end) as box,
orderid
from order
group by orderid;
这会将所有过滤逻辑移动到select
中。
如果您想要的是一行带有计数和订单 ID,最好是 XYZ,但如果不可用,则还有其他内容:
select convert(varchar(255),
sum(case when len(name) = 7 and orderid = 'XYZ' then 1 else 0 end) + 1
end) as box,
coalesce(max(case when orderid = 'XYZ' then orderid end),
max(orderid)
) as orderid
from order
group by orderid;
当没有名字有lenth 7时,你应该使用以下查询
选择 CASE WHEN COUNT(名称( = 0 和 len(name(!=7 然后"1"否则转换(VARCHAR,计数(名称( + 1( 结束为框 、订单 ID 从订单 其中 orderid = 'XYZ' 按顺序 ID 分组
非常丑陋,但通过左连接到由 1 条记录组成的内联视图, B 中的每条记录都获得 XYZ,因此我们保证至少有 1 条记录;如果 order 的名称长度为 7,那么我们使用这些值,否则 order 左连接将为 null,我们合并内联视图中的值。
通常我会在 UI 中执行此类操作,如果没有返回任何记录,请在表示层而不是此处处理。
但是,如果您必须:
未经测试(我还看不到逻辑缺陷或语法缺陷,但我没有测试环境(
SELECT coalesce(CASE WHEN count(a.name) = 0
THEN '1'
ELSE CONVERT(varchar,count(a.name) + 1) END
,b.Box) AS box
, coalesce(a.orderid,b.orderID)
FROM (SELECT '1' Box, 'xyz' OrderID) b
LEFT join [order] A
on 1=1
and len(a.name) = 7
and a.orderid = 'XYZ'
GROUP BY coalesce(a.orderid,b.OrderID)