Reputation: 318
I'm not too experienced with SQL, so not sure if a similar question has already been answered (I'm sure there is, but I'm way out of my depth here). I used to be great at SQL many years back, but it's been so long that mind is foggy.
I'm migrating customers from one CMS to a different CMS.
Site A = Old CMS Site B = New CMS
In Site A's database, we have a table "p20kx_users" which contains the basic info - unique ID, username and email.
We then have a table "p20kx_virtuemart_userinfos" which contains in essence, two sets of data; shipping addresses and billing addresses.
In the "p20kx_virtuemart_userinfos" table, some users have just one row (the billing address), however most users have two rows (shipping AND billing addresses). There is a column in the "p20kx_virtuemart_userinfos" table named "address_type" that determines whether the row is Billing (BT) or Shipping (ST). There are also instances where users have neither, so that row shows up as NULL.
I've written a basic query that appears to retrieve all of the details I need, however I'm looking for a way so that the shipping and billing addresses appear on one row, in separate columns, so that I can export the results of the query directly to CSV and import to Site B.
Here's my query (I'm running this via PHPMyAdmin on a MariaDB 10.2 DB):
SELECT
p20kx_users.id,
p20kx_users.name,
p20kx_users.username,
p20kx_users.email,
p20kx_virtuemart_userinfos.address_type,
p20kx_virtuemart_userinfos.company,
p20kx_virtuemart_userinfos.title,
p20kx_virtuemart_userinfos.first_name,
p20kx_virtuemart_userinfos.last_name,
p20kx_virtuemart_userinfos.phone_1,
p20kx_virtuemart_userinfos.phone_2,
p20kx_virtuemart_userinfos.address_1,
p20kx_virtuemart_userinfos.address_2,
p20kx_virtuemart_userinfos.city,
p20kx_virtuemart_userinfos.zip
FROM p20kx_users
LEFT JOIN p20kx_virtuemart_userinfos
ON p20kx_users.id=p20kx_virtuemart_userinfos.virtuemart_user_id
I've had a good old google, and attempted the below which returns one result with mixed up details from other users.
SELECT
p20kx_users.id,
p20kx_users.name,
p20kx_users.username,
p20kx_users.email,
MAX(CASE WHEN p20kx_virtuemart_userinfos.address_type = 'BT' THEN p20kx_virtuemart_userinfos.company ELSE NULL END) Billing_Company,
MAX(CASE WHEN p20kx_virtuemart_userinfos.address_type = 'BT' THEN p20kx_virtuemart_userinfos.title ELSE NULL END) Billing_Title,
MAX(CASE WHEN p20kx_virtuemart_userinfos.address_type = 'BT' THEN p20kx_virtuemart_userinfos.first_name ELSE NULL END) Billing_Fname,
MAX(CASE WHEN p20kx_virtuemart_userinfos.address_type = 'BT' THEN p20kx_virtuemart_userinfos.last_name ELSE NULL END) Billing_LName,
MAX(CASE WHEN p20kx_virtuemart_userinfos.address_type = 'BT' THEN p20kx_virtuemart_userinfos.phone_1 ELSE NULL END) Billing_Phone1,
MAX(CASE WHEN p20kx_virtuemart_userinfos.address_type = 'BT' THEN p20kx_virtuemart_userinfos.phone_2 ELSE NULL END) Billing_Phone2,
MAX(CASE WHEN p20kx_virtuemart_userinfos.address_type = 'BT' THEN p20kx_virtuemart_userinfos.address_1 ELSE NULL END) Billing_Add1,
MAX(CASE WHEN p20kx_virtuemart_userinfos.address_type = 'BT' THEN p20kx_virtuemart_userinfos.address_2 ELSE NULL END) Billing_Add2,
MAX(CASE WHEN p20kx_virtuemart_userinfos.address_type = 'BT' THEN p20kx_virtuemart_userinfos.city ELSE NULL END) Billing_City,
MAX(CASE WHEN p20kx_virtuemart_userinfos.address_type = 'BT' THEN p20kx_virtuemart_userinfos.zip ELSE NULL END) Billing_Zip,
MAX(CASE WHEN p20kx_virtuemart_userinfos.address_type = 'ST' THEN p20kx_virtuemart_userinfos.company ELSE NULL END) Shipping_Company,
MAX(CASE WHEN p20kx_virtuemart_userinfos.address_type = 'ST' THEN p20kx_virtuemart_userinfos.title ELSE NULL END) Shipping_Title,
MAX(CASE WHEN p20kx_virtuemart_userinfos.address_type = 'ST' THEN p20kx_virtuemart_userinfos.first_name ELSE NULL END) Shipping_Fname,
MAX(CASE WHEN p20kx_virtuemart_userinfos.address_type = 'ST' THEN p20kx_virtuemart_userinfos.last_name ELSE NULL END) Shipping_LName,
MAX(CASE WHEN p20kx_virtuemart_userinfos.address_type = 'ST' THEN p20kx_virtuemart_userinfos.phone_1 ELSE NULL END) Shipping_Phone1,
MAX(CASE WHEN p20kx_virtuemart_userinfos.address_type = 'ST' THEN p20kx_virtuemart_userinfos.phone_2 ELSE NULL END) Shipping_Phone2,
MAX(CASE WHEN p20kx_virtuemart_userinfos.address_type = 'ST' THEN p20kx_virtuemart_userinfos.address_1 ELSE NULL END) Shipping_Add1,
MAX(CASE WHEN p20kx_virtuemart_userinfos.address_type = 'ST' THEN p20kx_virtuemart_userinfos.address_2 ELSE NULL END) Shipping_Add2,
MAX(CASE WHEN p20kx_virtuemart_userinfos.address_type = 'ST' THEN p20kx_virtuemart_userinfos.city ELSE NULL END) Shipping_City,
MAX(CASE WHEN p20kx_virtuemart_userinfos.address_type = 'ST' THEN p20kx_virtuemart_userinfos.zip ELSE NULL END) Shipping_Zip
FROM p20kx_users
LEFT JOIN p20kx_virtuemart_userinfos
ON p20kx_users.id=p20kx_virtuemart_userinfos.virtuemart_user_id
Can someone tell me where I am going wrong, and how I should address this - I've spent half a day looking at this. The longer I look, the more confused I get.
Upvotes: 1
Views: 595
Reputation: 1269803
Your query is close. You need a GROUP BY
:
SELECT u.id, u.name, u.username, u.email,
MAX(CASE WHEN ui.address_type = 'BT' THEN ui.company END) as Billing_Company,
. . .
FROM p20kx_users u LEFT JOIN
p20kx_virtuemart_userinfos ui
ON u.id = ui.virtuemart_user_id
GROUP BY u.id, u.name, u.username, u.email;
I also introduced table aliases, so the query is easier to write and to read. And I removed the ELSE NULL
, because that is redundant.
Upvotes: 1