Pergunta

I have a simple customers table designed this way (I report only some fields, the ones regarding this qeustions):

+ ----------- + --------------- + ---------------- +
+ customer_id + invoice_address + ship_address     +
+ ----------- + --------------- + ---------------- +
+ 33          + 234, Walnut Ave + null             +
+ ----------- + --------------- + ---------------- +
+ 47          + 66, Smart Ave   + null             +
+ ----------- + --------------- + ---------------- +
+ 47          + 4, Cool Ave     + 45, Dark Street  +
+ ----------- + --------------- + ---------------- +

Rows with null ship_address means we must use customer's invoice address also for shipping.


1st question: is this a good enough design, or should all the null ship_address fields be filled with the invoice address (even if identical) and not left null.

2nd question: keeping such a design (even in case it's bad design), how do I create a SELECT query (if it's possible) that returns always one single address for each row: the ship_address when NOT null, otherwise just the invoice_address, something like:

SELECT CONCAT_IF_SHIP_ADDRESS_NOT_NULL_OTHERWISE_USE_ONLY_SHIP_ADDRESS(invoice_address, ship_address) AS address FROM customers;

Query for MySQL DB.

Thanks,

Foi útil?

Solução

You have a 1-to-many relationship between customers and addresses, so I'd pull address out into a separate table with a "type" to distinguish between them. I'd consider breaking the address itself into separate attributes. Optionally, you could even add reference tables for valid cities/states/countries.

alt text

As for querying the data in this structure, assuming 1 address always exists and you create AddressType records in the desired order (i.e., Invoice=1, Shipping=2):

select c.CustomerID, a.AddressLine1, a.AddressLine2, a.AddressLine3,
       a.City, a.State, a.PostalCode, a.Country
    from Customer c
        inner join (select MIN(cax.AddressTypeID) as MinAddressTypeID
                        from CustomerAddressXref cax
                        where cax.CustomerID = c.CustomerID
                        group by cax.CustomerID) mincax
        inner join CustomerAddressXref cax
            on c.CustomerID = cax.CustomerID
                and mincax.MinAddressTypeID = cax.AddressTypeID
        inner join Address a
            on cax.AddressID = a.AddressID

Outras dicas

i think the schema is fine. if you're using ms sql server you can use coalesce, like this:

select coalesce(ship_address,invoice_address) as address 
from customers

coalesce basically takes a list of items, and displays the first item in the list that is not null.

This will do

SELECT customer_id, ISNULL(ship_address,invoice_address) AS address
FROM customers

You should leave the ship address null as copying invoice address will lead to redundancy.

As for the query:

SELECT invoice_address
from table 
where ship_address IS Null

UNION

SELECT ship_address 
from table 
where ship_address IS NOT NULL
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top