Sql 您将如何编写此查询?

Sql 您将如何编写此查询?,sql,refactoring,rewrite,Sql,Refactoring,Rewrite,我希望将下面的查询重构为更具可读性和可修改性的查询。前半部分与第二部分相同,但从中查询的数据库除外(尽管表名相同) 这个查询是的定义,要求我重新编写,但我不知道如何编写 编辑:我们不能使用linq,我们希望得到不同的结果;我希望使查询的物理文件大小更小,而不是返回的结果 编辑:我正在查询的数据库是一个专有的ERP数据库。重构它不是一个选项。我看到的一个性能提示是使用UNION ALL而不是UNION,除非您有意想要不同的记录。一个简单的联合将消除需要时间的重复项UNION-ALL不会这样做 您可

我希望将下面的查询重构为更具可读性和可修改性的查询。前半部分与第二部分相同,但从中查询的数据库除外(尽管表名相同)

这个查询是的定义,要求我重新编写,但我不知道如何编写

编辑:我们不能使用linq,我们希望得到不同的结果;我希望使查询的物理文件大小更小,而不是返回的结果


编辑:我正在查询的数据库是一个专有的ERP数据库。重构它不是一个选项。

我看到的一个性能提示是使用
UNION ALL
而不是
UNION
,除非您有意想要不同的记录。一个简单的
联合
将消除需要时间的重复项
UNION-ALL
不会这样做

您可以使用动态SQL和循环重写它,但我认为结果会更糟。如果有足够多的重复代码来证明动态sql方法的合理性,那么我猜它是合理的

或者,您是否考虑过将逻辑从存储过程移到类似LINQ的东西中?对很多人来说,这不是一个选择,所以我只是问问


最后一点提示:不要急于修复没有损坏的东西,只是为了让它看起来更干净。如果清理将有助于维护、验证等,那么就去做吧。

我在bat上看到的一个性能提示是使用
UNION ALL
而不是
UNION
,除非您有意想要不同的记录。一个简单的
联合
将消除需要时间的重复项
UNION-ALL
不会这样做

您可以使用动态SQL和循环重写它,但我认为结果会更糟。如果有足够多的重复代码来证明动态sql方法的合理性,那么我猜它是合理的

或者,您是否考虑过将逻辑从存储过程移到类似LINQ的东西中?对很多人来说,这不是一个选择,所以我只是问问


最后一点提示:不要急于修复没有损坏的东西,只是为了让它看起来更干净。如果清理工作有助于维护、验证等工作,那就去做吧。

我要在这里冒险,说,根据你给我们的信息


这是最好的

我要站出来说,根据你给我们的信息


这是最好的了

有什么问题吗?太久了?太重复了

有时,您会遇到丑陋的SQL—对此您无能为力


我看不出任何方法来清理它,除非您想使用单独的视图,然后将它们合并在一起。

有什么问题吗?太久了?太重复了

有时,您会遇到丑陋的SQL—对此您无能为力


除非您想使用单独的视图,然后将它们合并在一起,否则我看不到任何方法来清理它。

我赞成视图,它几乎没有任何开销(好的,也许编译时的开销很小,但这应该就够了)。然后你的程序就变成了某种形式

SELECT * FROM database1.view1
UNION
SELECT * FROM database1.view2
UNION
SELECT * FROM database2.view1
UNION
SELECT * FROM database2.view2

我不确定我是否想进一步压缩它,尽管我希望大多数平台都能容忍它。

我投票支持视图,它带来的开销几乎为零(好吧,也许编译时成本很小,但应该就这些了)。然后你的程序就变成了某种形式

SELECT * FROM database1.view1
UNION
SELECT * FROM database1.view2
UNION
SELECT * FROM database2.view1
UNION
SELECT * FROM database2.view2

我不确定我是否想进一步压缩它,尽管我预计大多数平台都会容忍它。

