不同值的 SQL 分组聚合
我有一个数据库表,如下所示:
ForeignId: int
Key: varchar
Value: varchar
其中ForeignId和Key构成唯一主键
我可以轻松确定为给定文档集定义的总键集 但是
SELECT DISTINCT [Key] FROM [Table] WHERE [ForeignId] IN (...)
我想做的是进一步区分每个值每个属性的值(如果每个ForeignId 都相同)(如果值不同,则为NULL 或其他一些标记值)。
如果我做类似的事情:
ForeignId Key Value 1 1 A 1 2 B 1 3 C 2 1 A 2 2 Z 3 1 A 3 2 Z
我想要类似的输出:
Key Value 1 A -- All 3 are the same 2 NULL -- More than one distinct value (B, and Z) 3 NULL -- Defined for only one ForeignId
我能想到的最好的方法是
SELECT [Key], MAX([Value]), MIN([Value]) FROM [Table]
WHERE [ForeignId] IN (...)
GROUP BY [Key]
寻找返回的最大值和最小值不同的任何实例。 如果它们相同,我假设所有值都匹配,如果它们不同,我知道有多个不同的值。
这里缺少的是第三部分,如果任何单个项目根本没有定义,我需要将值标记为不同。 在上面的示例中,我当前的代码将返回键 3 的值 C,即使它没有为某些ForeignId 定义。
I have a database table that looks like:
ForeignId: int
Key: varchar
Value: varchar
Where ForeignId and Key constitute a unique primary key
I can easily determine the total set of keys defined for a given set of document with
SELECT DISTINCT [Key] FROM [Table] WHERE [ForeignId] IN (...)
What I would like to do however is to further distinguish the values of each values of each property in the case where it is the same for every ForeignId (and NULL or some other sentinal value in the case where there the values differ).
If I do something like:
ForeignId Key Value 1 1 A 1 2 B 1 3 C 2 1 A 2 2 Z 3 1 A 3 2 Z
I want output like:
Key Value 1 A -- All 3 are the same 2 NULL -- More than one distinct value (B, and Z) 3 NULL -- Defined for only one ForeignId
The best I have been able to come up with is
SELECT [Key], MAX([Value]), MIN([Value]) FROM [Table]
WHERE [ForeignId] IN (...)
GROUP BY [Key]
and looking for any instances where the max and min values returned differ. If they are the same I assume all of the values match, if they differ, I know there are more than one distinct values.
What's missing here is the 3rd part where I need to mark values as differing if any of the individual items doesn't have a definition at all. In my example above, my current code would return the value C for key 3 even though it is not defined for some of the ForeignIds.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
好的 - 所以如果我理解你的问题,你需要生成一个包含两列、键和值的列表。
该列表中的每个键都有一行,值列可以定义为:
如果没有为所有foreignid'定义它,则为NULL
如果为所有键定义但包含多个值,则为 NULL
如果为所有键定义了该值,并且该值始终相同?
所以,我认为我们想做这样的事情:
其中 x 是不同键的数量(您可能想将其放入子查询中)。
左连接将确保列出所有键,子查询仅在分组计数等于键数的情况下返回值。
我无法访问 sql(在家,新电脑)来测试我的语法,但我认为这个想法应该让您走上正确的道路。
如果我误解了你的问题,请告诉我
Ok - so if I understand your question you need to generate a list containing two columns, key and value.
The list will have a single row for each and every key, the value column can be defined as:
NULL if it is not defined for all ForeignID'
NULL if it is defined for all keys but contains multiple values
The value if it is defined for all keys, with that value being consistently the same?
So, I think we want to do something like this:
where x is the number of distinct keys (which you may want to throw into a subquery).
The left join will ensure you list all keys, the subquery will only return values for the case when the count of the grouping is equal to the number of keys.
I don't have access to sql (am at home, new PC) to test my syntax, but I think the idea should get you on the right path.
If I have misunderstood your question please let me know
我认为如果不使用某种代码(存储过程可以工作)就无法做到这一点,而且它真的很难看(而且很可能很慢)。
这是我最好的尝试。 实在是比较难看。 我不想在生产中使用它。 我质疑它的表现如何(时间方面)。 这是 MySQL 的说法,因为这是我所熟悉的
以下是各部分的解释:
如果表中存在另一行具有相同的键但不同的值,则返回一行。
IF 检查上面的查询是否返回一行。 如果确实如此(EXISTS 有效),则返回 null(因为有一行具有不同的值)。 如果它没有返回一行,那么它们都匹配,我们返回该值。
GROUP BY 确保每个键只执行一次。
ORDER BY 让它变得很漂亮。
I don't think you can do that without using some kind of code (a stored procedure would work) without it being REALLY ugly (and quite possibly slow).
Here is my best attempt. It's rather ugly. I wouldn't want to use this in production. I question how well it performs (time wise). This is MySQL speak, since that's what I'm familiar with
Here are the explanations of the parts:
Returns a row if there is another row in the table with the same key but a different value.
The IF checks if the query above returned a row. If it did (the EXISTS works) then return the null (since there is a row with a different value). If it didn't return a row, then they all match and we return the value.
The GROUP BY makes sure this is only executed once for each key.
The ORDER BY makes it pretty.
克里斯几乎已经拥有了。 添加另一个组,你就很出色了。
Chris pretty much had it. Add another group by and you're golden.