SQL Server中的EAV数据

时间:2017-04-27 17:23:52

标签: tsql sql-server-2005 pivot entity-attribute-value

我无法控制数据或数据库结构。我有这种EAV类型的数据,顾问可以说一种或多种语言,他可以前往欧洲的一个或多个国家,他确实有很多技能。

仅供参考我的数据中有10个不同的主要类别。

一些顾问讲10种语言,而其他顾问只讲一种语言。

数据看起来有点像这样

 ____________________________________________
| ConsultantID | Category | Value            |
 --------------------------------------------
| 1            | Language | English          |
| 1            | Language | French (fluent)  |
| 1            | Language | Spanish (working)|
| 1            | Country  | Ireland          |
| 1            | Country  | Italy            |
| 1            | Country  | Germany          |
| 1            | Country  | Belgium          |
| 456          | Language | French (working) |
| 456          | Country  | Belgium          |
| 847          | Language | English          |
| 847          | Country  | Belgium          |
 --------------------------------------------

我想列出所有愿意前往比利时并且说法语(工作流利)的顾问。根据我目前的例子#1和#456

我在下面写了一个查询,其中列出了与顾问类别匹配的所有值(请注意,这不是动态的,因为我的示例中的值的数量设置为5 max - 所以已经是一个糟糕的设计)。

SELECT  
    ID, category,
    MAX(CASE seq WHEN 1 THEN value  ELSE '' END ) +
    MAX(CASE seq WHEN 2 THEN ',' + value ELSE '' END )  +
    MAX(CASE seq WHEN 3 THEN ',' + value ELSE '' END )  +
    MAX(CASE seq WHEN 4 THEN ',' + value ELSE '' END ) +
    MAX(CASE seq WHEN 5 THEN ',' + value ELSE '' END )
FROM 
    (SELECT 
         p1.ID, p1.category, p1.value,
         (SELECT COUNT(*) 
          FROM tblWebPracticeInfo p2
          WHERE p2.category = p1.category
            AND p2.ID = P1.ID
            AND p2.value <= p1.value)
     FROM 
         tblWebPracticeInfo p1) D (ID, category, value, seq )
GROUP BY 
    ID, category 
ORDER BY
    ID;

然后我需要查询此表...

但即使没有where子句,也需要2秒才能执行

我还有其他更基本的东西(但同样没有效率)

select *
from tblWebMemberInfo m 
where 
    m.ID in (select p.id from  tblWebPracticeInfo p 
             where p.category = 'Language' and p.value like 'French%')
    and m.ID in (select p.id from  tblWebPracticeInfo p 
                 where p.category = 'Country' and p.value = 'Belgium')
order by m.ID

这基本上就是我的位置。你可以看到没有任何天才和任何真正有效的东西。

你能指出我正确的方向。

我正在使用SQL Server 2005 - v9.00.1

非常感谢您的时间和提前帮助

1 个答案:

答案 0 :(得分:0)

如果您只需要列出顾问,那么您可以使用exists()

select p.Id ...
from Person p /* Assuming you have a regular table for people,
                if not, use distinct or group by */
where exists (
    select 1
    from tblWebPracticeInfo l
    where l.Id = p.Id
      and l.Category = 'Language'
      and l.Value = 'French'
      )
  and exists (
    select 1
    from tblWebPracticeInfo c
    where c.Id = p.Id
      and c.Category = 'Country'
      and c.Value = 'Belgium'
      )

你也可以像这样使用聚合和having

select ConsultantID
from tblWebMemberInfo m 
where (p.category = 'Language' and p.value like 'French%')
   or (p.category = 'Country' and p.value = 'Belgium')
group by ConsultantID
having count(*) = 2     /* number of conditions to match is 2 */