I'm working from a dump of some DISASTER legacy-data which effectively has zero data normalization. Just about ALL fields were manually keyed. There were no constraints. Data relationships are weak and unstable (based on text-matches of mutable data).
NOTE: I added id fields when I imported the data from the legacy CSV exports. You'll see ID's in my SQL, but they were not part of the original data. They are useless unless self-referencing.
GOAL
Our goal is to get a list of "active" customers (companies which we've had any quote or sale interaction with in the last few years) for import into our new/modern program.
I am prioritizing Bill-To address records. If an active-company has one, then that's the address row I want. (if a company has several, then we're left just picking one arbitrarily.) If an active-company does not have a "billing" address specified, then again, we're left to just arbitrarily grab one from what's there.
The result set should contain only one single row for a given company name.
NOTE: addresses.description could be ANYTHING; like "Bill To" or "NY" or "Main St" or "shipto" or "Bill/Ship" or ...
SOURCE
The source table is addresses which contains as many rows for a given company as addresses they've ever had since the dawn of time ... including drop-ship-to addresses.
There are no company_id's. The index is on company names. Most companies have multiple rows in the addresses table, and some have 10, 20, or more entries.
WHAT I'VE TRIED
My SQL skills are quite novice and super rusty. But I did ultimately achieve the desired results.
That being said, my solution is exceedingly kludgy! Since this data is going to have to be re-exported several times throughout the testing and migration phases, I'd really like to save a more streamlined (easily reusable) SQL.
Here's what I've come to so far:
CREATE TEMPORARY TABLE active_billto_companies
(id INT PRIMARY KEY, company varchar(72));
INSERT INTO active_billto_companies (id, company)
SELECT MIN(active.id), active.company
FROM(
SELECT
addr.id,
addr.company,
addr.description
FROM addresses addr
WHERE addr.company IN
(SELECT DISTINCT s.company FROM sales s WHERE s.`datetime` > '2019-01-01 00:00:00')
OR addr.company IN
(SELECT DISTINCT q.company FROM quotes q WHERE q.`datetime` > '2019-01-01 00:00:00')
OR addr.company IN
(SELECT DISTINCT i.company FROM invoices i WHERE i.`datetime` > '2019-01-01 00:00:00')
ORDER BY addr.id
) AS active
WHERE active.description LIKE '%bill%'
GROUP BY active.company;
CREATE TEMPORARY TABLE active_other_companies
(id INT PRIMARY KEY, company varchar(72));
INSERT INTO active_other_companies (id, company)
SELECT MIN(active.id), active.company
FROM(
SELECT
addr.id,
addr.company,
addr.description
FROM addresses addr
WHERE addr.company IN
(SELECT DISTINCT s.company FROM sales s WHERE s.`datetime` > '2019-01-01 00:00:00')
OR addr.company IN
(SELECT DISTINCT q.company FROM quotes q WHERE q.`datetime` > '2019-01-01 00:00:00')
OR addr.company IN
(SELECT DISTINCT i.company FROM invoices i WHERE i.`datetime` > '2019-01-01 00:00:00')
ORDER BY addr.id
) AS active
LEFT JOIN active_billto_companies b
ON active.company = b.company
WHERE active.description NOT LIKE '%bill%'
AND b.company IS NULL
GROUP BY active.company;
SELECT
a.id AS custno,
LEFT (a.company, 30) AS name,
a.line_1 AS addr1,
a.line_2 AS addr2,
a.line_3 AS addr3,
a.city,
a.state,
a.postal_code AS zipcd,
a.country AS countrycd,
a.description
FROM addresses a
RIGHT JOIN active_billto_companies b
ON a.id = b.id
UNION
SELECT
a.id AS custno,
LEFT (a.company, 30) AS name,
a.line_1 AS addr1,
a.line_2 AS addr2,
a.line_3 AS addr3,
a.city,
a.state,
a.postal_code AS zipcd,
a.country AS countrycd,
a.description
FROM addresses a
RIGHT JOIN active_other_companies o
ON a.id = o.id;
What are some things I could do to achieve this more succinctly?