多个sql连接不能产生所需的结果

时间:2013-08-27 20:06:36

标签: sql sql-server

我是sql的新手,并试图调整其他人的巨大存储过程来获取结果的子集。下面的代码可能是整个过程的10%。我添加了lp.posting_date,最后左连接和where子句。尝试获取发布日期在开始日期和结束日期之间的记录。我这样做了吗?显然不是因为结果不受变化的影响。更新:我改变了最后的加入。如果只有一个区域分配术语,则结果是正确的。如果有多个区域分配术语,则每个术语的结果都会重复。

SELECT Distinct
l.lease_id , 
l.property_id as property_id,
l.lease_number as LeaseNumber, 
l.name as LeaseName, 
lty.name as LeaseType,
lst.name as LeaseStatus,
l.possession_date as PossessionDate,
l.rent as RentCommencementDate,
l.store_open_date as StoreOpenDate,
msr.description as MeasureUnit,
l.comments as Comments ,
lat.start_date as atStartDate,
lat.end_date as atEndDate,
lat.rentable_area as Rentable,
lat.usable_area as Usable,
laat.start_date as aatStartDate,
laat.end_date as aatEndDate,
MK.Path as OrgPath,
CAST(laa.percentage as numeric(9,2)) as Percentage,
laa.rentable_area as aaRentable,
laa.usable_area as aaUsable,
laa.headcounts as Headcount,
laa.area_allocation_term_id,
lat.area_term_id, 
laa.area_allocation_id,
lp.posting_date
INTO #LEASES FROM la_tbl_lease l
INNER JOIN  #LEASEID on l.lease_id=#LEASEID.lease_id 
INNER JOIN la_tbl_lease_term lt on lt.lease_id=l.lease_id and lt.IsDeleted=0
LEFT JOIN la_tlu_lease_type lty on lty.lease_type_id=l.lease_type_id and lty.IsDeleted=0
LEFT JOIN la_tlu_lease_status lst on lst.status_id= l.status_id
LEFT JOIN la_tbl_area_group lag on lag.lease_id=l.lease_id
LEFT JOIN fnd_tlu_unit_measure msr on msr.unit_measure_key=lag.unit_measure_key
LEFT JOIN  la_tbl_area_term lat on lat.lease_id=l.lease_id and lat.isDeleted=0
LEFT JOIN  la_tbl_area_allocat_term laat on laat.area_term_id=lat.area_term_id and laat.isDeleted=0
LEFT JOIN dbo.la_tbl_area_allocation laa on laa.area_allocation_term_id=laat.area_allocation_term_id and  laa.isDeleted=0
LEFT JOIN vw_FND_TLU_Menu_Key MK on menu_type_id_key=2 and isActive=1  and id=laa.menu_id_key
INNER JOIN la_tbl_lease_projection lp on lp.lease_projection_id = #LEASEID.lease_projection_id 
where lp.posting_date <= laat.end_date and lp.posting_date >= laat.start_date

4 个答案:

答案 0 :(得分:1)

将其缩短并将其复制为ssms中的新查询或用于测试的任何内容。除非您希望保留左侧集,即使没有匹配的lp.lease_id,也请使用内连接。尝试像

这样的东西
if object_id('tempdb..#leases) is not null
    drop table #leases;
select distinct
 l.lease_id  
,l.property_id as property_id
,lp.posting_date

into #leases
from la_tbl_lease as l
inner join la_tbl_lease_projection as lp on lp.lease_id = l.lease_id

where lp.posting_date <= laat.end_date and lp.posting_date >= laat.start_date 

select * from #leases

drop table #leases

如果这得到了你想要的东西,那么你可以从那里开始工作并将其他左连接添加到查询中(如果你将它复制回你的proc中,则删除select *和'drop table')。如果没有,那么请查看您的布尔日期逻辑或为我们提供更多详细信息。如果您不熟悉sql及其过程扩展,请尝试使用对象资源管理器检查要查询的列的属性,并尝试从您正在使用的表中选择前1000 *以了解数据的外观在构建查询时。 -Mike

答案 1 :(得分:1)

正如可能已经暗示的那样,将WHERE子句与OUTER JOIN一起使用时应该小心。

OUTER JOIN的想法是可选地连接该表并提供对列的访问。 JOINS将生成您的集合,然后运行WHERE子句来限制您的集合。如果你在WHERE子句中使用一个条件,说明你的外连接表中的一个列必须存在/等于一个值,那么根据你的查询的性质,你不再进行LEFT JOIN,因为你只是在那里检索行加入发生。

答案 2 :(得分:0)

您也可以尝试BETWEEN运算符

Where lp.posting_date BETWEEN laat.start_date AND laat.end_date

推理:如果表中没有匹配的值,您可能会遇到问题。在左边连接的那个实例中,表将填充null。使用'BETWEEN'运算符可确保所有返回值都在该范围之间,并且不会出现空值。

答案 3 :(得分:0)

事实证明,问题更容易解决,而且它存储过程中的位置不同。我所要做的就是在其中一个游标上添加一行,按日期包含区域术语分配。