SQL:船舶/发票地址和SELECT CONCAT问题的表格设计

时间:2010-12-13 19:19:10

标签: mysql sql database-design street-address invoice

我有一个简单的customers表这样设计(我只报告一些字段,有关此qeustions的字段):

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

包含null ship_address的行意味着我们必须使用客户的发票地址进行发货。


第一个问题:这是一个足够好的设计,或者所有null ship_address字段是否应填写发票地址(即使相同)而不是{ {1}}。

第二个问题:保留这样的设计(即使设计不好),如何创建一个SELECT查询(如果可能的话),每个行返回一个地址:{ {1}}当不是null,否则只有ship_address,类似于:

null

查询MySQL数据库。

谢谢,

4 个答案:

答案 0 :(得分:2)

我认为架构很好。如果您正在使用ms sql server,则可以使用coalesce,如下所示:

select coalesce(ship_address,invoice_address) as address 
from customers

coalesce基本上会获取一个项目列表,并显示列表中非空的第一个项目。

答案 1 :(得分:2)

您在客户和地址之间存在一对多关系,因此我将地址拉出到一个单独的表中,其中包含“类型”以区分它们。我会考虑将地址本身分成不同的属性。或者,您甚至可以为有效的城市/州/国家/地区添加参考表。

alt text

至于查询此结构中的数据,假设始终存在1个地址,并按所需顺序创建AddressType记录(即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

答案 2 :(得分:1)

这样做

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

答案 3 :(得分:1)

您应该将发货地址留空,因为复制发票地址会导致冗余。

至于查询:

SELECT invoice_address
from table 
where ship_address IS Null

UNION

SELECT ship_address 
from table 
where ship_address IS NOT NULL