0

这是一个复杂的问题,所以请多多包涵。我正在使用 3 个不同的表来制作 1 个结果集。它们如下:

customer_address_entity
    entity_id | entity_type_id | attribute_set_id | increment_id | parent_id | create_at | update_at | is_active

customer_entity_int
    value_id | entity_type_id | attribute_id | entity_id | value


customer_address_entity_varchar
    value_id | entity_type_id | attribute_id | entity_id | value

好的,现在你有了结构,这是我到目前为止构建的 SQL 调用:

SELECT CAE.entity_id, 
       CEI.value AS default_entity_id, 
       CAEV.attribute_id, 
       CAEV.value 
FROM   customer_address_entity AS CAE 
       JOIN customer_entity_int AS CEI 
         ON CEI.entity_id = CAE.parent_id 
            AND CEI.attribute_id = '13' 
       JOIN customer_address_entity_varchar AS CAEV 
         ON CAEV.entity_id = CAE.entity_id 
WHERE  CAE.parent_id = '2328' 
       AND CAE.is_active = 1 

这将输出以下示例数据集:

 ID     default  att   value

'1567', '1567', '19', 'John'
'1567', '1567', '21', 'Doe'
'1567', '1567', '23', 'Johns Company'
'1567', '1567', '25', 'Johns City'
'1567', '1567', '26', 'Johns Country'
'1567', '1567', '27', 'Johns State'
'1567', '1567', '29', 'Johns Zip Code'
'1567', '1567', '30', 'Johns Phone'
'1567', '1567', '31', 'Johns Fax'
'1568', '1567', '19', 'Jane'
'1568', '1567', '21', 'Doe'
'1568', '1567', '23', 'Janes Company'
'1568', '1567', '25', 'Janes City'
'1568', '1567', '26', 'Janes Country'
'1568', '1567', '27', 'Janes State'
'1568', '1567', '29', 'Janes Zip'
'1568', '1567', '30', 'Janes Phone'
'1568', '1567', '31', 'Janes Fax'
'1569', '1567', '19', 'Frank'
'1569', '1567', '21', 'Frunz'
'1569', '1567', '23', 'Franks Company'
'1569', '1567', '25', 'Franks City'
'1569', '1567', '26', 'Franks Country'
'1569', '1567', '27', 'Franks State'
'1569', '1567', '29', 'Franks Zip'
'1569', '1567', '30', 'Franks Phone'
'1569', '1567', '31', 'Franks Fax'

这段代码的最后一部分,我想根据数字UNIQUE entity_id(返回数据集中的第 1 列,即 0.1567、1568 和 1569)创建 X 个 ROWS(在本例中为 3)。预期的最终结果是:

'1567', '1567', 'John', 'Doe', 'Johns Company', 'Johns City', 'Johns State', 'Johns Zip Code', 'Johns Phone', 'Johns Fax'
'1568', '1567', 'Jane', 'Doe', 'Janes Company', ...  etc
'1569', '1567', 'Frank', 'Franz', 'Franks Comapny', ...   etc        

这甚至可能吗?

编辑感谢 Gordon Linoff——答案既优雅又简单!我自己进行了一些编辑,但会接受 Gordons 的回答并投票。这是我所做的编辑,效果很好!!

select entity_id,
   if(entity_id = default_entity_id, 'true', 'false') as default_entity,
   max(case when attr = '19' then `value` end) as `FirstName`,
   max(case when attr = '21' then `value` end) as `LastName`,
   max(case when attr = '23' then `value` end) as `CompanyName`,
   max(case when attr = '25' then `value` end) as `City`,
   max(case when attr = '27' then `value` end) as `State`,
   max(case when attr = '29' then `value` end) as `ZipCode`,
   max(case when attr = '30' then `value` end) as `PhoneNumber`,
   max(case when attr = '31' then `value` end) as `Fax`

from (SELECT CAE.entity_id, CEI.value AS default_entity_id, CAEV.attribute_id AS attr, CAEV.value 
  FROM   customer_address_entity CAE 
         JOIN customer_entity_int CEI 
           ON CEI.entity_id = CAE.parent_id 
              AND CEI.attribute_id = '13' 
         JOIN customer_address_entity_varchar CAEV 
           ON CAEV.entity_id = CAE.entity_id 
  WHERE  CAE.parent_id = '2328' 
         AND CAE.is_active = 1
 ) as t
