以下图像是Microsoft SQL Server 2008 R2系统视图的一部分。从图像中我们可以看出sys.partitions
和sys.allocation_units
之间的关系取决于sys.allocation_units.type
的值。因此,为了将它们加在一起,我会写一些与此类似的东西:
SELECT *
FROM sys.indexes i
JOIN sys.partitions p
ON i.index_id = p.index_id
JOIN sys.allocation_units a
ON CASE
WHEN a.type IN (1, 3)
THEN a.container_id = p.hobt_id
WHEN a.type IN (2)
THEN a.container_id = p.partition_id
END
但是上面的代码给出了语法错误。我猜这是因为CASE
声明。
任何人都可以帮忙解释一下吗?
谢谢!
添加错误消息:
Msg 102,Level 15,State 1,Line 6'='附近的语法不正确。
答案 0 :(得分:178)
CASE
表达式从子句的THEN
部分返回一个值。你可以这样使用它:
SELECT *
FROM sys.indexes i
JOIN sys.partitions p
ON i.index_id = p.index_id
JOIN sys.allocation_units a
ON CASE
WHEN a.type IN (1, 3) AND a.container_id = p.hobt_id THEN 1
WHEN a.type IN (2) AND a.container_id = p.partition_id THEN 1
ELSE 0
END = 1
请注意,您需要对返回的值执行某些操作,例如将它与1.进行比较。您的语句试图返回赋值或测试的值,以确保它们在CASE
/ THEN
子句的上下文中是否有意义。 (如果BOOLEAN
是一种数据类型,那么相等性测试就有意义了。)
答案 1 :(得分:29)
相反,您只需加入两个表,并在SELECT子句中, 返回匹配的数据:
我建议您浏览此链接Conditional Joins in SQL Server和T-SQL Case Statement in a JOIN ON Clause
e.g。
SELECT *
FROM sys.indexes i
JOIN sys.partitions p
ON i.index_id = p.index_id
JOIN sys.allocation_units a
ON a.container_id =
CASE
WHEN a.type IN (1, 3)
THEN p.hobt_id
WHEN a.type IN (2)
THEN p.partition_id
END
编辑:根据评论。
您不能像正在做的那样指定连接条件。检查 上面的查询没有错误。我已经把共同栏目拿出来了 并且将根据条件评估正确的列值。
答案 2 :(得分:16)
试试这个:
...JOIN sys.allocation_units a ON
(a.type=2 AND a.container_id = p.partition_id)
OR (a.type IN (1, 3) AND a.container_id = p.hobt_id)
答案 3 :(得分:4)
我认为您需要两个案例陈述:
SELECT *
FROM sys.indexes i
JOIN sys.partitions p
ON i.index_id = p.index_id
JOIN sys.allocation_units a
ON
-- left side of join on statement
CASE
WHEN a.type IN (1, 3)
THEN a.container_id
WHEN a.type IN (2)
THEN a.container_id
END
=
-- right side of join on statement
CASE
WHEN a.type IN (1, 3)
THEN p.hobt_id
WHEN a.type IN (2)
THEN p.partition_id
END
这是因为:
答案 4 :(得分:2)
是的,可以。这是一个例子。
SELECT a.*
FROM TableA a
LEFT OUTER JOIN TableB j1 ON (CASE WHEN LEN(COALESCE(a.NoBatiment, '')) = 3
THEN RTRIM(a.NoBatiment) + '0'
ELSE a.NoBatiment END ) = j1.ColumnName
答案 5 :(得分:1)
这看起来很不错
https://bytes.com/topic/sql-server/answers/881862-joining-different-tables-based-condition
FROM YourMainTable
LEFT JOIN AirportCity DepCity ON @TravelType = 'A' and DepFrom = DepCity.Code
LEFT JOIN AirportCity DepCity ON @TravelType = 'B' and SomeOtherColumn = SomeOtherColumnFromSomeOtherTable
答案 6 :(得分:1)
我以您的示例为例,对其进行了编辑:
SELECT *
FROM sys.indexes i
JOIN sys.partitions p
ON i.index_id = p.index_id
JOIN sys.allocation_units a
ON CASE
WHEN a.type IN (1, 3)
THEN p.hobt_id
WHEN a.type IN (2)
THEN p.partition_id
ELSE NULL
END = a.container_id
答案 7 :(得分:0)
这里我比较了两种不同结果集的差异。希望这可能会有所帮助。
SELECT main.ColumnName, compare.Value PreviousValue, main.Value CurrentValue
FROM
(
SELECT 'Name' AS ColumnName, 'John' as Value UNION ALL
SELECT 'UserName' AS ColumnName, 'jh001' as Value UNION ALL
SELECT 'Department' AS ColumnName, 'HR' as Value UNION ALL
SELECT 'Phone' AS ColumnName, NULL as Value UNION ALL
SELECT 'DOB' AS ColumnName, '1993-01-01' as Value UNION ALL
SELECT 'CreateDate' AS ColumnName, '2017-01-01' as Value UNION ALL
SELECT 'IsActive' AS ColumnName, '1' as Value
) main
INNER JOIN
(
SELECT 'Name' AS ColumnName, 'Rahul' as Value UNION ALL
SELECT 'UserName' AS ColumnName, 'rh001' as Value UNION ALL
SELECT 'Department' AS ColumnName, 'HR' as Value UNION ALL
SELECT 'Phone' AS ColumnName, '01722112233' as Value UNION ALL
SELECT 'DOB' AS ColumnName, '1993-01-01' as Value UNION ALL
SELECT 'CreateDate' AS ColumnName, '2017-01-01' as Value UNION ALL
SELECT 'IsActive' AS ColumnName, '1' as Value
) compare
ON main.ColumnName = compare.ColumnName AND
CASE
WHEN main.Value IS NULL AND compare.Value IS NULL THEN 0
WHEN main.Value IS NULL AND compare.Value IS NOT NULL THEN 1
WHEN main.Value IS NOT NULL AND compare.Value IS NULL THEN 1
WHEN main.Value <> compare.Value THEN 1
END = 1
答案 8 :(得分:0)
以DonkeyKong为例。
问题是我需要使用声明的变量。这样可以说明需要比较的内容的左侧和右侧。这是为了支持SSRS报告,其中必须根据用户的选择来链接不同的字段。
初始情况根据选择设置字段选择 然后我可以设置要加入的字段。
如果第二个case语句可以添加到右侧 需要从不同字段中选择变量
LEFT OUTER JOIN Dashboard_Group_Level_Matching ON
case
when @Level = 'lvl1' then cw.Lvl1
when @Level = 'lvl2' then cw.Lvl2
when @Level = 'lvl3' then cw.Lvl3
end
= Dashboard_Group_Level_Matching.Dashboard_Level_Name
答案 9 :(得分:0)
根据条件至少有两种加入方式。一个比另一个更快:
declare @loopZaKosovnice int = 1
select *
from tHE_MoveItem mi
left join tHE_SetProdSt st on st.acIdent = mi.acIdent
-- slow
--join the_setitem si on si.acident = case when @loopZaKosovnice = 0 then mi.acident else st.acIdentChild end
-- two times as fast
left join the_setitem si1 on @loopZaKosovnice = 0 and si1.acident = mi.acident
left join the_setitem si2 on @loopZaKosovnice = 1 and si2.acident = st.acIdentChild
join the_setitem si on si.acident = isnull (si1.acident, si2.acIdent)