父子连接SQL Server所需的SQL查询

时间:2016-12-08 09:51:08

标签: sql sql-server sql-server-2012

我有一个名为PostDkServicePoint的表,它存储了一堆经度/纬度位置。我今天这样称呼它 - 在那里它会找到指定点lat / lng参数的前30个最接近的位置。

SELECT TOP (30) 
    PostDkServicePoint.location.Lat AS latitude,    
    PostDkServicePoint.location.Long AS longitude,  
    PostDkServicePoint.servicePointId
FROM         
    PostDkServicePoint 
WHERE     
    (PostDkServicePoint.location.STDistance('POINT(40.587990    -73.662457)') IS NOT NULL)
ORDER BY 
    PostDkServicePoint.location.STDistance('POINT(40.587990 -73.662457)')

现在我有另一个名为PostDkOpeningHour的表:

 openingHoursId int
 servicePointId int
 day varchar
 from1 varchar
 to1 varchar

示例行:

 1233   5725    MONDAY      07:00   19:00
 1234   5725    TUESDAY     07:00   19:00
 1235   5725    WEDNESDAY   07:00   19:00
 1236   5725    THURSDAY    07:00   19:00

它总共包含24000行。我希望连接两个表,以便对于从上面的postdkservicepoint SQL查询返回的30行中的每一行,它还将显示PostDkOpeningHour表中的所有匹配子行(其中servicepointid是匹配两个表之间的关键字。)

使用这样的“加入”查询 - 那么纬度/经度数据是否只会为每行打开小时数据,如下所示:

5725 40.587990 -73.662457 MONDAY   07:00 19:00
5725 40.587121 -73.662412 TUESDAY  07:00 19:00

或者有没有办法以更多的父子关系风格返回它?

2 个答案:

答案 0 :(得分:1)

如果您只是按照以下行执行查询:

select a.Col1
      ,a.Col2
      ,b.Col1
      ,b.Col2
from TableA a
    inner join TableB b
        on(a.ID = b.FKID)

TableA中有5行,TableB中每个ID有5000个匹配行,然后是,输出将返回每个表中返回的每个表的匹配数据,导致每个TableA行重复5000次。

这就是SQL的工作原理,除非您返回多个数据集并在以后的应用程序中将它们连接在一起,否则无法以其他方式返回数据。通常,在执行此操作时的网络传输收益远远超过在应用程序中将数据重新连接在一起的处理时间,因为SQL在数据操作方面非常有效。

如果您的网络流量非常宝贵并且您绝对需要每一行值 - 即:您没有聚合返回的数据 - 那么您可能希望探索加入应用程序,尽管通常不建议这样做。

答案 1 :(得分:0)

我个人认为,您首先应该获取30条记录,然后使用PostDkServicePoint加入以获取相关的行。

WITH CTE (latitude, longitude, servicePointId) AS
(
SELECT TOP (30) 
    PostDkServicePoint.location.Lat AS latitude,    
    PostDkServicePoint.location.Long AS longitude,  
    PostDkServicePoint.servicePointId
FROM         
    PostDkServicePoint
WHERE     
    (PostDkServicePoint.location.STDistance('POINT(40.587990    -73.662457)') IS NOT NULL)
ORDER BY 
    PostDkServicePoint.location.STDistance('POINT(40.587990 -73.662457)')
)
SELECT
    cte.servicePointId,
    cte.latitude,
    cte.longitude,
    PostDkOpeningHour.day,
    PostDkOpeningHour.from1,
    PostDkOpeningHour.to1
FROM
    cte 
    INNER JOIN PostDkOpeningHour
        ON cte.servicePointId = PostDkOpeningHour.servicePointId;