Ste*_*ger 5 sql sql-server ssms query-designer
SSMS 有一个查询设计器,我通常会避免使用它,因为老实说,我无法真正使用它。
不幸的是,我的同事们也这样做。由于我还有 30 分钟的空闲时间,我终于想知道是我的问题还是 SSMS 的问题。
例如:假设我们有一个表buildings、一个表floor、一个表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.
Run Code Online (Sandbox Code Playgroud)
现在,当我尝试在查询设计器中执行相同操作时,它以某种方式从映射表开始,然后左连接房间,左连接楼层,然后左连接建筑物。
这从根本上是有缺陷的,因为如果映射表中没有房间的条目,它不会返回所有房间(这是假设每个房间都必须在一个楼层中,并且每个楼层都必须在建筑物中,但不是每个房间)必然有一个与其自身相关的使用类型[在一段时间内])...
现在,如果我开始修改连接,我会得到这个查询
SELECT
FROM usage_type mapping
RIGHT OUTER JOIN Floors
LEFT OUTER JOIN Rooms
RIGHT OUTER JOIN Floors
Run Code Online (Sandbox Code Playgroud)
现在这个查询看起来是等价的,但这是一个例子,通常,我必须连接更多的表。所以我不是特别喜欢右连接和左连接的混合,因为它最终很难理解(特别是当几个 ON 语句在连接的地方没有遵循时),使得搜索错误几乎不可能(而且我不太相信查询设计器弄清楚我想要什么的能力)。
到目前为止,我还没有找到一种像我想要的那样“设计”查询的方法。唯一的方法似乎是创建初始查询,然后获取 SQL 文本,然后调整联接,然后使用 SQL 查询设计器重新打开它。
不用说,最终,这比一开始手动执行要花费更长的时间,并且当查询设计者修改 SQL 脚本时,如果不先手动重新格式化它,您将无法再读取它......
在我看来,我的变体完全不可能用查询设计器来完成...我还发现奇怪的是,在查询设计器中,在连接符号的上下文菜单中,有时左侧的表格位于顶部,有时,右边的桌子。
然后,当我必须选择下一个而不是上一个时,它会执行右连接。我可以选择上面的一个,然后它进行左连接,但顺序错误......这正是我不想要的......
所以我想问:是否有一些“秘密”方法来指定查询应从哪个表开始,最好根本没有任何右连接?
我同意亚伦在评论中的评估,但我想无论如何我都会使用下表定义来看看。
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))
Run Code Online (Sandbox Code Playgroud)
打开“在编辑器中设计查询”窗口并通过按住 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
Run Code Online (Sandbox Code Playgroud)
但如果你按顺序选择,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
Run Code Online (Sandbox Code Playgroud)
从这个起点开始,不要单击“选择建筑物中的所有行”,因为它将查询转换为以下内容。
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
Run Code Online (Sandbox Code Playgroud)
相反,从右到左从中间的菱形开始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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1072 次 |
| 最近记录: |