Mysql

選擇具有來自其他表的值的動態列

  • May 31, 2017

我需要一些幫助來查詢。我想為儲存在另一個表中的數據庫查詢選擇額外的列。我將嘗試解釋我想要做什麼。我有兩個表,一個任務表和一個任務欄位表。當我查詢任務表時,有時我需要從 TaskField 表中選擇一些額外的欄位。

+-------------------+ +---------------------------+
|       Tasks       | |        TaskFields         |
+-------------------+ +---------------------------+
| TaskId PK int     | | TaskFieldId PK int        |
| TaskName string   | | TaskId FK -> Tasks.TaskId |
| TaskAuthor string | | TaskFieldName string      |
|                   | | TaskFieldValue string     |
+-------------------+ +---------------------------+

這些表中的行將如下所示。任務表如下所示

+--------+--------------+------------+
| TaskId |   TaskName   | TaskAuthor |
+--------+--------------+------------+
|      1 | Testing Task | Me         |
+--------+--------------+------------+

taskfields 表將包含這些行。

+-------------+--------+---------------+----------------+
| TaskFieldId | TaskId | TaskFieldName | TaskFieldValue |
+-------------+--------+---------------+----------------+
|           1 |      1 | Created_at    | 2017-31-05     |
|           2 |      1 | TaskLocation  | Berlin         |
+-------------+--------+---------------+----------------+

現在我想動態地將任務欄位中的數據選擇到表中的一行中,這樣我將得到以下輸出。

+--------+--------------+------------+------------+--------------+
| TaskId |   TaskName   | TaskAuthor | Created_at | TaskLocation |
+--------+--------------+------------+------------+--------------+
|      1 | Testing Task | Me         | 2017-31-05 | Berlin       |
+--------+--------------+------------+------------+--------------+

我不知道從哪裡開始這個查詢,我什至不知道在 mysql 中是否可行。我嘗試從以下查詢開始。

SELECT `Tasks`.`TaskId`, `Tasks`.`TaskName`, `Tasks`.`TaskAuthor` FROM `Tasks`
JOIN `TasksFields` ON `Tasks`.`TaskId` = `TasksFields`.`TaskId`

這將返回所有加入的行,但這不是我希望的結果,我需要動態地將列附加到結果中,但我不知道如何完成它。

上述數據庫設計背後的邏輯是什麼?

TaskfieldName 對於特定的 taskid 是動態的嗎?

在 SQL Server 中,

   create table #t (TaskId int,TaskName varchar(50)
,TaskAuthor varchar(50) )
insert into #t VALUES(1,'Testing Task','Me')


create table #t1 (TaskFieldId int,TaskId int
,TaskFieldName varchar(50), TaskFieldValue varchar(50))
insert into #t1 VALUES
(1 ,1,'Created_at'   ,'2017-31-05')
,(2 ,1,'TaskLocation' ,'Berlin') 
,(3 ,2,'TaskLocation' ,'Berlin') 
declare @TaskID varchar(10) =1
declare @Taskfield varchar(200)
declare @Sql varchar(max)=''
select top 1 
@Taskfield=stuff((select ','+'['+TaskFieldName +']'
from #t1 t11 where taskid=t1.taskid for xml path('') ),1,1,'')
from #t1 t1
where t1.TaskId=@TaskID
--select @Taskfield
set @Sql=
'SELECT *
FROM (
   SELECT t.*
       ,t1.TaskFieldName
       ,t1.TaskFieldValue
   FROM #t t
   INNER JOIN #t1 t1 ON t.TaskId = t1.TaskId
   where t.taskid='+@TaskID+'
   ) AS src
pivot(max(TaskFieldValue) FOR TaskFieldName IN (
           '+@Taskfield+'
           )) pv;'

--print @Sql
EXEC (@Sql)
drop table #t
drop table #t1

您的數據庫未標準化(2NF)欄位TaskFieldName| TaskFieldValue不依賴於taskFiledId,它們依賴於taskId,所以Create At並且taskLocation應該放在Task桌面上。當您需要報告時,只需從同一個表格中選擇所有內容。

引用自:https://dba.stackexchange.com/questions/174991