有条件加入MS SQL
我有一个DB表来存储基本的历史。我试图保持它超级通用。有条件加入MS SQL
表看起来像:
HistoryID Action Table PrimaryKey Field OldValue NewValue User DateTime
--------------------------------------------------------------------------------------------------------------------------------------------
240233 Added QueueItem 17177 QueueItemID 17177 XXXXXXXXXXXXXXX 2016-09-16 08:38:58.060
240237 Modified QueueItem 17177 StatusTypeID 1 2 XXXXXXXXXXXXXXX 2016-09-16 08:38:59.163
240240 Modified QueueItem 17177 StatusTypeID 2 3 XXXXXXXXXXXXXXX 2016-09-16 08:39:00.850
240241 Modified QueueItem 17177 PackageID 0 XXXXXXXXXXXXXXX 2016-09-16 08:39:00.850
240249 Modified QueueItem 17177 StatusTypeID 3 4 XXXXXXXXXXXXXXX 2016-09-16 08:39:09.207
240256 Modified QueueItem 17177 StatusTypeID 4 5 XXXXXXXXXXXXXXX 2016-09-16 08:39:10.163
240257 Modified QueueItem 17177 OutputDateTime 9/16/2016 8:39:10 XXXXXXXXXXXXXXX 2016-09-16 08:39:10.163
什么我不知道是可能的,是取决于Field
值有条件地加入。我想我会不得不使用t-SQL,虽然我有点卡住了。
我可以做一个单独的选择,然后结合我所有的结果,但不确定是否有更好的方法?
伪代码将是这样的:
select h.*, s.[name] from history h
some kind of condition that when satified joins the statusType table and if not, then perhaps sets s.[name] to null
我想是这样的,它适用于“状态从”,但不是“StatusTo” - 失败,因为它不能转换日期的最后一排到一个int。
select h.*,
so.[Name] as StatusFrom,
sn.[Name] as StatusTo
from history h
left outer join StatusType so
on so.StatusTypeID = Convert(int, h.OldValue)
AND 1 = case WHEN h.field = 'StatusTypeID'
THEN 1
else 0
end
left outer join StatusType sn
on sn.StatusTypeID = Convert(int, h.NewValue)
AND 1 = case WHEN h.field = 'StatusTypeID'
THEN 1
else 0
end
where primarykey = 17177
我会提供更多的代码示例,虽然我只是超级卡住。
我想我只是真的想要实际的加入,如果条件得到满足。这是可能的吗?
更新
预期的结果将是:
HistoryID Action Table PrimaryKey Field OldValue NewValue User DateTime StatusFrom StatusTo
--------------------------------------------------------------------------------------------------------------------------------------------------------------------
240233 Added QueueItem 17177 QueueItemID 17177 XXXXXXXXXXXXXXX 2016-09-16 08:38:58.060 NULL NULL
240237 Modified QueueItem 17177 StatusTypeID 1 2 XXXXXXXXXXXXXXX 2016-09-16 08:38:59.163 New Building
240240 Modified QueueItem 17177 StatusTypeID 2 3 XXXXXXXXXXXXXXX 2016-09-16 08:39:00.850 Building Ready
240241 Modified QueueItem 17177 PackageID 0 XXXXXXXXXXXXXXX 2016-09-16 08:39:00.850 NULL NULL
240249 Modified QueueItem 17177 StatusTypeID 3 4 XXXXXXXXXXXXXXX 2016-09-16 08:39:09.207 Ready Processing
240256 Modified QueueItem 17177 StatusTypeID 4 5 XXXXXXXXXXXXXXX 2016-09-16 08:39:10.163 Processing Done
240257 Modified QueueItem 17177 OutputDateTime 9/16/2016 8:39:10 XXXXXXXXXXXXXXX 2016-09-16 08:39:10.163 NULL NULL
每SWE答案,我想这太:
select h.*, so.[Name] as StatusFrom, sn.[Name] as StatusTo from history h
left outer JOIN StatusType so on so.StatusTypeID = Convert(int, h.NewValue) and h.field = 'statustypeid'
left outer JOIN StatusType sn on sn.StatusTypeID = Convert(int, h.NewValue) and h.field = 'statustypeid'
where primarykey = 17177
我得到了同样的问题 - 翻倒,当它击中newValue字段中的日期
Joinin g不支持动态表格。
你已经通过tsql-stored-procedure和一些cursour-logic并且手动建立你的结果集。或者,如果您只有可能的表格,请加入每个人并设置仅评估为真的条件,如果您想“加入”每个表格。
SELECT *
FROM a
LEFT JOIN b on a.id = b.id AND a.table = 'b' and a.field = 'id'
LEFT JOIN b on a.id = b.something AND a.table = 'b' and a.field = 'something'
LEFT JOIN c...
如果你只是想要一个子表的一个值,SELECT语句中的某种子查询可能更好也更易于阅读。
请参考您的'或'声明 - 这正是我在我的例子中试图做的。我添加了一个更新,显示我的新代码,我得到了相同的错误 – Darren
我和我最初的脚本非常接近。从这个答案Can I use CASE statement in a JOIN condition?
帮助让我想出这个,这给了我,我的预计业绩:
select h.*, so.[Name] as StatusFrom, sn.[Name] as statusto from history h
left outer join StatusType so
on
case
when h.field='StatusTypeID' and so.StatusTypeID = Convert(int, h.OldValue) then 1
else 0
end = 1
left outer join StatusType sn
on case
when h.field='StatusTypeID' and sn.StatusTypeID = Convert(int, h.NewValue) then 1
else 0
end = 1
where primarykey = 17177
如果解决您的问题,将其标记为已接受,所以其他现在已经解决。 –
谢谢,虽然我必须等待2天来标记我自己的答案。 – Darren
因为你正在做的左联接你的条件也不会留下任何记录,但只会让他们空。这是你想要的吗? – GuidoG
是的。我需要带回所有的历史,但有一个statusTypeID字段,然后我想加入状态表来获取文本名称。 – Darren
对不起,但我没看到预期的结果。 –