【问题标题】:Query designer in SSMS and order of join sequence?SSMS 中的查询设计器和连接顺序?
【发布时间】:2011-11-12 01:19:35
【问题描述】:

SSMS 有一个查询设计器,我通常会避免使用它,因为老实说,我无法真正使用它。

不幸的是,我的同事们这样做了。 由于我有 30 分钟的空闲时间,我终于想知道是我的问题还是 SSMS。

例如: 假设我们有一个表buildings、一个表floors、一个表rooms和一个映射表usage_types(room-usage_types)。

当我手动设计查询时,我会这样做:

select all buildings, 
left join all floors in those buildings
left join all rooms in those floors
left join the room-usage_types mapping table.

现在,当我尝试在查询设计器中执行相同操作时,它以某种方式从映射表开始,然后左连接房间,左连接楼层,然后左连接建筑物。

这从根本上是有缺陷的,因为如果一个房间的映射表中没有条目,它不会返回所有房间(这是假设每个房间都必须在一个楼层中,并且每个楼层都必须在一个建筑物中,但是不是每个房间都必然有一个与自身相关的使用类型[在一段时间内])...

现在,如果我开始修改连接,我会得到这个查询

SELECT  
FROM usage_type mapping 
RIGHT OUTER JOIN Floors 
LEFT OUTER JOIN Rooms 
RIGHT OUTER JOIN Floors

现在这个查询看起来是等价的,但这是一个例子,通常,我必须加入更多的表。所以我不是特别喜欢左右连接的混合,因为最后很难理解(尤其是当连接的地方没有遵循几个 ON 语句时),几乎不可能搜索错误(而且我不太相信查询设计器能够弄清楚我想要什么)。

到目前为止,我还没有找到一种方法来“设计”我想要的查询。 唯一的方法似乎是创建初始查询,然后获取 SQL 文本,然后调整连接,然后使用 SQL 查询设计器重新打开它。

最后不用说,这比一开始手动执行要花更长的时间,而且当查询设计器修改了 SQL 脚本时,如果不先手动重新格式化就无法再阅读它了。 .

在我看来,我的变体完全不可能用查询设计器来完成...... 我也觉得很奇怪的是,在查询设计器中,在连接符号的上下文菜单中,有时左侧的表格在顶部,有时右侧的表格。

然后,当我必须选择下一个而不是上一个时,它会进行右连接。我可以选择上面的那个,然后它进行左连接,但是顺序错误……这正是我不想要的……

所以我想问: 是否有一些“秘密”方式来指定查询应该从哪个表开始,最好根本没有任何正确的连接?

【问题讨论】:

  • 我的建议:不要使用查询设计器。抱歉大喊大叫,但这是一块有缺陷的垃圾,我不知道他们为什么拒绝从产品中切下它。你是对的,它比手写需要更长的时间。也只需查看提交的所有错误:google.com/…
  • Azure Data Studio 中至少没有包含查询设计器

标签: sql sql-server ssms query-designer


【解决方案1】:

我同意 Aaron 在 cmets 中的评估,但我想我还是会使用下表定义来看看。

CREATE TABLE buildings(
building_id int primary key)

CREATE TABLE floors(
floor_id int primary key,
building_id int references buildings)

CREATE TABLE rooms(
room_id int primary key,
floor_id int references floors)

CREATE TABLE room_usage_types(
room_id int references rooms,
usage_type_id int,
PRIMARY KEY  (room_id,usage_type_id))

打开“编辑器中的设计查询”窗口并在单击时按住 CTRL 键添加 4 个表,我发现选择它们的顺序会有所不同。

如果您按room_usage_types, rooms, buildings, Daily 的顺序选择,那么它开始时不是很有帮助

SELECT     
FROM         rooms INNER JOIN
                      room_usage_types ON rooms.room_id = room_usage_types.room_id CROSS JOIN
                      buildings CROSS JOIN
                      Daily

但如果你按顺序选择buildings, floors, rooms, room_usage_types,你最终会得到更有希望的

SELECT     
FROM         buildings INNER JOIN
                      floors ON buildings.building_id = floors.building_id INNER JOIN
                      rooms ON floors.floor_id = rooms.floor_id INNER JOIN
                      room_usage_types ON rooms.room_id = room_usage_types.room_id

从这个起点不要点击“从建筑物中选择所有行”,因为它会将查询转换为以下内容。

SELECT     
FROM         rooms INNER JOIN
                      floors ON rooms.floor_id = floors.floor_id INNER JOIN
                      room_usage_types ON rooms.room_id = room_usage_types.room_id RIGHT OUTER JOIN
                      buildings ON floors.building_id = buildings.building_id

而是从右到左从rooms, room_usage_types 之间的菱形开始,然后选择“从房间中选择所有行”等等。这似乎产生了预期的结果。

SELECT     
FROM         buildings LEFT OUTER JOIN
                      floors ON buildings.building_id = floors.building_id LEFT OUTER JOIN
                      rooms ON floors.floor_id = rooms.floor_id LEFT OUTER JOIN
                      room_usage_types ON rooms.room_id = room_usage_types.room_id   

【讨论】:

    猜你喜欢
    • 2011-04-27
    • 1970-01-01
    • 2012-06-27
    • 2011-07-02
    • 1970-01-01
    • 1970-01-01
    • 2013-05-26
    • 1970-01-01
    • 2015-11-25
    相关资源
    最近更新 更多