我有一个类似于:
的数据库表
ForeignId: int
Key: varchar
Value: varchar
其中ForeignId和Key构成唯一主键
我可以使用
轻松确定为给定文档集定义的密钥集
SELECT DISTINCT [Key] FROM [Table] WHERE [ForeignId] IN (...)
然而,我想要做的是进一步区分每个属性的每个值的值,在每个ForeignId相同的情况下(在值不同的情况下为NULL或其他一些sentinal值)
如果我这样做:
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]
并查找返回的max和min值不同的任何实例。如果它们是相同的,我假设所有的值都匹配,如果它们不同,我知道有不止一个不同的值。
这里缺少的是第3部分,如果任何单个项目根本没有定义,我需要将值标记为不同。在上面的例子中,我的当前代码将返回键3的值C,即使它没有为某些ForeignIds定义。
答案 0 :(得分:1)
好的 - 如果我理解你的问题,你需要生成一个包含两列,键和值的列表。
每个键的列表都有一行,value列可以定义为:
如果未为所有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(我在家,新PC)来测试我的语法,但我认为这个想法可以让你走上正确的道路。
如果我误解了您的问题,请告诉我
答案 1 :(得分: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让它漂亮。
答案 2 :(得分: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