从类似于EAV的元数据驱动模式查询数据

时间:2016-09-19 20:33:05

标签: sql sql-server pivot entity-attribute-value database-metadata

我们有一个类似于EAV的数据模型。但是,我们的属性集有限。在我们的数据模型中,我们存储由个人完成的不同活动,并且基于活动类型,属性将变化。

我们希望获得个人的活动和相应的属性/值。我已经描述了ActivityActivityDetails表和预期的结果集。

您能否指导我如何从数据模型中获得预期的结果集?我们必须进行某种旋转。但是,不确定到达同样的地方。

在以下示例数据中, ClickURL 是一个活动。它有三个属性: URLAddress ClickCount ClickDate 。与三个属性对应的值为: www.companyurl.com 10 20140101

结果集应如下所示:

ActivityName | Description            | URLAddress          | ClickCount    | ClickDate
-------------------------------------------------------------------------------------------
ClickURL     | Click advertisementURL | www.companyurl.com  |10             |20140101

Our Data model & Expected Result

带数据的示例查询

    CREATE TABLE [dbo].[Activity](
    [ActivityTypeID] [int] IDENTITY(1,1) NOT NULL,
    [ActivityName] VARCHAR(50) NULL,
    [Description] VARCHAR(255) NULL,
    [StringField1] [varchar](50) NULL,
    [StringField2] [varchar](50) NULL,
    [StringField3] [varchar](50) NULL,  
    [NumField1] [varchar](50) NULL,
    [NumField2] [varchar](50) NULL, 
    [DTTMField1] [varchar](50) NULL,
    [DTTMField2] [varchar](50) NULL
) ON [PRIMARY]
GO

CREATE TABLE [dbo].[ActivityDetails](
    [ActivityDetailID] [int] IDENTITY(1,1) NOT NULL,
    [ActivityTypeID] VARCHAR(50) NULL,
    [StringField1] [varchar](50) NULL,
    [StringField2] [varchar](50) NULL,
    [StringField3] [varchar](50) NULL,  
    [NumField1] [] NULL,
    [NumField2] [int] NULL, 
    [DTTMField1] [datetime] NULL,
    [DTTMField2] [datetime] NULL
) ON [PRIMARY]
GO

INSERT INTO [dbo].[Activity](
[ActivityName]
,[Description] 
,[StringField1]
,[StringField2]
,[StringField3]
,[NumField1] 
,[NumField2] 
,[DTTMField1]
,[DTTMField2]
)
VALUES
('ClickURL','Click advertisementURL','URLAddress',NULL,NULL,'ClickCount',NULL,'clickDate',NULL)
GO

INSERT INTO [dbo].[ActivityDetails](
[ActivityTypeID]
,[StringField1]
,[StringField2]
,[StringField3]
,[NumField1] 
,[NumField2] 
,[DTTMField1]
,[DTTMField2]
)
VALUES
(1,'www.companyurl.com',NULL,NULL,10,NULL,'20140101',NULL)
GO

2 个答案:

答案 0 :(得分:1)

谢谢Shnugo。我也尝试过类似的东西。

$("input[type='checkbox']").change(function(){    
    var checked_count = $('input[type="checkbox"]:checked').length;
    if (checked_count>0) {
            $('.adi').addClass("redBackground"); 
    }else{
            $('.adi').removeClass("redBackground");  
    }
});

答案 1 :(得分:0)

我必须承认,我怀疑,你的方法是最好的方法......但是 - 至少 - 你可以试试这个:

注意:为了测试目的,我将删除创建的表格。小心真实的数据!

- 你的桌子

Does Not Equal

- 我声明一个变量并动态创建语句

 CREATE TABLE [dbo].[Activity](
    [ActivityTypeID] [int] IDENTITY(1,1) NOT NULL,
    [ActivityName] VARCHAR(50) NULL,
    [Description] VARCHAR(255) NULL,
    [StringField1] [varchar](50) NULL,
    [StringField2] [varchar](50) NULL,
    [StringField3] [varchar](50) NULL,  
    [NumField1] [varchar](50) NULL,
    [NumField2] [varchar](50) NULL, 
    [DTTMField1] [varchar](50) NULL,
    [DTTMField2] [varchar](50) NULL
) ON [PRIMARY]
GO

CREATE TABLE [dbo].[ActivityDetails](
    [ActivityDetailID] [int] IDENTITY(1,1) NOT NULL,
    [ActivityTypeID] VARCHAR(50) NULL,
    [StringField1] [varchar](50) NULL,
    [StringField2] [varchar](50) NULL,
    [StringField3] [varchar](50) NULL,  
    [NumField1] [int] NULL,
    [NumField2] [int] NULL, 
    [DTTMField1] [datetime] NULL,
    [DTTMField2] [datetime] NULL
) ON [PRIMARY]
GO

INSERT INTO [dbo].[Activity](
[ActivityName]
,[Description] 
,[StringField1]
,[StringField2]
,[StringField3]
,[NumField1] 
,[NumField2] 
,[DTTMField1]
,[DTTMField2]
)
VALUES
('ClickURL','Click advertisementURL','URLAddress',NULL,NULL,'ClickCount',NULL,'clickDate',NULL)
GO

INSERT INTO [dbo].[ActivityDetails](
[ActivityTypeID]
,[StringField1]
,[StringField2]
,[StringField3]
,[NumField1] 
,[NumField2] 
,[DTTMField1]
,[DTTMField2]
)
VALUES
(1,'www.companyurl.com',NULL,NULL,10,NULL,'20140101',NULL)
GO

- 此处执行语句

DECLARE @cmd VARCHAR(MAX)=
(
    SELECT
    'SELECT ''' + a.ActivityName + ''' AS ActivityName'
    +   ',''' + a.Description + ''' AS Description'
    +   ISNULL(',''' + ad.StringField1 +''' AS ' + QUOTENAME(a.StringField1),'')
    +   ISNULL(',''' + ad.StringField2 +''' AS ' + QUOTENAME(a.StringField2),'')
    +   ISNULL(',''' + ad.StringField3 +''' AS ' + QUOTENAME(a.StringField3),'')
    +   ISNULL(',' + CAST(ad.NumField1 AS VARCHAR(100)) +' AS ' + QUOTENAME(a.NumField1),'')
    +   ISNULL(',' + CAST(ad.NumField2 AS VARCHAR(100)) +' AS ' + QUOTENAME(a.NumField2),'')
    +   ISNULL(',CAST(''' + CONVERT(VARCHAR(100),ad.DTTMField1,126) +''' AS DATETIME) AS ' + QUOTENAME(a.DTTMField1),'')
    +   ISNULL(',CAST(''' + CONVERT(VARCHAR(100),ad.DTTMField2,126) +''' AS DATETIME) AS ' + QUOTENAME(a.DTTMField1),'')
    FROM Activity AS a
    INNER JOIN ActivityDetails AS ad ON a.ActivityTypeID=ad.ActivityTypeID
)

- 清理(关注真实数据!

EXEC(@cmd)
GO

创建的语句如下所示:

--DROP TABLE ActivityDetails;
--DROP TABLE Activity;

诀窍是,如果其中一个元素为SELECT 'ClickURL' AS ActivityName ,'Click advertisementURL' AS Description ,'www.companyurl.com' AS [URLAddress] ,10 AS [ClickCount] ,CAST('2014-01-01T00:00:00' AS DATETIME) AS [clickDate] ,则串联字符串全部为NULL。这就是为什么创建的语句将包含仅使用的列的原因。