3 回答

TA貢獻(xiàn)1839條經(jīng)驗(yàn) 獲得超15個(gè)贊
這個(gè)問(wèn)題提到了MySQL,實(shí)際上這個(gè)DBMS對(duì)這類問(wèn)題有一個(gè)特殊的功能:GROUP_CONCAT(expr)
。請(qǐng)參閱有關(guān)逐個(gè)功能的MySQL參考手冊(cè)。該功能已在MySQL 4.1版中添加。您將GROUP BY FileID
在查詢中使用。
我不確定你希望結(jié)果如何。如果你想為每個(gè)項(xiàng)目列出每個(gè)屬性(即使沒(méi)有設(shè)置),它將更難。但是,這是我對(duì)如何做的建議:
SELECT bt.FileID, Title, Author, GROUP_CONCAT( CONCAT_WS(':', at.AttributeName, at.AttributeType, avt.AttributeValue) ORDER BY at.AttributeName SEPARATOR ', ') FROM BaseTable bt JOIN AttributeValueTable avt ON avt.FileID=bt.FileID JOIN AttributeTable at ON avt.AttributeId=at.AttributeId GROUP BY bt.FileID;
這為您提供了相同順序的所有屬性,這可能很有用。輸出將如下所示:
'F001', 'Dox', 'vinay', 'CustomAttr1:varchar(40):Akash, CustomUseDate:Datetime:2009/03/02'
這樣,您只需要一個(gè)單獨(dú)的數(shù)據(jù)庫(kù)查詢,并且輸出很容易解析。如果要將屬性存儲(chǔ)為數(shù)據(jù)庫(kù)中的實(shí)際日期時(shí)間等,則需要使用動(dòng)態(tài)SQL,但我會(huì)保持清晰并將值存儲(chǔ)在varchars中。

TA貢獻(xiàn)1784條經(jīng)驗(yàn) 獲得超7個(gè)贊
這種查詢的一般形式是
SELECT file.*, attr1.value AS 'Attribute 1 Name', attr2.value AS 'Attribute 2 Name', ...FROM file LEFT JOIN attr AS attr1 ON(file.FileId=attr1.FileId and attr1.AttributeId=1) LEFT JOIN attr AS attr2 ON(file.FileId=attr2.FileId and attr2.AttributeId=2) ...
因此,您需要根據(jù)所需的屬性動(dòng)態(tài)構(gòu)建查詢。在php-ish偽代碼中
$cols="file";$joins="";$rows=$db->GetAll("select * from Attributes");foreach($rows as $idx=>$row){ $alias="attr{$idx}"; $cols.=", {$alias}.value as '".mysql_escape_string($row['AttributeName'])."'"; $joins.="LEFT JOIN attr as {$alias} on ". "(file.FileId={$alias}.FileId and ". "{$alias}.AttributeId={$row['AttributeId']}) ";} $pivotsql="select $cols from file $joins";

TA貢獻(xiàn)1891條經(jīng)驗(yàn) 獲得超3個(gè)贊
如果您正在尋找比group-concat結(jié)果更可用(和可加入)的東西,請(qǐng)嘗試以下解決方案。我已經(jīng)創(chuàng)建了一些與你的例子非常相似的表格,以使其有意義。
這適用于:
你想要一個(gè)純SQL解決方案(沒(méi)有代碼,沒(méi)有循環(huán))
您有一組可預(yù)測(cè)的屬性(例如,不是動(dòng)態(tài)的)
您可以在需要添加新屬性類型時(shí)更新查詢
您希望結(jié)果可以是JOINed,UNIONed或嵌套為子選擇
表A(文件)
FileID, Title, Author, CreatedOn
表B(屬性)
AttrID, AttrName, AttrType [not sure how you use type...]
表C(Files_Attributes)
FileID, AttrID, AttrValue
傳統(tǒng)查詢會(huì)拉出許多冗余行:
SELECT * FROM
Files F
LEFT JOIN Files_Attributes FA USING (FileID)
LEFT JOIN Attributes A USING (AttributeID);
AttrID FileID標(biāo)題作者CreatedOn AttrValue AttrName AttrType
50 1 TestFile Joe 2011-01-01 true ReadOnly bool
60 1 TestFile Joe 2011-01-01 xls FileFormat文本
70 1 TestFile Joe 2011-01-01 false私人布爾
80 1 TestFile Joe 2011-01-01 2011-10-03 LastModified日期
60 2 LongNovel Mary 2011-02-01 json FileFormat文本
80 2 LongNovel Mary 2011-02-01 2011-10-04 LastModified日期
70 2 LongNovel Mary 2011-02-01 true私人布爾
50 2 LongNovel Mary 2011-02-01 true ReadOnly bool
50 3 ShortStory Susan 2011-03-01 false ReadOnly bool
60 3 ShortStory Susan 2011-03-01 ascii FileFormat文本
70 3 ShortStory Susan 2011-03-01 false私人布爾
80 3 ShortStory Susan 2011-03-01 2011-10-01 LastModified日期
50 4 ProfitLoss Bill 2011-04-01 false ReadOnly bool
70 4 ProfitLoss Bill 2011-04-01 true Private bool
80 4 ProfitLoss Bill 2011-04-01 2011-10-02 LastModified date
60 4 ProfitLoss Bill 2011-04-01 text FileFormat text
50 5 MonthlyBudget George 2011-05-01 false ReadOnly bool
60 5 MonthlyBudget George 2011-05-01二進(jìn)制文件格式文本
70 5 MonthlyBudget George 2011-05-01 false私人布爾
80 5 MonthlyBudget George 2011-05-01 2011-10-20 LastModified日期
這個(gè)合并查詢(使用MAX的方法)可以合并行:
SELECT
F.*,
MAX( IF(A.AttrName = 'ReadOnly', FA.AttrValue, NULL) ) as 'ReadOnly',
MAX( IF(A.AttrName = 'FileFormat', FA.AttrValue, NULL) ) as 'FileFormat',
MAX( IF(A.AttrName = 'Private', FA.AttrValue, NULL) ) as 'Private',
MAX( IF(A.AttrName = 'LastModified', FA.AttrValue, NULL) ) as 'LastModified'
FROM
Files F
LEFT JOIN Files_Attributes FA USING (FileID)
LEFT JOIN Attributes A USING (AttributeID)
GROUP BY
F.FileID;
FileID標(biāo)題作者CreatedOn ReadOnly FileFormat Private LastModified
1 TestFile Joe 2011-01-01 true xls false 2011-10-03
2 LongNovel Mary 2011-02-01 true json true 2011-10-04
3 ShortStory Susan 2011-03-01 false ascii false 2011-10-01
4 ProfitLoss Bill 2011-04-01 false text true 2011-10-02
5 MonthlyBudget George 2011-05-01 false binary false 2011-10-20
添加回答
舉報(bào)