group by entity_id
4

2 回答 2

1

您可以使用以下命令执行此操作group by

select entity_id,
       MAX(default) as default,
       max(case when att = '19' then value end) as FirstName,
       max(case when att = '21' then value end) as LastName,
       max(case when att = '23' then value end) as CompanyName,
       max(case when att = '25' then value end) as City,
       max(case when att = '27' then value end) as State,
       max(case when att = '29' then value end) as ZipCode,
       max(case when att = '30' then value end) as PhoneNumber,
       max(case when att = '31' then value end) as Fax
from (SELECT CAE.entity_id, CEI.value AS default_entity_id, CAEV.attribute_id, CAEV.value 
      FROM   customer_address_entity CAE 
             JOIN customer_entity_int CEI 
               ON CEI.entity_id = CAE.parent_id 
                  AND CEI.attribute_id = '13' 
             JOIN customer_address_entity_varchar CAEV 
               ON CAEV.entity_id = CAE.entity_id 
      WHERE  CAE.parent_id = '2328' 
             AND CAE.is_active = 1
     ) t
group by entity_id

此过程称为旋转,聚合是一种解决方案(某些数据库pivot为此提供了关键字)。这假设每个值在每个实体中仅出现一次。此外,如果某个值不存在,它将获得 NULL 值。

于 2013-01-07T21:21:03.043 回答
0

正如@Gordon 的回答所指出的,这就是所谓的 aPIVOT但 MySQL 没有该功能。在 MySQL 中,您可以将聚合函数与CASE语句一起使用。

如果它们都是已知的,您可以对这些值进行硬编码:

SELECT CAE.entity_id, 
    CEI.value AS default_entity_id,
    MAX(case when CAEV.attribute_id = 19 then CAEV.value else null end) FirstName,
    MAX(case when CAEV.attribute_id = 21 then CAEV.value else null end) LastName,
    MAX(case when CAEV.attribute_id = 23 then CAEV.value else null end) Company,
    MAX(case when CAEV.attribute_id = 25 then CAEV.value else null end) City,
    MAX(case when CAEV.attribute_id = 26 then CAEV.value else null end) Country,
    MAX(case when CAEV.attribute_id = 27 then CAEV.value else null end) State,
    MAX(case when CAEV.attribute_id = 29 then CAEV.value else null end) ZipCode,
    MAX(case when CAEV.attribute_id = 30 then CAEV.value else null end) Phone,
    MAX(case when CAEV.attribute_id = 31 then CAEV.value else null end) Fax
FROM   customer_address_entity AS CAE 
JOIN customer_entity_int AS CEI 
    ON CEI.entity_id = CAE.parent_id 
    AND CEI.attribute_id = '13' 
JOIN customer_address_entity_varchar AS CAEV 
    ON CAEV.entity_id = CAE.entity_id 
WHERE  CAE.parent_id = '2328' 
    AND CAE.is_active = 1 
GROUP BY CAE.entity_id, CEI.value;

或者你可以使用准备好的语句来实现动态sql。我假设您有一个将每个属性值与属性名称联系起来的表:

SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'max(case when CAEV.attribute_id = ''',
      attribute_id,
      ''' then CAEV.value else null end) AS `',
      attribute_id, '`'
    )
  ) INTO @sql
FROM customer_address_entity_varchar;

SET @sql = CONCAT('SELECT CAE.entity_id, 
                        CEI.value AS default_entity_id, ', @sql, '
                   FROM   customer_address_entity AS CAE 
                   JOIN customer_entity_int AS CEI 
                        ON CEI.entity_id = CAE.parent_id 
                        AND CEI.attribute_id = ''13' '
                    JOIN customer_address_entity_varchar AS CAEV 
                        ON CAEV.entity_id = CAE.entity_id 
                    WHERE  CAE.parent_id = ''2328''
                        AND CAE.is_active = 1 
                    GROUP BY CAE.entity_id, CEI.value');

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
于 2013-01-07T22:34:15.440 回答