문제

데이터 테이블이 있으며 사람들이 해당 테이블에 메타 데이터를 추가 할 수 있습니다.

데이터가 저장된 테이블에 추가 열을 추가하는 것처럼 처리 할 수있는 인터페이스를 제공하지만 실제로 다른 테이블에 데이터를 저장하고 있습니다.

Data Table
   DataID
   Data

Meta Table
   DataID
   MetaName
   MetaData

따라서 데이터, 날짜 및 이름을 저장 한 테이블을 원한다면 데이터 테이블에 데이터가 있고 메타나 이름에 "날짜"라는 단어와 메타 데이터의 날짜와 다른 행 메타 이름에 "이름"이 있고 메타 데이터의 이름이있는 메타 테이블.

이제이 테이블에서 정보를 가져 와서 두 개의 추가 열 "데이터"와 "이름"이있는 단일 테이블에서 나오는 것처럼 보이는 쿼리가 필요하므로 고객에게는 사용자 정의 열이있는 단일 테이블이있는 것처럼 보입니다. :

MyTable
   Data
   Date
   Name

즉, 여기에서 어떻게 여기에서 갈 수 있습니까?

Data Table
   DataID        Data
   1             Testing!
   2             Hello, World!

Meta Table
   DataID        MetaName         MetaData
   1             Date             20081020
   1             Name             adavis
   2             Date             20081019
   2             Name             mdavis

여기로:

MyTable
   Data          Date             Name
   Testing!      20081020         adavis
   Hello, World! 20081019         mdavis

몇 년 전 PHP를 사용하여 MySQL 에서이 작업을 수행했을 때, 나는 두 가지 쿼리를했는데, 첫 번째는 추가 메타 데이터를 얻었고 두 번째는 모두 함께 합류했습니다. 최신 데이터베이스에이를 다루는 대체 방법이 있기를 바랍니다.

옵션 3의 관련 이 질문.

-아담

도움이 되었습니까?

해결책

MyTable에서 각 이름 값 쌍 행을 피벗하려고합니다 ...이 SQL을 시도하십시오.

DECLARE @Data   TABLE (
    DataID      INT IDENTITY(1,1)   PRIMARY KEY,
    Data        VARCHAR(MAX)
)

DECLARE @Meta   TABLE (
    DataID      INT ,
    MetaName    VARCHAR(MAX),
    MetaData    VARCHAR(MAX)
)

INSERT INTO @Data
SELECT 'Data'

INSERT INTO @Meta
SELECT 1, 'Date', CAST(GetDate() as VARCHAR(20))
UNION
SELECT 1, 'Name', 'Joe Test'

SELECT * FROM @Data

SELECT * FROM @Meta

SELECT 
    D.DataID,
    D.Data,
    MAX(CASE MetaName WHEN 'Date' THEN MetaData ELSE NULL END) as Date,
    MAX(CASE MetaName WHEN 'Name' THEN MetaData ELSE NULL END) as Name
FROM
    @Meta M
JOIN    @Data D     ON M.DataID = D.DataID  
GROUP BY
    D.DataID,
    D.Data

다른 팁

SELECT DataTable.Data AS Data, MetaTable.MetaData AS Date, MetaTable.MetaName AS Name
FROM DataTable, MetaTable
WHERE DataTable.DataID = MetaTable.DataID

사용자가 관심있는 행을 반환하기 위해 추가 조항 (및 data = 'some value')을 추가하고 싶을 것입니다.

Afaik, 당신은 동적으로 서버 측에서만 할 수 있습니다. SQL 저장된 절차.

효과적으로 동적으로 생성하려는 코드는 다음과 같습니다.

SELECT [Data Table].*
    ,[MyTable Date].MetaData
    ,[MyTable Name].MetaData
FROM [Data Table]
LEFT JOIN [MyTable] AS [MyTable Date]
    ON [MyTable Date].DataID = [Data Table].DataID
    AND [MyTable Date].MetaName = 'Date'
LEFT JOIN [MyTable] AS [MyTable Name]
    ON [MyTable Name].DataID = [Data Table].DataID
    AND [MyTable Name].MetaName = 'Name'

그리고 다음은 다음과 같습니다.

DECLARE @sql AS varchar(max)
DECLARE @select_list AS varchar(max)
DECLARE @join_list AS varchar(max)
DECLARE @CRLF AS varchar(2)
DECLARE @Tab AS varchar(1)

SET @CRLF = CHAR(13) + CHAR(10)
SET @Tab = CHAR(9)

SELECT @select_list = COALESCE(@select_list, '')
                        + @Tab + ',[MyTable_' + PIVOT_CODE + '].[MetaData]' + @CRLF
        ,@join_list = COALESCE(@join_list, '')
                        + 'LEFT JOIN [MyTable] AS [MyTable_' + PIVOT_CODE + ']' + @CRLF
                            + @Tab + 'ON [MyTable_' + PIVOT_CODE + '].DataID = [DataTable].DataID'  + @CRLF
                            + @Tab + 'AND [MyTable_' + PIVOT_CODE + '].MetaName = ''' + PIVOT_CODE + '''' + @CRLF
FROM (
    SELECT DISTINCT MetaName AS PIVOT_CODE
    FROM [MyTable]
) AS PIVOT_CODES

SET @sql = 'SELECT [DataTable].*' + @CRLF
            + @select_list
            + 'FROM [DataTable]' + @CRLF
            + @join_list
PRINT @sql
--EXEC (@sql)

당신은 그것을 사용하여 유사한 동적 기술을 사용할 수 있습니다 CASE 진술 예제 피벗을 수행 할 예정입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top