-1

最好用一个例子来解释。我的试验和结果如下所示。

有两个表(实际上我有多个表)

表:产品

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 个表并组合列值,如上所示。我就是无法理解这一点。帮助将不胜感激。

4

4 回答 4

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
于 2013-04-25T10:51:31.123 回答
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 |

看到这个 SQLFiddle

SQL Server 演示

于 2013-04-25T11:02:07.090 回答
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

于 2013-04-25T10:47:19.943 回答
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,'');

接下来,this can 变量可用于生成像静态 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);
于 2019-05-03T17:34:20.767 回答