Question

Can anyone provide an SQL command that retrieves a customer's first and last name in one row? All my attempts at JOINs have resulted in multiple rows, with first name in one row and last name in the next.

Was it helpful?

Solution

Since attribute ids for first and last name vary between magento instlalations it would be wise to select attribute_id values for first name and last name from eav_attribute and write the query for retrieving first and last name in a single row like this:

SELECT entity_id, group_concat(VALUE SEPARATOR ' ') AS fullname 
FROM customer_address_entity_varchar AS val
INNER JOIN eav_attribute AS attr ON attr.attribute_id  = val.attribute_id
WHERE attr.attribute_code IN ( 'firstname',  'lastname' ) 
GROUP BY entity_id

OTHER TIPS

As @sonassi pointed out, you should really be using Magento models to interact with the data. I would add that regardless of where your code is, this still holds true. If you are writing something completely detached from Magento, then use the Web Services API, it's what it's there for.

You can get a collection of customers in Magento with the full name loaded on the individual records by calling addNameToSelect on the collection before loading it:

$collection = Mage::getResourceModel('customer/customer_collection')
    ->addNameToSelect()
    ->setPageSize(20)
    ->load()
;

With the above having been run, you can then call $collection->getSelect()->assemble() to get the query which Magento uses:

SELECT
    `e`.*,
    `at_prefix`.`value` AS `prefix`,
    `at_firstname`.`value` AS `firstname`,
    `at_middlename`.`value` AS `middlename`,
    `at_lastname`.`value` AS `lastname`,
    `at_suffix`.`value` AS `suffix`,
    CONCAT(IF(at_prefix.value IS NOT NULL AND at_prefix.value != '',
                CONCAT(LTRIM(RTRIM(at_prefix.value)), ' '),
            ''),
            LTRIM(RTRIM(at_firstname.value)), ' ',
            IF(at_middlename.value IS NOT NULL AND at_middlename.value != '',
                CONCAT(LTRIM(RTRIM(at_middlename.value)), ' '),
            ''),
            LTRIM(RTRIM(at_lastname.value)),
            IF(at_suffix.value IS NOT NULL AND at_suffix.value != '',
                CONCAT(' ', LTRIM(RTRIM(at_suffix.value))),
            '')
        ) AS `name`
FROM `customer_entity` AS `e`
    LEFT JOIN `customer_entity_varchar` AS `at_prefix` ON (`at_prefix`.`entity_id` = `e`.`entity_id`) AND (`at_prefix`.`attribute_id` = '4')
    LEFT JOIN `customer_entity_varchar` AS `at_firstname` ON (`at_firstname`.`entity_id` = `e`.`entity_id`) AND (`at_firstname`.`attribute_id` = '5')
    LEFT JOIN `customer_entity_varchar` AS `at_middlename` ON (`at_middlename`.`entity_id` = `e`.`entity_id`) AND (`at_middlename`.`attribute_id` = '6')
    LEFT JOIN `customer_entity_varchar` AS `at_lastname` ON (`at_lastname`.`entity_id` = `e`.`entity_id`) AND (`at_lastname`.`attribute_id` = '7')
    LEFT JOIN `customer_entity_varchar` AS `at_suffix` ON (`at_suffix`.`entity_id` = `e`.`entity_id`) AND (`at_suffix`.`attribute_id` = '8')
WHERE (`e`.`entity_type_id` = '1') LIMIT 20

As you can see, it is quite a beast, and I will re-iterate what I opened with. Unless you are using this for manually introspecting the data you should be using the Magento models to interact with the data. Attempts at avoiding them will almost guarantee that you break compatibility with varying versions, as stuff like this does change. The immediate issue though, you cannot rely on the values used for the attribute_id values being the same across the board. Most of the time they will be due to them being setup by install scripts, but I have seen cases where they are not what would be called "normal."

Here it is for name and email, attribute_id might not be 5 so change it if needed..

SELECT cev.value AS first_name,  ce.email AS email
FROM  `product_alert_stock` AS pas
LEFT JOIN  `customer_entity` AS ce ON pas.customer_id = ce.entity_id
LEFT JOIN  `customer_entity_varchar` AS cev ON pas.customer_id = cev.entity_id
WHERE cev.attribute_id =5
GROUP BY pas.alert_stock_id
SELECT entity_id, group_concat(VALUE SEPARATOR ' ') AS fullname 
FROM customer_entity_varchar AS val
INNER JOIN eav_attribute AS attr ON attr.attribute_id  = val.attribute_id
WHERE attr.attribute_code IN ( 'firstname',  'lastname' ) 
GROUP BY entity_id

You can also do it using a join like this:

SELECT first.entity_id,CONCAT(first.value,' ',last.value) FROM `customer_entity_varchar` first 
INNER JOIN customer_entity_varchar last ON first.entity_id = last.entity_id AND last.attribute_id = 7 
WHERE first.attribute_id = 5

In this case, attribute_id 5 is first name and attribute_id 7 is last name.

It seems the trick is to use the MYSQL function group_concat:

SELECT entity_id, group_concat(VALUE SEPARATOR ' ') AS fullname 
FROM `customer_address_entity_varchar` 
WHERE attribute_id IN (20,22) 
GROUP BY entity_id

Attribute IDs 20 and 22 represent the first and last name. I've also included the entity_id in order to join this data with other tables.

Edit: Since attribute IDs can vary, this isn't a general solution for all installs.

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top