朋友,我有查询根据信用卡表中的帐单邮寄地址ID的可用性从地址表中查找数据。问题是,对于信用卡表中的许多记录,账单地址id是全零的默认值。我想要做的是当账单地址id全为零时,对另一个默认地址表执行我的内连接。我相信解决方案是使用Coalesce。以下是查询。任何帮助将不胜感激。
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+'_%'
答案 0 :(得分:0)
不是这类问题的最佳解决方案,但它确实使用了合并。
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 + "_%'";
答案 1 :(得分:0)
为您提供的一些注意事项:
您需要说top 1
来控制结果集的大小,这是一种代码气味,表明您没有在SQL中提出正确的问题。
始终使用表名别名限定列引用。它使您的SQL更容易阅读。而下一个必须了解它的人不必花时间试图找出哪个列来自哪个表。
始终对表名称进行架构限定(dbo.some_table
)。必须在每次调用时解析不受限制的名称:必须通过
探索当前会话的默认架构
如果未找到,则探测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+'_%'
您可能还会考虑使用UNION,如下所示:
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+'_%'