不同值的 SQL 分组聚合

发布于 2024-07-13 18:25:40 字数 1011 浏览 9 评论 0原文

我有一个数据库表,如下所示:


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 技术交流群。

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

发布评论

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

评论(3

滥情哥ㄟ 2024-07-20 18:25:40

好的 - 所以如果我理解你的问题,你需要生成一个包含两列、键和值的列表。

该列表中的每个键都有一行,值列可以定义为:

如果没有为所有foreignid'定义它,则为NULL
如果为所有键定义但包含多个值,则为 NULL
如果为所有键定义了该值,并且该值始终相同?

所以,我认为我们想做这样的事情:

SELECT
    TABLE.KEY,
    data.VAL
FROM
    TABLE
LEFT JOIN
(
   SELECT KEY, VALUE FROM TABLE GROUP BY KEY, VALUE HAVING COUNT(*) = x
) data


其中 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:

SELECT
    TABLE.KEY,
    data.VAL
FROM
    TABLE
LEFT JOIN
(
   SELECT KEY, VALUE FROM TABLE GROUP BY KEY, VALUE HAVING COUNT(*) = x
) data


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

祁梦 2024-07-20 18:25:40

我认为如果不使用某种代码(存储过程可以工作)就无法做到这一点,而且它真的很难看(而且很可能很慢)。

这是我最好的尝试。 实在是比较难看。 我不想在生产中使用它。 我质疑它的表现如何(时间方面)。 这是 MySQL 的说法,因为这是我所熟悉的

SELECT key, IF(EXISTS (SELECT 1 FROM table t
                        WHERE t.key = key AND t.value != value),
               null, value)
FROM table
GROUP BY key
ORDER BY key

以下是各部分的解释:

SELECT 1 FROM table t WHERE t.key = key AND t.value != value

如果表中存在另一行具有相同的键但不同的值,则返回一行。

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

SELECT key, IF(EXISTS (SELECT 1 FROM table t
                        WHERE t.key = key AND t.value != value),
               null, value)
FROM table
GROUP BY key
ORDER BY key

Here are the explanations of the parts:

SELECT 1 FROM table t WHERE t.key = key AND t.value != value

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.

反差帅 2024-07-20 18:25:40

克里斯几乎已经拥有了。 添加另一个组,你就很出色了。

SELECT
    TABLE.KEY,
    data.VAL
FROM
    TABLE
LEFT JOIN
(
   SELECT KEY, VALUE FROM TABLE GROUP BY KEY, VALUE HAVING COUNT(*) = x
) data on Table.Key = data.Key
group by Table.Key, data.VAL

Chris pretty much had it. Add another group by and you're golden.

SELECT
    TABLE.KEY,
    data.VAL
FROM
    TABLE
LEFT JOIN
(
   SELECT KEY, VALUE FROM TABLE GROUP BY KEY, VALUE HAVING COUNT(*) = x
) data on Table.Key = data.Key
group by Table.Key, data.VAL
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文