1

我有一个customers这样设计的简单表格(我只报告一些字段,关于这个问题的那些):

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

ship_address 为空的行意味着我们也必须使用客户的发票地址进行运输。


第一个问题:这是一个足够好的设计,还是应该所有null ship_address字段都填写发票地址(即使相同)而不是留下null

第二个问题:保持这样的设计(即使它是糟糕的设计),我如何创建一个 SELECT 查询(如果可能的话),它总是为每一行返回一个地址:ship_addresswhen NOT null,否则只是 the invoice_address,类似于:

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

查询 MySQL 数据库。

谢谢,

4

4 回答 4

3

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

select coalesce(ship_address,invoice_address) as address 
from customers

coalesce 基本上采用项目列表,并显示列表中不为空的第一个项目。

于 2010-12-13T19:24:02.950 回答
2

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

替代文字

至于查询此结构中的数据,假设始终存在 1 个地址,并且您以所需的顺序(即 Invoice=1,Shipping=2)创建 AddressType 记录:

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
于 2010-12-13T19:44:53.253 回答
1

这会做

SELECT customer_id, ISNULL(ship_address,invoice_address) AS address
FROM customers
于 2010-12-13T19:24:52.167 回答
1

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

至于查询:

SELECT invoice_address
from table 
where ship_address IS Null

UNION

SELECT ship_address 
from table 
where ship_address IS NOT NULL
于 2010-12-13T19:29:26.940 回答