关于动态SQL主题-这里是一个示例-不确定它是否更好。好处是您只需编写一次选择列表

DECLARE @Select1 varchar(1000)
DECLARE @Select2 varchar(1000)

DECLARE @SQL varchar(4000)


SET @Select1 = 'SELECT
    Column 1 AS c1,
    ...
    Column N AS cN'


SET @Select2 = 'SELECT
    ''Some String'' as c1,
    ...
    NULL as cN'


SET @SQL = @Select1 + ' FROM database1.dbo.Table1 '

SET @SQL = @SQL + ' UNION ' + @Select2 + ' FROM database1.dbo.Table2 '

SET @SQL = @SQL + ' UNION ' + @Select1 + ' FROM database2.dbo.Table1 '

SET @SQL = @SQL + ' UNION ' + @Select2 + ' FROM database2.dbo.Table2 '


EXEC @SQL

关于动态SQL主题-这里是一个示例-不确定它是否更好。好处是您只需编写一次选择列表

DECLARE @Select1 varchar(1000)
DECLARE @Select2 varchar(1000)

DECLARE @SQL varchar(4000)


SET @Select1 = 'SELECT
    Column 1 AS c1,
    ...
    Column N AS cN'


SET @Select2 = 'SELECT
    ''Some String'' as c1,
    ...
    NULL as cN'


SET @SQL = @Select1 + ' FROM database1.dbo.Table1 '

SET @SQL = @SQL + ' UNION ' + @Select2 + ' FROM database1.dbo.Table2 '

SET @SQL = @SQL + ' UNION ' + @Select1 + ' FROM database2.dbo.Table1 '

SET @SQL = @SQL + ' UNION ' + @Select2 + ' FROM database2.dbo.Table2 '


EXEC @SQL

如果您的所有进程都是这样的,那么您可能遇到了架构问题

您对table2的所有调用都只有一个有用的字段吗?(由于工会,最终只有一排?)

我完全赞同为这项工作使用参数化动态SQL和/或代码生成的想法,甚至使用
INFORMATION\u SCHEMA
动态生成列列表。这并不完全是您所需要的,但这只是一个开始(您可以从数据库和表的表中生成):


如果您的所有进程都是这样的,那么您可能遇到了架构问题

您对table2的所有调用都只有一个有用的字段吗?(由于工会,最终只有一排?)

我完全赞同为这项工作使用参数化动态SQL和/或代码生成的想法,甚至使用
INFORMATION\u SCHEMA
动态生成列列表。这并不完全是您所需要的,但这只是一个开始(您可以从数据库和表的表中生成):


这是一个非常标准的SQL模式。有时很容易将OOP/过程性代码原则(如DRY)随意转换为SQL,但它们不一定是可转换的概念

请注意,与搜索子模块相比,查询的整个逻辑设计是多么容易。如果其中一个子表达式有一个额外的列,或者列被反转,它就会突出。这基本上是一个非常简单的SQL语句,可以作为一个执行单元来使用,分解它会使它变得混乱


在调试时,可以方便地使用编辑器的文本突出显示选项有选择地执行语句的某些部分,这是过程代码中不存在的技术。OTOH,如果将所有片段分散到视图等中,那么试图追踪它们可能会变得混乱。即使是CTE也会使这变得不方便。

这是一个非常标准的SQL模式。有时很容易将OOP/过程性代码原则(如DRY)随意转换为SQL,但它们不一定是可转换的概念

请注意,您可以多么轻松地浏览整个logica SELECT DISTINCT subquery.c1, subquery.cN FROM ( SELECT Column 1 AS c1, Column N AS cN FROM database1.dbo.Table1 UNION ALL SELECT 'Some String' as c1, NULL as cN FROM database1.dbo.Table2 UNION ALL SELECT Column 1 AS c1, Column N AS cN FROM database2.dbo.Table1 UNION ALL SELECT 'Some String' as c1, NULL as cN FROM database2.dbo.Table2 ) subquery