SQL Cast Sub Select to a bit
Posted
技术标签:
【中文标题】SQL Cast Sub Select to a bit【英文标题】: 【发布时间】:2020-05-13 01:10:39 【问题描述】:场景:我有项目和销售订单。一个项目可以有多个销售订单。一个项目也可以有多个“活动”销售订单。所以有3个表:
项目 SalesOrders:具有项目表的外键 ActiveSalesOrders:具有 ID、ProjectID 和 SalesOrderID我想要一个返回许多销售订单的 select 语句。我想创建一个计算列是真还是假。这一列基本上是“ActiveSalesOrder 表中是否包含我的 ID”。
所以我使用 w3schools 数据库进行测试,因为我当前的数据库还没有数据。所以转换为:
项目 = 订单 SalesOrders = 产品 ActiveSalesOrders = OrderDetails这里是运行 sql 命令到他们的数据库的链接:here
这是我运行的 sql。有效!!
SELECT pr.ProductID,
pr.ProductName,
pr.Price,
CAST(CASE WHEN Price > 20 THEN 1 ELSE 0 END AS BIT) AS IsAbove20,
CAST(
EXISTS(
SELECT od.ProductID
FROM [OrderDetails] od
WHERE od.ProductID = pr.ProductID
) AS BIT
) AS HasOrderDetails
FROM [Products] pr
但是当我在 SQL 管理中运行它时,它会用 as
抱怨转换:
(注意:这是转换回我的数据模型,而不是 w3schools 的数据模型)
错误消息:“'as' 附近的语法不正确。需要 '、'、AND 或 OR。”
不知道从这里去哪里。我花了很多时间试图创建“Cast”语句,并且很高兴它在 w3school 的引擎上工作,但在 SQL Server 上却不行。关于在哪里可以找到此问题的解决方案的任何想法或链接?
【问题讨论】:
【参考方案1】:SQL Server 没有布尔类型。您需要使用CASE
表达式:
SELECT pr.ProductID,
pr.ProductName,
pr.Price,
CAST(CASE WHEN Price > 20 THEN 1 ELSE 0 END AS BIT) AS IsAbove20,
CAST(CASE WHEN EXISTS (SELECT od.ProductID
FROM OrderDetails od
WHERE od.ProductID = pr.ProductID
)
THEN 1
ELSE 0
END AS BIT) AS HasOrderDetails
FROM Products pr;
确实没有理由选择列作为位。 0/1 数字很好。 bit
数据类型在 SQL Server 中不是真正的布尔值,因此它只会为屏蔽操作带来额外的开销。
【讨论】:
我一直将“Bit”视为布尔值,这就是我的第一个问题。我没有想到使用“案例”功能。所以基本上我从你的最后一句话中了解到,没有理由“转换”“Case”函数,因为我返回的是 1 或 0,对吗? @jediderek 。 . .完全没有理由。 明白了,我很感激你教给我的关于“Bits”的课程。【参考方案2】:正如@Gordon Linoff 教我的那样,最好不要像我正在做的那样将列投射到“位”,因为它会增加开销。所以我的回答删除了 Casting 以显示最佳实践。谢谢!
SELECT pr.ProductID,
pr.ProductName,
pr.Price,
CASE
WHEN EXISTS(
SELECT od.ProductID
FROM [OrderDetails] od
WHERE od.ProductID = pr.ProductID
) THEN 1
ELSE 0
END AS HasOrderDetails
FROM [Products] pr;
【讨论】:
以上是关于SQL Cast Sub Select to a bit的主要内容,如果未能解决你的问题,请参考以下文章
FlinkFlink SQL 报错 ClassCastException: VarCharType cannot be cast to RowType