1

EAVに似たデータモデルがあります。ただし、属性のセットは限られています。私たちのデータモデルでは、個人が行ったさまざまなアクティビティを保存しており、アクティビティの種類に基づいて属性が異なります。

個人のアクティビティと対応する属性/値を取得したいと考えています。ActivityActivityDetailsテーブル、および予想される結果セットを示しました。

データモデルから期待される結果セットに到達する方法を教えてください。ある種のピボットを行う必要があります。しかし、同じに到着するかどうかはわかりません。

以下のサンプル データでは、ClickURLがアクティビティです。URLAddressClickCountClickDateの3 つの属性があります。3 つの属性に対応する値は、 www.companyurl.com1020140101 です。

結果セットは次のようになります。

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

私たちのデータモデルと期待される結果

データを使用したサンプル クエリ

    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
4

2 に答える 2

1

Shnugo に感謝します。以下でも同様のことを試しました。

DECLARE @ActivityTypeID int =1
DECLARE @ColList VARCHAR(MAX)
DECLARE @ActivityDetailsQuery VARCHAR(MAX)
SELECT @ColList = ''''+ ActivityName + ''' as ActivityName ,''' + Description + ''' as Description'
        +CASE when StringField1 is not null then ',StringField1 AS '+ stringField1 else '' end
       + CASE when StringField2 is not null then ',StringField2 AS '+ stringField2 else '' end
       + CASE when StringField3 is not null then ',StringField3 AS '+ StringField2 else '' end
       + CASE when NumField1 IS NOT NULL then ',NumField1 AS '+ NumField1 else '' end
       + CASE when NumField2 IS NOT NULL then ',NumField2 AS '+ NumField2 else '' end
       + CASE when DttmField1 IS NOT NULL then ',DttmField1 AS '+ DttmField1 else '' end
       + CASE when DttmField2 IS NOT NULL then ',DttmField2 AS '+ DttmField2 else '' end
from dbo.Activity
where ActivityTypeID = @ActivityTypeID  

SET @ActivityDetailsQuery = 'SELECT '+ @ColList + ' FROM dbo.ActivityDetails WHERE ActivityTypeID = ' + CAST(@ActivityTypeID as VARCHAR(10))
EXEC(@ActivityDetailsQuery)
于 2016-09-19T21:41:14.553 に答える
0

あなたのアプローチが最良のものであるとは思えないことを認めなければなりません...しかし、少なくとも-これを試すことができます:

注意:テスト目的で、作成したテーブルを最後にドロップします。実際のデータには注意してください!

-- あなたのテーブル

 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その要素の 1 つがNULL. これが、作成されたステートメントに使用される列のみが含まれる理由です。

于 2016-09-19T21:35:23.607 に答える