另一个表中的 SQL SELECT 条件
我有 2 个相关的表:
messages
--------
mid subject
--- -----------------
1 Hello world
2 Bye world
3 The third message
4 Last one
properties
----------
pid mid name value
--- --- ---------------- -----------
1 1 read false
2 1 importance high
3 2 read false
4 2 importance low
5 3 read true
6 3 importance low
7 4 read false
8 4 importance high
我需要使用 properties
表上的条件从 messages
获取数据。 例如:如果我有一个标准,例如返回未读(读=假)高优先级(重要性=高)消息
,它应该返回
mid subject
--- -----------------
1 Hello world
4 Last one
如何使用SELECT子句(MySQL方言)获得这个?
I have 2 related tables:
messages
--------
mid subject
--- -----------------
1 Hello world
2 Bye world
3 The third message
4 Last one
properties
----------
pid mid name value
--- --- ---------------- -----------
1 1 read false
2 1 importance high
3 2 read false
4 2 importance low
5 3 read true
6 3 importance low
7 4 read false
8 4 importance high
And I need to get from messages
using the criteria on the properties
table.
Eg: if I have a criteria like return unread (read=false) high prio (importance=high) messages
it should return
mid subject
--- -----------------
1 Hello world
4 Last one
How could I get this with a SELECT clause (MySQL dialect)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
在 SQL 中,WHERE 子句中的任何表达式一次只能引用一行。因此,您需要某种方法将属性表中的多行获取到一行结果中。您可以通过自连接来执行此操作:
这显示了使用 EAV antipattern< /a>.与使用传统属性相比,其中一个属性属于一列:
顺便说一句,@Abe Miessler 和 @Thomas 的答案都比您想要的匹配更多的 mid。它们匹配所有中读=假或重要性=高的中值。您需要将这些属性与等效的 AND 组合起来。
In SQL, any expression in a WHERE clause can only reference one row at a time. So you need some way of getting multiple rows from your properties table onto one row of result. You do this with self-joins:
This shows how awkward it is to use the EAV antipattern. Compare with using conventional attributes, where one attribute belongs in one column:
By the way, both answers from @Abe Miessler and @Thomas match more mid's than you want. They match all mid's where read=false OR where importance=high. You need to combine these properties with the equivalent of AND.
我相信下面的查询会起作用。更新: @Gratzy 是对的,这个查询不起作用,看看我建议的结构更改。
不过,您的属性表的结构对我来说似乎有点偏离...
是否可以像这样构造表:
并使用此查询:
I believe the query below will work.UPDATE: @Gratzy is right, this query won't work, take a look at the structure changes I suggested.
The structure of your properties table seems a little off to me though...
Would it be possible to structure the table like this:
and use this query:
显然,您正在使用 EAV(实体属性值)模式。避免这种结构的众多原因之一是它使查询变得更加困难。但是,对于您给出的示例,您可以执行以下操作:
更简洁的解决方案是:
Clearly, you are using an EAV (Entity-Attribute-Value) schema. One of the many reasons for avoiding such a structure is that it makes queries more difficult. However, for the example you gave, you could do something like:
A more succinct solution would be:
我更喜欢将过滤条件放在 where 子句中,并将联接保留在两个表中并且是联接的实际条件的元素。
I prefer to put my filter criteria in the where clause and leave my join's to elements that are in both tables and are the actual criteria for the join.
另一种方法可能是(未经测试)使用派生表来保存所有消息必须满足的标准,然后使用双
NOT EXISTS
标准关系划分技术Another way might be (untested) to use a derived table to hold the criteria that all messages must meet then use the standard relational division technique of double
NOT EXISTS
如果您想保留现有的数据模型,请遵循 Bill Karwin 的第一个建议。使用此 select 子句运行它以了解它在做什么:
但是如果您这样做,则应该设置一些约束以避免存储和检索错误数据:
If you want to keep your existing data model, then go with Bill Karwin's first suggestion. Run it with this select clause to understand what it's doing:
But if you go this way, there are a few constraints you should put in place to avoid storing and retrieving bad data: