SQL:船舶/請求書アドレスのテーブルデザインとconcatの問題を選択します
-
09-10-2019 - |
質問
簡単なことです 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
フィールドは請求書アドレスで満たされています(たとえ同一であっても)残されていない null
.
2番目の質問: このようなデザインを保持してください(デザインが悪い場合でも)、各行の常に1つのアドレスを返す選択クエリ(可能であれば)を作成するにはどうすればよいですか。 ship_address
そうでないとき null
, 、そうでなければ invoice_address
, 、 何かのようなもの:
SELECT CONCAT_IF_SHIP_ADDRESS_NOT_NULL_OTHERWISE_USE_ONLY_SHIP_ADDRESS(invoice_address, ship_address) AS address FROM customers;
mysql dbのクエリ。
ありがとう、
解決
顧客と住所の間に1対多い関係があるので、アドレスを「タイプ」とともに別のテーブルに引き出して、それらを区別します。アドレス自体を個別の属性に分割することを検討します。オプションで、有効な都市/州/国の参照表を追加することもできます。
この構造のデータの照会に関しては、1つのアドレスが常に存在すると仮定し、希望の順序でaddressTypeレコードを作成します(つまり、請求書= 1、出荷= 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
他のヒント
スキーマは大丈夫だと思います。 MS SQL Serverを使用している場合は、このようなCoalesceを使用できます。
select coalesce(ship_address,invoice_address) as address
from customers
Coalesceは基本的にアイテムのリストを撮影し、リストにnullではない最初のアイテムを表示します。
これはそうします
SELECT customer_id, ISNULL(ship_address,invoice_address) AS address
FROM customers
請求書アドレスをコピーすると冗長性につながるため、船の住所はnullを残しておく必要があります。
クエリについては:
SELECT invoice_address
from table
where ship_address IS Null
UNION
SELECT ship_address
from table
where ship_address IS NOT NULL