0

我有一个看起来像这样的数据库表:


ForeignId: int
Key: varchar
Value: varchar

其中 ForeignId 和 Key 构成唯一主键

我可以很容易地确定为给定文档集定义的总键集


SELECT DISTINCT [Key] FROM [Table] WHERE [ForeignId] IN (...)

但是,我想做的是进一步区分每个属性的每个值的值,如果每个 ForeignId 都相同(如果值不同,则为 NULL 或其他一些标记值)。

如果我这样做:

ForeignId 键值
1 1 安
1 2 乙
1 3℃
2 1 安
2 2 Z
3 1 安
3 2 Z

我想要像这样的输出:

核心价值
1 A -- 所有 3 个都相同
2 NULL -- 多个不同的值(B 和 Z)
3 NULL -- 只为一个 ForeignId 定义

我能想到的最好的是


SELECT [Key], MAX([Value]), MIN([Value]) FROM [Table]
WHERE [ForeignId] IN (...)
GROUP BY [Key]

并寻找返回的最大值和最小值不同的任何实例。如果它们相同,我假设所有值都匹配,如果它们不同,我知道有多个不同的值。

这里缺少的是第三部分,如果任何单个项目根本没有定义,我需要将值标记为不同。在上面的示例中,我当前的代码将返回键 3 的值 C,即使它没有为某些 ForeignId 定义。

4

3 回答 3

1

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

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

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

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

选择
    表键,
    数据.VAL
从
    桌子
左连接
(
   SELECT KEY, VALUE from TABLE GROUP BY KEY, VALUE HAVING COUNT(*) = x
) 数据


其中 x 是不同键的数量(您可能希望将其放入子查询中)。

左连接将确保您列出所有键,子查询仅在分组计数等于键数的情况下返回值。

我无法访问 sql(在家,新 PC)来测试我的语法,但我认为这个想法应该让你走上正确的道路。

如果我误解了您的问题,请告诉我

于 2009-02-12T22:54:39.017 回答
0

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

这是我最好的尝试。比较难看。我不想在生产中使用它。我质疑它的表现如何(时间方面)。这是 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 让它很漂亮。

于 2009-02-12T23:01:59.483 回答
0

克里斯几乎拥有它。添加另一个组,你是金子。

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
于 2009-02-12T23:07:14.573 回答