如何查询设计不佳的SQL表?

时间:2016-01-20 16:41:10

标签: sql sql-server-2008 sql-server-2008-r2

我需要帮助提出一个查询,该查询允许我搜索非常设计不佳的SQL表。

该表包含某些项目的各种属性数据。问题是表格的布局如下:

serial#     attr        val
---------------------------
num         attr1       value
num         attr2       value
num         attr3       value

多行引用同一项,但每行包含不同的属性值。 在我开始之前,我没有创建此表。我意识到属性值应该是列标题等等。不幸的是,这是我必须要合作的。

我需要做的是编写一个查询,根据多个属性标准在此表中搜索给定的特定项目名称(另一个属性,存储在自己的表格行中)。

我的想法到目前为止,因为'序列#'对于给定的项来说,value是常量,就是编写一个" cascade"从一个属性值到下一个属性值,但我不确定如何做到这一点,或者即使这是最有效的方式。我已经尝试过" union"

select serial# from [table] where attr = 'attr1' and val = 'value'
union
select serial# from [table] where attr = 'attr3' and val = 'value'

...但所有这一切都是单独运行每个select语句,所以我最终得到序列号值,其中attr1可能与我的搜索值匹配,但attr3可能不匹配,反之亦然。

所以我需要退回'名称'属性值,其中attr1和attr3(以及我可能需要包括的任何其他参数)都匹配搜索条件。有没有办法做到这一点?我正在使用Sql Server 2008 R2,fyi。

2 个答案:

答案 0 :(得分:3)

您可以使用intersect来获取具有这两个属性的项目。

select serial# from [table] where attr = 'attr1' and val = 'value'
intersect
select serial# from [table] where attr = 'attr3' and val = 'value'

或者可以使用having子句来完成。

select serial# 
from [table] 
group by serial# 
having sum(case when attr = 'attr1' and val = 'value' then 1 else 0 end)
     + sum(case when attr = 'attr3' and val = 'value' then 1 else 0 end)
      > = 2

答案 1 :(得分:0)

另外几种可能的解决方案,具体取决于您可能搜索的项目数量:

SELECT [serial#]
FROM
    My_Table T1
WHERE
    attr = 'attr1' AND val = 'value1' AND
    EXISTS
    (
        SELECT *
        FROM My_Table T2
        WHERE
            T2.[serial#] = T1.[serial#] AND
            T2.attr = 'attr2' AND
            T2.value = 'value2'
    )

或者:

SELECT [serial#]
FROM
    My_Table T1
WHERE
    (T1.attr = 'attr1' AND T1.value = 'value1') OR
    (T1.attr = 'attr2' AND T1.value = 'value2')
GROUP BY
    [serial#]
HAVING
    COUNT(*) = 2