Sql 数据丢失时在两个表之间合并
朋友们,我有一个查询,它根据信用卡表中账单地址id的可用性从地址表中查找数据。问题在于,对于信用卡表中的许多记录,账单地址id的默认值为全零。我想做的是,当账单地址id全部为零时,对另一个默认地址表执行内部联接。我相信解决方法是使用Coalesce。下面是查询。任何帮助都将不胜感激Sql 数据丢失时在两个表之间合并,sql,sql-server-2008,Sql,Sql Server 2008,朋友们,我有一个查询,它根据信用卡表中账单地址id的可用性从地址表中查找数据。问题在于,对于信用卡表中的许多记录,账单地址id的默认值为全零。我想做的是,当账单地址id全部为零时,对另一个默认地址表执行内部联接。我相信解决方法是使用Coalesce。下面是查询。任何帮助都将不胜感激 select top 1 u_address_id, u_address_name, ads.u_first_name, ads.u_last_name,
select top 1
u_address_id,
u_address_name,
ads.u_first_name,
ads.u_last_name,
ads.u_address_line1,
ads.u_address_line2,
u_city,
u_region_code,
u_postal_code,
u_country_code,
ads.u_tel_number,
ads.u_tel_extension,
uo.u_email_address,
uo.u_user_id,
pm.PaymentMethodName,
ccea.CreditCard,
ccea.u_id
from CreditCard_Export_All ccea
inner join CreditCards cc on ccea.creditcard = cc.u_id
inner join Addresses ads on cc.u_billing_address = ads.u_address_id
inner join UserObject uo on ccea.UserId = uo.u_user_id
inner join PaymentMethod pm on cc.u_payment_group_id = pm.GroupId
where ccea.CreditCard = @ccId
and ccea.u_id between @_startUId and @_endUId
and uo.u_email_address is not null
and uo.u_email_address like @site+'_%'
这不是解决此类问题的最佳方案,但它确实使用了合并
select top 1
u_address_id,
u_address_name,
Coalesce(ads.u_first_name,ads2.u_first_name) as 'u_first_name',
Coalesce(ads.u_last_name,ads2.u_last_name) as 'u_last_name',
Coalesce(ads.u_address_line1,ads2.u_address_line1) as 'u_address_line1',
Coalesce(ads.u_address_line2,ads2.u_address_line2) as 'u_address_line2',
u_city, u_region_code,
u_postal_code,
u_country_code,
Coalesce(ads.u_tel_number,ads2.u_tel_number) as 'u_tel_number',
Coalesce(ads.u_tel_extension,ads2.u_tel_extension) as 'u_tel_extension',
uo.u_email_address,
uo.u_user_id,
pm.PaymentMethodName,
ccea.CreditCard,
ccea.u_id
from CreditCard_Export_All ccea
inner join CreditCards cc on ccea.creditcard = cc.u_id
left outer join Addresses ads on cc.u_billing_address = ads.u_address_id and ads.u_address_id != '000000000'
left outer join [ANOTHER DEFAULT ADDRESS TABLE] ads2 on cc.u_billing_address = ads2.u_address_id
inner join UserObject uo on ccea.UserId = uo.u_user_id
inner join PaymentMethod pm on cc.u_payment_group_id = pm.GroupId
where ccea.CreditCard = '" + ccId + "'" +
"and ccea.u_id between '" + _startUId + "' and '" + _endUId + "' " +
"and uo.u_email_address is not null " +
"and uo.u_email_address like '" + site + "_%'";
请注意:
- 要控制结果集的大小,您需要说
,这是一种代码气味,表明您在SQL中问的问题不对top 1
- 始终使用表名别名限定列引用。它使您的SQL更易于阅读。下一个必须理解它的人不必花时间试图找出哪个列来自哪个表
- 始终使用模式限定表名(
)。每次调用都必须解析非限定名称:非限定对象引用必须由dbo.some\u表
- 探测当前会话的默认架构的命名空间
- 如果未找到,则探测
命名空间dbo
)的对象,则这会减慢计划编译速度,禁止查询计划缓存,并可能导致创造性的、难以诊断的错误(foo.some_table
)。别问我怎么知道的dbo.some_table
- 不要像现在这样构造SQL。它
- 使您面临SQL注入攻击
- 防止缓存执行计划,因此需要在每次执行时重新编译/绑定计划。请注意,这也会去掉依赖对象上的编译锁,这可能会导致暂时的阻塞和并发问题
- 当数据的形式与您认为的不同时,您可能会遇到一些有趣的错误
select top 1
address_id = coalesce( ads.u_address_id , soat.address_id ) ,
address_name = coalesce( ads.u_address_name , soat.address_name ) ,
first_name = coalesce( ads.u_first_name , soat.first_name ) ,
last_name = coalesce( ads.u_last_name , soat.last_name ) ,
addr_line_1 = coalesce( ads.u_address_line1 , soat.addr_line_1 ) ,
addr_line_2 = coalesce( ads.u_address_line2 , soat.addr_line_2 ) ,
city = coalesce( ads.u_city , soat.city ) ,
region_code = coalesce( ads.u_region_code , soat.region_code ) ,
postal_code = coalesce( ads.u_postal_code , soat.postal_code ) ,
country_code = coalesce( ads.u_country_code , soat.country_code ) ,
telephone = coalesce( ads.u_tel_number , soat.telephone_number ) ,
telephone_ext = coalesce( ads.u_tel_extension , soat.telephone_ext ) ,
email_address = uo.u_email_address ,
user_id = uo.u_user_id ,
payment_method = pm.PaymentMethodName ,
credit_card = ccea.CreditCard ,
credit_card_id = ccea.u_id
from CreditCard_Export_All ccea
join CreditCards cc on cc.u_id = ccea.creditcard
join UserObject uo on uo.u_user_id = ccea.UserId
join PaymentMethod pm on pm.GroupId = cc.u_payment_group_id
left join Addresses ads on ads.u_address_id = cc.u_billing_address
and 0 != cc.u_billing_address
left join SomeOtherAddressTable soat on soat.address_id = cc.some_other_address_id
and 0 = cc.u_billing_address
where ccea.CreditCard = @ccId
and ccea.u_id between @_startUId and @_endUId
and uo.u_email_address is not null
and uo.u_email_address like @site+'_%'
您还可以考虑使用一个联合体,例如:
select address_id = ads.u_address_id ,
address_name = ads.u_address_name ,
first_name = ads.u_first_name ,
last_name = ads.u_last_name ,
addr_line_1 = ads.u_address_line1 ,
addr_line_2 = ads.u_address_line2 ,
city = ads.u_city ,
region_code = ads.u_region_code ,
postal_code = ads.u_postal_code ,
country_code = ads.u_country_code ,
telephone = ads.u_tel_number ,
telephone_ext = ads.u_tel_extension ,
email_address = uo.u_email_address ,
user_id = uo.u_user_id ,
payment_method = pm.PaymentMethodName ,
credit_card = ccea.CreditCard ,
credit_card_id = ccea.u_id
from CreditCard_Export_All ccea
join CreditCards cc on cc.u_id = ccea.creditcard
and cc.u_billing_address != 0
join UserObject uo on uo.u_user_id = ccea.UserId
join PaymentMethod pm on pm.GroupId = cc.u_payment_group_id
join Addresses ads on ads.u_address_id = cc.u_billing_address
where ccea.CreditCard = @ccId
and ccea.u_id between @_startUId and @_endUId
and uo.u_email_address is not null
and uo.u_email_address like @site+'_%'
UNION ALL
select address_id = soat.address_id ,
address_name = soat.address_name ,
first_name = soat.first_name ,
last_name = soat.last_name ,
addr_line_1 = soat.addr_line_1 ,
addr_line_2 = soat.addr_line_2 ,
city = soat.city ,
region_code = soat.region_code ,
postal_code = soat.postal_code ,
country_code = soat.country_code ,
telephone = soat.telephone_number ,
telephone_ext = soat.telephone_ext ,
email_address = uo.u_email_address ,
user_id = uo.u_user_id ,
payment_method = pm.PaymentMethodName ,
credit_card = ccea.CreditCard ,
credit_card_id = ccea.u_id
from CreditCard_Export_All ccea
join CreditCards cc on cc.u_id = ccea.creditcard
and cc.u_billing_address = 0
join UserObject uo on uo.u_user_id = ccea.UserId
join PaymentMethod pm on pm.GroupId = cc.u_payment_group_id
left join SomeOtherAddressTable soat on soat.address_id = cc.some_other_address_id
and 0 = cc.u_billing_address
where ccea.CreditCard = @ccId
and ccea.u_id between @_startUId and @_endUId
and uo.u_email_address is not null
and uo.u_email_address like @site+'_%'
也许您可以将问题简化为两到三个表,并提供示例数据和所需结果。这将使您更容易理解需要做什么。合并将不会帮助您,因为它只允许您消除空值,而不是默认值。如果要获取的值不是全零,可以使用CASE语句。
其他默认地址表
只有一行,其中u\u address\u id为全零?现在还不清楚。请发布一些数据。非常感谢您的反馈。