如何在SQL EAV模型中过滤行?

时间:2012-01-12 16:31:28

标签: tsql entity-attribute-value

我有一个EAV SQL表,其中包含用于显示GUI的首选项列表。每个首选项由表中的一行表示。

我需要过滤这些行,使每个ColumnName/key列组合只有一行。如果ID_UserPersonal列不为NULL,则表示该行表示特定于用户的首选项,该首选项必须优先于默认值(当ID_UserPersonal为NULL时)。在这种情况下,必须过滤掉默认首选项,并且必须为ColumnName/key列组合保留用户定义的首选项。

Data Rows

2 个答案:

答案 0 :(得分:4)

您可以按ID_Personal对非NULL值后的NULL进行排名,然后选择排名值为1的行,如下所示:

;
WITH ranked AS (
  SELECT
    *,
    rnk = ROW_NUMBER() OVER (
      PARTITION BY ID_Role, Section, GridName, ColumnName, [key]
      ORDER BY CASE WHEN ID_Personal IS NULL THEN 1 ELSE 0 END, DateCreated
    )
  FROM AnEAVTable
)
SELECT *  /* or specify your columns explicitly, which is even better */
FROM ranked
WHERE rnk = 1

请注意我示例中PARTITION BY函数的ROW_NUMBER()子句,以防我在那里添加太多(或者可能太少)列。

参考文献:

答案 1 :(得分:2)

以下是您需要的完整示例:

create table #t(
f1 int null,
f2 int null,
f3 int null)

insert into #t values (1,2,3), (1,2,null), (1,3,null)



--select the not null
select t.* from #t t
where t.f3 is NOT NULL
UNION ALL
--union with the NULL not present in the previously select
select t.* from #t t
inner join (select convert(varchar,f1) + convert(varchar,f2) r
            from #t where f3 is not null) a
            on a.r <> convert(varchar,t.f1) + convert(varchar,t.f2)


drop table #t

您需要对字段进行连接,以便在您的桌子上单独识别一行。