【问题标题】:how to do a SELECT with a composite key?如何使用复合键执行 SELECT?
【发布时间】:2018-09-14 04:58:49
【问题描述】:

我有一个带有复合键的表,我想用该键执行我的 SELECT 查询,有没有办法为复合键命名或执行查询而无需添加 AND

假设:

SELECT * FROM MyTable WHERE PRIMARY KEY = 12345

将主键作为复合键

【问题讨论】:

  • 除了使用AND之外没有其他合理的方法。我的意思是,你可以构建类似的东西,但AND 是要走的路。
  • key 与否,什么时候选择都无所谓。
  • 我想,您可以使用列的组合将计算列添加到表定义中,然后在您的SELECT 中查询。但不确定这是否真的有助于提高性能。
  • 您可以添加一个计算列来组合复合主键的各个列。您可能希望添加一个分隔符或类似的东西来涉及误报。您也可能会失去应用于表的索引的好处,总的来说,我认为这是一个非常糟糕的主意。
  • 您是否有理由想要这样做,或者这只是一个“出于好奇”的问题?

标签: sql sql-server sql-server-2008 select composite-primary-key


【解决方案1】:

不,没有 SELECT * FROM MyTable WHERE PRIMARY KEY = 'PrimaryKeyName' 的概念。换句话说,谓词(WHERE 子句)不允许这样做。您需要列出谓词中复合主键中包含的所有列。

一个潜在的解决方案是构建一个表来存储事实表的所有主键组合。您可以向该表添加一个标识字段,并使其成为表的外键约束。然后,您的谓词使用单个外键列。

【讨论】:

  • @waroxx 您可能需要考虑将您的问题标记为已回答。
【解决方案2】:

还有其他方法可以编写等效逻辑。例如:

where not (key1 <> val1 or key2 <> val2)

或:

select t.*
from (select t.* from t where key1 = val1) t
where t.key2 = val2

或许:

where t.key1 + '|' + t.key2 = val1 + '|' + val2

(假设| 从来不在这两个值中)。

或:

where (case when t.key1 <> val1 then 0
            when t.key2 <> val2 then 0
            else 1
       end) = 1

甚至:

where (case when t.key1 = val1 then 1 end) = (case when t.key2 = val2 then 1 end)

但是除了使用AND之外,没有合理的替代方法。

我应该注意,我创建的表几乎总是将标识列作为主键。我不喜欢复合主键,所以您可能想要使用标识列。

【讨论】:

  • 我相信您可能误读了 OP 的问题 - 他们想知道是否有命令将复合主键包含在谓词中,然后让优化器解决。
【解决方案3】:

也许Computed column 就是您要找的东西。

简而言之,您可以拥有另一列,它是系统根据您的定义生成的(这里是您的复合键的每一列的组合)。

然后,当您查询表时,您可以查询Computed Column

例如,对于 Charge:您有 ChargeCode 和 ChargeAmount,这两个是复合键。然后Computed Column 将具有值(ChargeCode + ChargeAmount)。

收费示例一:ChargeCode:A ChargeAmount:100(复合键) 如果您像往常一样编写查询: SELECT * FROM Table WHERE ChargeCode = 'A' AND ChargeAmount = '100'

如果使用Computed Column: ComputedColumn_Key: A100(注意这里的数据类型转换为字符串连接)

那么查询将是SELECT * FROM TABLE WHERE ComputedColumn_Key = 'A100'

【讨论】:

    【解决方案4】:

    感谢大家的头脑风暴,它帮助了我。

    我结束了创建一个视图,将复合键的列连接到一个新列中,并对那个视图执行 SELECT 查询。

    查看:

    SELECT (CONVERT(VARCHAR,PK1) + CONVERT(VARCHAR, PK2)) AS NEW_ID, nameColumn FROM MyTable
    

    查询

    SELECT nameColumn FROM viewName WHERE NEW_ID = 12345
    

    【讨论】:

    • 你为此放弃了索引搜索?
    • 我需要它是一个特定的枚举,如果我索引表它会给我一个新的
    • 复合主键是一个索引
    猜你喜欢
    • 2011-12-13
    • 1970-01-01
    • 2015-06-15
    • 2014-06-22
    • 2017-03-27
    • 2011-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多