最佳解释使用示例。我的试验和结果如下所示。
有两个表(实际上我有多个表)
ID name
-----------
1 apple
2 orange
3 pear
ID prod_ID attr_id value
----------------------------
1 1 101 20
2 1 102 red
3 1 103 sweet
4 2 101 30
5 2 102 orange
6 2 103 sour
6 3 101 40
7 3 102 green
8 3 103 sweet
name attr_id 101 AS 'price' attr_id 102 AS 'taste'
------------------------------------------------------
apple 20 sweet
orange 30 sour
pear 40 sweet
到目前为止,我已经管理过SQL,但最近我不得不调用3个表并组合列值,如上所示。我只是无法把头包裹起来。非常感谢帮助。
答案 0 :(得分:2)
由于您未在提问中提及任何RDBMS,因此下面的查询将适用于大多数RDBMS。
SELECT a.Name,
MAX(CASE WHEN b.attr_ID = 101 THEN b.value END) Price,
MAX(CASE WHEN b.attr_ID = 103 THEN b.value END) Taste
FROM Products a
INNER JOIN Attributes b
ON a.ID = b.prod_ID
GROUP BY a.Name
答案 1 :(得分:1)
您可以使用CASE
语句:(这将在MySQL中运行)
SELECT p.name
,GROUP_CONCAT(CASE WHEN attr_id = 101 THEN value else NULL END) AS price
,GROUP_CONCAT(CASE WHEN attr_id = 102 THEN value else NULL END) AS color
,GROUP_CONCAT(CASE WHEN attr_id = 103 THEN value else NULL END) AS taste
FROM Products p JOIN Attributes a
ON p.id = a.prod_id
GROUP BY p.name;
或者您也可以对join进行相同的操作:(这将在MySQL和SQL Server中都有效)
SELECT Name
,CASE WHEN a.attr_id = 101 THEN a.value ELSE NULL END AS price
,CASE WHEN b.attr_id = 102 THEN b.value else NULL END AS color
,CASE WHEN c.attr_id = 103 THEN c.value else NULL END AS taste
FROM Products p
LEFT JOIN Attributes a ON p.id = a.prod_id
LEFT JOIN Attributes b ON p.id = b.prod_id AND a.attr_id = 101 AND b.attr_id = 102
LEFT JOIN Attributes c ON p.id = c.prod_id AND a.attr_id = 101 AND c.attr_id = 103
WHERE a.attr_id IS NOT NULL and b.attr_id IS NOT NULL AND c.attr_id IS NOT NULL
我还为color
添加了一列。
输出
| NAME | PRICE | COLOR | TASTE |
-----------------------------------
| apple | 20 | red | sweet |
| orange | 30 | orange | sour |
| pear | 40 | green | sweet |
答案 2 :(得分:0)
您必须分别查询每个列...
SELECT
p.name,
(SELECT value FROM Attributes a WHERE attr_id=101 AND a.prod_ID=p.ID) AS price,
(SELECT value FROM Attributes a WHERE attr_id=102 AND a.prod_ID=p.ID) AS taste
FROM Products p
......或...... 如果您使用的是MSSQL 2008 R2,则可以使用PIVOT: http://msdn.microsoft.com/en-us/library/ms177410(v=sql.105).aspx
答案 3 :(得分:0)
使用PIVOT,可以轻松调整其他属性。
SELECT NAME, [101],[102],[103]
FROM (
SELECT P.NAME as NAME, A.ATTR_ID as ATTR_ID, A.VALUE as VALUE
FROM PRODUCTS as P, ATTRIBUTES as A
WHERE A.PROD_ID = P.ID
) SrcTable
PIVOT
(
MAX(VALUE)
for ATTR_ID in ([101],[102],[103])
) PivotTable;
或者可以生成动态语句来调整可变数量的属性(因为这是上面语句中唯一更改的内容)
列字符串可以通过类似以下方式获得:
DECLARE @columns AS NVARCHAR(MAX);
set @columns = STUFF((SELECT distinct ',' + QUOTENAME(ATTR_ID)
FROM ATTRIBUTES
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'),1,1,'');
接下来,该变量可以用于生成类似于静态PIVOT的字符串
DECALARE @stmt AS NVARCHAR(MAX);
set @stmt ='SELECT NAME, ' + @columns + '
FROM (
SELECT P.NAME as NAME, A.ATTR_ID as ATTR_ID, A.VALUE as VALUE
FROM PRODUCTS as P, ATTRIBUTES as A
WHERE A.PROD_ID = P.ID
) SourceTable
PIVOT (
MAX(VALUE)
for ATTR_ID in (' + @columns + ')
) PivotTable';
EXECUTE(@stmt);