如果在SQL或Access查询中使用逻辑运算符

3
你好,各位 Stack Overflow 的用户。
我正在处理一个需要使用 Access 数据库的项目。以下是设置:
我有三个表:
Tab1 with employee names, ID#s, Manager names and Manager ID#s.
Tab2 with chat info, employee ID#s and employee names.
Tab3 with Manager ID#s, Manager names and team names.

我目前有一个查询,选择以下内容:

tab2.[employee name], tab2.[employee id], tab3.[chat info], tab1.[manager id], tab1.[manager id], tab3.[team name]
where
tab2.[employee id] = tab1.[employee id] and tab2.[manager id] = tab3.[manager id];

我想要实现的是:如果ID不匹配,我希望有一种方法将“未知”放入“团队”字段。有什么想法吗?
提前感谢!

您可能还希望删除MySQL标签;此处的语法看起来非常针对Access。 - El Yobo
为什么表的命名如此泛泛而谈?为什么非规范化现象如此猖獗?不一致的ID是否意味着数据不一致? - user359996
1
这些表的名称非常通用,因为我不知道是否可以由于公司政策而发布真实名称。 - Enyalius
也不确定什么是反规范化(我学SQL已经有几年了),以及哪些ID是不一致的? - Enyalius
表名: 公司政策方面的观点很好,但也许可以编写一些不同但有意义的表名,以帮助人们更轻松地理解模式。 去规范化: 粗略地说,这意味着同一字段在多个表中不必要地出现。例如,在Tab1中,您既有经理姓名又有经理ID,而(大概)只需要ID即可。这不仅会占用更多的空间,而且更新需要更改多个表以保持一致性,这可能会带来问题。 不一致性: 这是指“如果ID在某个地方不匹配”的情况。 - user359996
(不一致,继续):我不确定您所说的ID不匹配是什么意思,但这可能是个问题——您能澄清一下您的意图吗?例如,如果每个员工都应该分配到一个团队,但“ID不匹配”,那么与其费力地尝试弄清如何在团队字段中返回“未知”,您的时间可能更好地花在验证数据进入数据库(或更新)的时候。也就是说,您的数据库中的数据应该是有意义的(语义上一致),而不是依赖于查询代码中的技巧。 - user359996
5个回答

5
也许是这样的一些内容:
select tab2.[employee name], 
       tab2.[employee id], 
       tab3.[chat info], 
       tab1.[manager id], 
       Nz(tab3.[team name], 'Unknown') as [team name]
    from (tab2
        left join tab1
            on tab2.[employee id] = tab1.[employee id])
        left join tab3
            on tab2.[manager id] = tab3.[manager id]

显然Access也不支持COALESCE :-/ - El Yobo
@El Yobo:快速谷歌一下,看起来Nz是Access中COALESCE的等效函数。 - Joe Stefanelli
你也需要括号。 - Fionnuala
在连接表达式中添加更多的括号! - Ken Keenan
好的,事实证明我搞糊涂了我的变量。当我把这个弄清楚后,Joe的方法完美地工作了。谢谢你们所有人的帮助! - Enyalius
显示剩余2条评论

1
SELECT
   tab2.[employee name], tab2.[employee id], 
   tab3.[chat info], tab1.[manager id], 
   tab1.[manager id], 
   Nz(tab3.[team name],"Unknown")
FROM (tab2 
LEFT JOIN tab1 
ON tab2.[employee id] = tab1.[employee id]) 
LEFT JOIN tab3 
ON tab2.[manager id] = tab3.[manager id];

0

好的,我对于无法使用CASE语句有些慢反应,Joe使用Nz函数可能是你最好的选择,但如果有另一种Access特定的替代方案,也可以在这里介绍一下,以防它更适合你的情况:

select tab2.[employee name],
       tab2.[employee id],
       tab3.[chat info],
       tab1.[manager id],
       Iif(IsNull(tab3.[team name]), 'Unknown', tab3.[team name]) as [team name]
    from tab2
        left join tab1
            on tab2.[employee id] = tab1.[employee id]
        left join tab3
            on tab2.[manager id] = tab3.[manager id]

在这种情况下,Iif(条件,真实答案,假的答案)与Nz执行相同的操作,但如果您的条件不是IsNull,它可以更加灵活。

你还缺少括号,创建连接时Access对它们非常挑剔。 - Fionnuala
@Remou:你说得完全正确——我甚至没有处理括号的问题,只是复制了Joe的代码并将Nz调用更改为Iif调用。括号是……怎么说来着?“留给读者练习的题目。” - RolandTumble
再次提到Nz/Iif:我刚刚发现一个链接,建议使用Iif而不是Nz:http://allenbrowne.com/QueryPerfIssue.html#Nz - RolandTumble

0

看起来Access不支持SQL case语句,所以我之前的答案是错误的。我把它留在那里,供任何使用符合SQL标准的数据库遇到相同问题的人参考。

显然,您可以使用switch语句来实现相同的结果;这个例子展示了如何使用switch。希望这更有帮助。

否则,如果可能的话,请切换到真正的数据库 :)


有很多种 SQL 方言,但它们中没有一种是“真正的 SQL”。 - David-W-Fenton
我发现如果你依赖SWITCH()或CHOOSE(),那么你很可能存在设计错误,因为这些是在SQL语句中存储数据的方式。也就是说,如果你依赖这些函数,你应该将其中的数据放入查找表中,以便能够正确地利用SQL。 - David-W-Fenton
@David:真实的数据库,而不是真实的 SQL。有一个标准,大多数数据库都在某种程度上遵守。Access 明显是最不兼容的之一。 - El Yobo
Access还是Jet/ACE?任何人如果认为Jet/ACE不是一个“真正的数据库”,那么我完全可以安全地忽略他们的建议。 - David-W-Fenton

-1

我不确定Access,但在SQL中通常您会左连接您的表,并且您可以使用CASE语句添加您正在寻找的条件行为;Access可能不支持此功能。

这里示例显示得相当标准。

哇,Access查询真的看起来像那样吗?嗯...也许可以尝试这样做。

tab2.[employee name], tab2.[employee id], tab3.[chat info], tab1.[manager id], tab1.[manager id], case when tab3.[team name] is null then 'Unknown' else tab3.[team name] end as [team name]
where
tab2.[employee id] = tab1.[employee id] and tab2.[manager id] = tab3.[manager id];

1
如果你不确定Access,不要发表回答。 - David-W-Fenton
很容易被你的负评虎吓到;我不确定访问方面的问题,但是CASE语法适用于任何符合SQL标准的数据库,因此建议使用它。 - El Yobo
1
当我发布我的答案时,没有其他答案,因此我认为提供一个在大多数数据库中可能适用并且可能适用于Access的答案是有帮助的。除了原始发布者之外,其他搜索者也可能遇到这个问题,并且答案在大多数情况下仍然适用。当然,您可以随意浪费声望,进行尽可能多的负面投票。 - El Yobo
我同意这个原则,只是我不同意什么是有用的和什么是不好的。 - El Yobo
作为一个只在SO上阅读和发布Access主题的人,我可以告诉你,那些无法在Access中工作的T-SQL答案真的很令人厌烦。因此,我将继续对任何不适用的答案进行投票。 - David-W-Fenton
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接