SQL Select 语句根据许多属性查找唯一条目

发布于 2024-09-30 09:01:36 字数 1655 浏览 0 评论 0原文

为了将这项工作放在上下文中......我正在尝试过滤对象数据库并构建可以用语音 UI 语言表达的描述。为了最大限度地减少描述,我想根据格莱斯准则的思想找到描述对象的最短方法。

在代码中可以通过迭代记录并运行所有排列来实现这一点,但我一直认为应该有一种方法可以在 SQL 中做到这一点......到目前为止我还没有找到它。 (我正在使用 PostGRES。)

所以我有一个看起来像这样的表:

id     colour   position   height
(int)  (text)    (text)    (int)

0      "red"    "left"       9
1      "red"    "middle"     8
2      "blue"   "middle"     8
3      "blue"   "middle"     9
4      "red"    "left"       7

我希望根据属性(不包括 ID)找到两件事。

a) 根据最少属性数量,是否有任何记录是唯一的? =>例如,记录 0 根据颜色和高度是唯一的 =>例如记录 1 是中间唯一的红色项目 =>例如,记录 4 是唯一的,因为它是唯一高度为 7 的记录

b) 特定记录如何是唯一的?

=>例如,记录 0 是如何唯一的?因为它是唯一一个颜色为红色且高度为 9 的项目 =>例如,记录 4 是唯一的,因为它是唯一高度为 7 的项目。

当然,根据属性,没有对象是唯一的,这很好。

+++++++++++++++++++++++++

(a) 的答案

因此,我认为在 SQL 中执行此操作的唯一方法是从测试单个属性来查看所有记录中是否存在单个匹配项。如果没有,则添加属性 2 并再次测试。然后尝试属性 1 和 3。最后尝试属性 1,2 和 3。

类似这样的:-

单列测试:

select * from griceanmaxims 
where height=(Select height from griceanmaxims
group by height
having (count(height)=1))  
or 
relpos=
(Select relpos
from griceanmaxims
group by relpos
having (count(relpos)=1))
or
colour=
(Select colour
from griceanmaxims
group by colour
having (count(colour)=1))

双列测试:

(Select colour,relpos
from griceanmaxims
group by colour,relpos
having (count(colour)=1))

(Select colour,height
from griceanmaxims
group by colour,height
having (count(colour)=1))

etc

++++++++

我不确定是否有更好的方法或如何将双列测试的结果合并起来。

另外,如果有人对如何确定记录的区分因素(如问题 b)有任何建议,那就太好了。我的猜测是,(b) 需要对所有字段组合运行(a),但我不确定是否有更好的方法。

预先感谢您对此的任何帮助......

To put this work in context... I'm trying to filter a database of objects and build descriptions which can be verbalized for a speech UI. To minimise the descriptions I want to find the shortest way to describe an object, based on the idea of Grices Maxims.

It's possible in code by iterating through the records, and running through all permutations, but I keep thinking there ought to be a way to do this in SQL... so far I haven't found it. (I'm using PostGRES.)

So I have a table that looks something like this:

id     colour   position   height
(int)  (text)    (text)    (int)

0      "red"    "left"       9
1      "red"    "middle"     8
2      "blue"   "middle"     8
3      "blue"   "middle"     9
4      "red"    "left"       7

There are two things I wish to find based on the attributes (excluding the ID).

a) are any of the records unique, based on the minimum number of attributes?
=> e.g. record 0 is unique based on colour and height
=> e.g. record 1 is the only red item in the middle
=> e.g. record 4 is unique as its the only one which has a height of 7

b) how is a particular record unique?

=> e.g. how is record 0 unique? because it is the only item with a colour red, and height of 9
=> e.g. record 4 is unique because it is the only item with a height of 7

It may of course be that no objects are unique based on the attributes which is fine.

+++++++++++++++++++++++++

Answer for (a)

So the only way I can think to do this in SQL is to start off by testing a single attribute to see if there is a single match from all records. If not then add attribute 2 and test again. Then try attributes 1 and 3. Finally try attributes 1,2 and 3.

Something like this:-

single column test:

select * from griceanmaxims 
where height=(Select height from griceanmaxims
group by height
having (count(height)=1))  
or 
relpos=
(Select relpos
from griceanmaxims
group by relpos
having (count(relpos)=1))
or
colour=
(Select colour
from griceanmaxims
group by colour
having (count(colour)=1))

double column tests:

(Select colour,relpos
from griceanmaxims
group by colour,relpos
having (count(colour)=1))

(Select colour,height
from griceanmaxims
group by colour,height
having (count(colour)=1))

etc

++++++++

I'm not sure if there's a better way or how to join up the results from the double column tests.

Also if anyone has any suggestions on how to determine the distinguishing factors for a record (as in question b), that would be great. My guess is that (b) would require (a) to be run for all of the field combinations, but I'm not sure if there's a better way.

Thanks in advance for any help on this one....

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

美男兮 2024-10-07 09:01:36

我喜欢使用通用语言(例如 C#)来解决问题的想法:

1)迭代并查看是否有 1 个唯一的属性,例如 ID = 4,这是唯一的,因为高度为 7。从 ' 中取出 ID 4 do' 集合,并放入具有适当属性的 'done' 集合中

使用单元测试工具(例如 MSUNIT)来证明上述工作

2) 尝试并扩展到 n 个属性

单元测试

3) 看看是否有任何属性可以是唯一的 2 个属性。使用属性对将这些 ID 取出并放入完成单元

测试

4)扩展到 m 个属性

单元测试

3)可能使用递归进行重构

希望这会有所帮助。

I like the idea of attacking the problem using a General Purpose Language eg C#:

1) Iterate through and see if any have 1 attribute which is unique eg ID = 4, which is unique because height is 7. Take ID 4 out of the 'doing' collection, and put into 'done' collection with appropriate attribute

Use a unit testing tool eg MSUNIT to prove the above works

2) Try and extend to n attibutes

Unit Test

3) See if any can be unique with 2 attributes. Take those IDs out of doing and into done with the pairs of attributes

Unit Test

4) Extend to m attributes

Unit Test

3) Refactor maybe using recursion

Hope this helps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文