返回符合条件的多行中常见的列值

时间:2014-11-14 23:40:18

标签: sql sql-server

我有一个时间表表,每个时间表必须有一个或多个相关标准。父母和孩子看起来像这样:

SchedId ScheduleName
1       ScheduleA
2       ScheduleB
3       ScheduleC

标准表:

CriteriaName    CriteriaValue    SchedId
color           red              1
width           wide             1
depth           verydeep         1
color           blue             2
density         dense            3
height          short            3
porosity        spongy           3

现在,我有数据记录,我需要确定正确的时间表。因为我的查询仅限于特定的域,我碰巧确切地知道要测试的标准 - 换句话说,我知道我只对涉及3个标准的结果感兴趣,并且我知道它们是颜色,宽度和深度。

典型的数据记录集可能如下所示:

Color        Width       Depth
--------------------------------------
red          narrow      shallow
red          medium      deep
blue         wide        verydeep
red          wide        verydeep

我也碰巧知道只有1个且只有1个时间表具有已知标准的给定值集。那么更容易呢?

从概念上讲,我想要的查询如下:

SELECT color, width, depth, SchedId
  FROM [...]

并且正确的返回行将是:

red     wide     verydeep    1

我在这里使用了类似问题的答案,以至少两种不同的方式获得所需的SchedId - 一种是通过JOINing在条件表上为每组标准选择(criterianame = color,criteriavalue = red),加入SchedId,要求所有返回行的SchedId相同。这是有效的,因为我在查询中使用了文字值。

我无法在常规查询(无sproc)中找到我的数据行的值到JOIN子选择以供比较。

我过去用于这个确切问题的另一种技术是我试图避免的 - 它基本上计算了我在每个SchedId的标准上得到的匹配数。如果给定SchedId的匹配数等于该Id的条件数,则它是正确的Sched。我不太关心这种方法,虽然它运作正常。这种技术与MySQL一起使用,但我现在使用的是T-SQL。

最后,我以这种方式设计了标准表,允许无限数量的标准,以及无限数量的时间表的无限种标准。它已被证明具有惊人的挑战性。想法?

2 个答案:

答案 0 :(得分:3)

您可以使用条件聚合执行此操作:

select pt.Schedid, pt.schedname,
       max(case when ct.citerianame = 'color' then ct.criteriavalue end) as Color, 
       max(case when ct.citerianame = 'width' then ct.criteriavalue end) as Width, 
       max(case when ct.citerianame = 'depth' then ct.criteriavalue end) as Depth
from parenttbl pt inner join
     criteriatbl ct
     on pt.schedid = ct.schedid
group by pt.schedid, pt.schedname;

答案 1 :(得分:1)

SELECT 
    case when ct.citerianame = 'color' then ct.criteriavalue end Color, 
    ,case when ct.citerianame = 'width' then ct.criteriavalue end Witdh, 
    ,case when ct.citerianame = 'depth' then ct.criteriavalue end Depth
    ,pt.Schedid  


FROM 
    parenttbl pt 
    inner join criteriatbl ct on pt.schedid = ct.schedid
where 
    pt.schedid = 1