SQL: conception de table pour navire / adresse de facturation et numéro SELECT CONCAT
-
09-10-2019 - |
Question
J'ai une simple table de customers
conçu de cette façon (je signale que certains domaines, ceux concernant cette qeustions):
+ ----------- + --------------- + ---------------- +
+ customer_id + invoice_address + ship_address +
+ ----------- + --------------- + ---------------- +
+ 33 + 234, Walnut Ave + null +
+ ----------- + --------------- + ---------------- +
+ 47 + 66, Smart Ave + null +
+ ----------- + --------------- + ---------------- +
+ 47 + 4, Cool Ave + 45, Dark Street +
+ ----------- + --------------- + ---------------- +
Les lignes avec les moyens de null, nous devons utiliser l'adresse de facturation du client pour assurer un transport.
1ère question:. est-ce une conception assez de bien, ou si tous les champs de null
de ship_address
être rempli avec l'adresse de facturation (même si identique) et non null
gauche
2ème question: en gardant une telle conception (même dans le cas où il est une mauvaise conception), comment puis-je créer une requête SELECT (si possible) qui retourne toujours une adresse unique pour chaque ligne: le ship_address
quand ne pas null
, sinon juste le invoice_address
, quelque chose comme:
SELECT CONCAT_IF_SHIP_ADDRESS_NOT_NULL_OTHERWISE_USE_ONLY_SHIP_ADDRESS(invoice_address, ship_address) AS address FROM customers;
requête pour MySQL DB.
Merci,
La solution
Vous avez un 1-à-plusieurs entre les clients et les adresses, donc je tire sur l'adresse dans une table séparée avec un « type » pour les distinguer. Je considère casser l'adresse elle-même en attributs distincts. En option, vous pouvez même ajouter des tables de référence pour les villes valides / États / pays.
En ce qui concerne l'interrogation des données dans cette structure, en supposant 1 adresse existe toujours et vous créer des enregistrements de addresstype dans l'ordre souhaité (à savoir, facture = 1, Expédition = 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
Autres conseils
Je pense que le schéma est très bien. si vous utilisez ms le serveur, vous pouvez utiliser soudent, comme ceci:
select coalesce(ship_address,invoice_address) as address
from customers
coalesce prend essentiellement une liste d'éléments, et affiche le premier élément dans la liste qui est non nulle.
fera
SELECT customer_id, ISNULL(ship_address,invoice_address) AS address
FROM customers
Vous devriez laisser l'adresse du navire null comme la copie de l'adresse de facturation conduira à la redondance.
En ce qui concerne la requête:
SELECT invoice_address
from table
where ship_address IS Null
UNION
SELECT ship_address
from table
where ship_address IS NOT NULL