如何在 SQL Server 视图中选择值(如果存在)或其他值(如果不在 SQL Server 视图中)
Posted
技术标签:
【中文标题】如何在 SQL Server 视图中选择值(如果存在)或其他值(如果不在 SQL Server 视图中)【英文标题】:How to select value if present or another if not in SQL Server view 【发布时间】:2013-04-17 20:08:41 【问题描述】:我需要在 SQL Server 数据库上创建一个视图,其中的一列可能来自两个来源中的任何一个,具体取决于存在的内容。具体来说,我们有一系列这样的表(简化):
表 1:
personid
typeid (one of the values from Table2)
surname
forename
etc...
表2:
typeid
typename
etc...
表3:
attributeid
attributename
etc...
Table4:
valueid
attributeid (one of the values from table3)
typeid (one of the values from table2)
personid (one of the values from table1)
attributevalue
etc...
现在,我需要(除其他外)从 table4 中选择适用于一个人的“属性值”的值。这可能看起来很简单(加入 personid 就完成了),但并不是那么简单。表 4 中可能没有 personid 的行,在这种情况下,我们需要默认为与类型关联的属性值。换句话说,从逻辑上讲,它是
if (there exists an attributevalue in t4 associated with personid)
use it
else
use attributevalue in t4 associated with typeid
我希望这很清楚。我一直在尝试确定是否可以通过一些微妙的连接或合并来完成,但一直无法弄清楚。
不幸的是,我对 SQL 的练习并不多,因此不胜感激!
最终我希望不能使用 t3 中的属性名来编写查询(因此在这里包括它),但现在的症结在于为每个属性获取正确的值。
提前致谢
编辑:根据以下建议进行更新(评论太长!):
感谢您的意见。我已经尝试过了,但它并没有返回我们所期望的。以下是数据示例:
表1:
PersonID 184
TypeID 49
...etc...
表4:
valueid 423 424 425 426 431 432
attributeid 4 5 6 7 6 5
typeid 49 49 49 49 49 49
personid NULL NULL NULL NULL 184 184
attributevalue yes track no no yes pay
etc...
所以我们期望的人 id 184 的属性值是
4: yes
5: pay
6: yes
7: no
(默认为与相关 typeid 关联的值,其中没有与非空 personid 关联的值)
为了清楚起见,稍微修改查询:
SELECT distinct t.id, p.AttributeID, isnull(p.attributevalue, p1.attributevalue) AS attributevalue
FROM table1 as T
LEFT JOIN table4 AS p ON p.personID = t.personID
left JOIN table4 p1 ON p1.typeID = t.typeID
where t.ID=184
我们回来了
id AttributeID attributevalue
184 5 pay
184 6 yes
所以它正确地撤回了存在特定于 personid 的覆盖的值,而不是默认值。
任何更多的想法将不胜感激!
再次感谢
第二次更新:
感谢这里的建议。最后,我选择了其他地方的一个,即使用一个函数并在我需要插入一个值的每个地方调用它。它只是为给定的人/类型/属性组合返回适当的值。像魅力一样工作。
【问题讨论】:
您的问题仍然令人困惑。为什么'5:track'不在预期的结果集中。它与againg=st type id (49)匹配。 @Sivakumar - 这是因为它是特定于类型的默认值,但有一个特定于人的值覆盖它(valueid 432 5:pay)。 我个人会重新设计您的数据库。 EAV 表很难正确查询并且运行缓慢。如果您事先知道应该使用 EAV 表具有哪些属性,那将是一个糟糕的选择。如果您不知道,请使用一个,但在 nosql 数据库中执行此操作,而不是针对此类查询进行更优化。 【参考方案1】:sql server is null 看起来你需要的是 null,下面是使用你的演示模式的演示。
SELECT isnull(p.atributeid,t.typeid) AS foo
FROM table1 as T
LEFT JOIN table4 AS p ON p.personid = t.personid
【讨论】:
谢谢,我早上会好好看看这个。第一反应:这是否使我们能够访问值(t4.value,因为为了清楚起见已编辑为 t4.attributevalue)?乍一看,它告诉我们是使用 personid 还是 typeid,这并不是我的想法。 (我可能还没有完全理解……) 左连接是魔法发生的地方。如果 table4 中没有与 table1 中的行匹配的行,则它将返回 null。既然是这种情况,那么 isnull 将像这样运行。如果 Table4.atributeid 为 null 则返回 table1.typeid【参考方案2】:我想这就是你要找的。看看这个。
SELECT isnull(p.attributevalue ,p1.attributevalue) AS foo
FROM table1 as T
LEFT JOIN table4 AS p ON p.personid = t.personid
LEFT JOIN table4 p1 ON p1.typeid = t.typeID
【讨论】:
非常感谢您的意见;我现在已经可以尝试这个了,但它并没有完全返回我想要的东西。我已经用详细信息和示例数据/结果编辑了我的原始查询。如果您有进一步的建议,我们将不胜感激!以上是关于如何在 SQL Server 视图中选择值(如果存在)或其他值(如果不在 SQL Server 视图中)的主要内容,如果未能解决你的问题,请参考以下文章
如何在 SQL Server 上创建一个数据库角色,其中该角色的用户只能从一个视图中选择,而不能从视图中使用的表中选择?