SQL Server 2008 复杂查询和表连接
Posted
技术标签:
【中文标题】SQL Server 2008 复杂查询和表连接【英文标题】:SQL Server 2008 Complex Query & Table Join 【发布时间】:2013-09-13 16:26:58 【问题描述】:这有点难以解释,但我会尽力而为。我有一个数据库,用于维护有关海运等的信息。我有以下几列可供使用。 (还有其他的,但它们对我的研究没有任何目的)我有 Message_ID、纬度、经度、MMSI(这代表个别船舶信号,因此它们是船舶独有的)Ship_type、Vessel_name。
问题来了
我只需要 Message_ID 的 1 和 3。 不幸的是,Message_ID 的 1 和 3 在它们各自的位置中将 Ship_type 和 Vessel_name 设为 Null。 Message_ID 5 标记了 Ship_type 和 Vessel_name。 我的研究区域在给定的经纬度范围内基本上我需要做的是将 Ship_type 和 Vessel_name 附加到 Message_ID 为 1 和 3 的行,方法是通过 Message_ID 5 共享的 MMSI 号加入。
到目前为止我的查询..
WHERE (latitude > 55 and latitude < 85 and longitude > 50 and longitude < 141) And (Message_ID = 1 or Message_ID = 3);
其他查询
WHERE Message_ID = 5;
如何将导致第二个查询的所有 Ship_type 和 Vessel_name 连接到第一个查询?
我觉得应该提到所有内容都在一个名为 dbo.DecodedCSVMEssages_Staging 的表中,该表有大约 1 亿个条目..:S
【问题讨论】:
【参考方案1】:我可能会这样做:
SELECT
t13.Message_ID,
t13.Latitude,
t13.Longitude,
t13.MMSI,
t5.Ship_type,
t5.Vessel_name
FROM yourTable As t13
OUTER APPLY ( SELECT TOP 1 *
FROM yourTable As t5
WHERE t5.Message_ID = 5
AND t5.MMSI = t13.MMSI
) As t5
WHERE t13.Message_ID IN(1,3)
AND t13.latitude > 55
and t13.latitude < 85
and t13.longitude > 50
and t13.longitude < 141
【讨论】:
t13.和 t5。代表什么? @dpalm 这是一种方便的语法,称为table alias。 所以基本上你给表名起了别名? 是的,它与SELECT yourTable.Message_ID, [...]
相同,但可以减少输入,更重要的是允许子查询明确引用外部查询中的表(在本例中为OUTER APPLY
部分)。
@dpalm 是的。当您不想弄乱列名的长表名时,它们很方便。但是,子查询(和 CTE)需要它们,并且当您在同一个 FROM
子句中多次引用同一个表/视图时,SQL 编译器可以判断您在列中引用的是哪个表+列参考文献。【参考方案2】:
我想你想要这样的东西:
select Message_ID, Latitude, Longitude, MMSI, x.Ship_type, x.Vessel_name
from table t
outer apply (select Ship_type, Vessel_name from table x where x.MMSI=t.MMSI and x.Message_ID=5) x
where t.Message_ID in (1,3) and (latitude > 55 and latitude < 85 and longitude > 50 and longitude < 141);
【讨论】:
x 代表什么? 是查询中OUTER APPLY
部分的别名。【参考方案3】:
with ship_cte(Ship_type,Vessel_name,MMSI)
as(select Distinct Ship_type,Vessel_name,MMSI from TableName WHERE Message_ID = 5)
select b.Ship_type,b.Vessel_name,a.other_columns
from tableName a join ship_cte b on a.MMSI=b.MMSI
WHERE (a.latitude > 55 and a.latitude < 85 and a.longitude > 50 and a.longitude < 141)
And (a.Message_ID = 1 or a.Message_ID = 3);
在查询的第一部分中,我得到了 message_id=5 的所有行的 ship_type 和vessel_name,然后我根据 MMSI 编号将查询的这一部分与主表连接起来。
【讨论】:
除非表在(MMSI, Message_ID)
上是唯一的,否则您将在 Join 上获得乘法。
感谢@RBarryYoung 指出,我已编辑代码以仅考虑不同。
好点,我认为 (Message_ID,MMSI) 在我的回答中也是独一无二的。 TOP(1)
无论如何都会解决它。
我对 SQL Server 比较陌生,我不确定 ship_cte 来自哪里?
@dpalm with
子句定义了 CTE(公用表表达式),它只是一种子查询。 ship_cte
是别名,因为表子查询必须有别名,以便您以后可以引用它们的列。以上是关于SQL Server 2008 复杂查询和表连接的主要内容,如果未能解决你的问题,请参考以下文章
当有更多行或查询变得更复杂时,分区视图会读取所有表? SQL Server 2008 错误?
如何在 SQL Server 2008 中查看打开的连接/正在运行的查询? [复制]