简体   繁体   English

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

[英]SQL: table design for ship/invoice address and SELECT CONCAT issue

I have a simple customers table designed this way (I report only some fields, the ones regarding this qeustions): 我有一个以此方式设计的简单customers表(我仅报告一些字段,与该要求有关的字段):

+ ----------- + --------------- + ---------------- +
+ 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. ship_address为空的行表示我们也必须使用客户的发票地址进行运输。


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 . 第一个问题:这是一个足够好的设计,还是所有null ship_address字段都应填上发票地址(即使相同),而不要保留为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查询(如果可能的话),该查询总是为每一行返回一个地址: ship_address null时的ship_address ,否则为invoice_address ,喜欢:

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

Query for MySQL DB. 查询MySQL数据库。

Thanks, 谢谢,

i think the schema is fine. 我认为架构很好。 if you're using ms sql server you can use coalesce, like this: 如果您使用的是ms sql服务器,则可以使用合并,如下所示:

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. 合并基本上会获取一个项目列表,并显示列表中不为null的第一项。

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. (可选)您甚至可以添加有效城市/州/国家/地区的参考表。

替代文字

As for querying the data in this structure, assuming 1 address always exists and you create AddressType records in the desired order (ie, Invoice=1, Shipping=2): 对于查询此结构中的数据,假设始终存在1个地址,然后以所需顺序(即,发票= 1,装运= 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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM