sql - 子查询,不必重用代码
问题描述
我有一个相对简单的任务,由于我目前正在接近它的方式,它正在成为一个雷区,我想知道是否有一种更整洁/更清洁的方式而没有那么多可重复的代码。
以我正在执行以下选择的情况为例:
select a.col1, a.col2, a.col3, a.col4, a.col5 from a
但是a.col2
andb.col3
是选择本身的结果,即上面的代码变为:
select a.col1,
a.col2 = (select something from somewhere where a.id = b.id),
a.col3 = (select something_else from somewhere_else where a.id = c.id)
from a
然后最重要的是,是使用and的 语句col4
的结果 ,并且是另一个 使用,和and 的 语句,然后突然你有一些非常混乱和非常重复的东西:CASE
col2
col3
col5
CASE
col4
col3
col2
select a.col1,
a.col2 = (select something from somewhere where a.id = b.id),
a.col3 = (select something_else from somewhere_else where a.id = c.id),
a.col4 = (
case
when (select something from somewhere where a.id = b.id) = 'X' then 'Y'
else 'Z'
end
),
a.col5 = [INSERT ALL OF COL4 CODE HERE] = 'Something' THEN
(
case
when (select something_else_again from somewhere_else where a.id = b.id) = 'X' then 'Y'
else 'Z'
end
)
这是我目前遇到的现实生活中的问题,出于问题目的,我已尝试在上面进行简化。我肯定有一种更整洁的方法吗?
解决方案
根据数据库,您可以执行以下任何操作。前两个实质上创建了一个新的“结果表”,您可以从中选择并重用先前计算的结果。最后一个选项是使用函数进行简单的常规编程。
此外,选项 1 和 2 都会让您有机会加入更多表,在许多情况下,这比您在 select 子句中执行的子选择更可取
选项 1:with
条款
这适用于 PostgreSQL,不确定它是否适用于其他数据库:
with result1 as (
select [calculation] col1,
[calculation] col2,
*
from a
),
result2 as (
select [calculation] col3,
*
from result1
)
select [calculation] col4,
*
from result2
选项 2:子查询
应该适用于所有数据库。
select [calculation] col4,
*
from (
select [calculation] col3,
*
from (
select [calculation] col1,
[calculation] col2,
*
from a
) tt
) t
选项 3:功能/程序
这在一定程度上取决于数据库实现,您必须阅读它。但取决于您是否想跨多个查询重用逻辑,这可能是一个不错的选择。不利的一面是,在函数中进行选择会带来隐藏成本。
它可能是这样的:
CREATE OR REPLACE FUNCTION calcualtion1(id integer) RETURNS boolean AS $$
BEGIN
RETURN [do calculation here];
END;
$$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION calcualtion2(id integer) RETURNS boolean AS $$
BEGIN
RETURN [call calculation1 from here];
END;
$$ LANGUAGE plpgsql;
[...]
select calculation1(id) col1,
calculation2(id) col2,
calculation3(id) col3,
calculation4(id) col4,
from a
不过,我想得越多,我很确定在您的情况下,这在速度方面会有很多缺点。但是在这里注意它,以防其他有类似问题的人出现在这有帮助的地方。
推荐阅读
- php - PHPDoc继承函数体中方法抛出的异常与PhpStorm
- django-admin - 如何在 Django 管理中添加一个弹出窗口以链接回当前的内联记录
- excel - 按月划分的未决投诉数量图表
- vue.js - Vuetify timepicker 返回值到模型
- c# - 我可以从我的 Unity 应用程序中阅读电子邮件收件箱吗?
- c# - 以编程方式获取 DataGridComboBoxColumn 中 ComboBox 的内容
- php - 将数组字段调用到 If 条件语句
- excel - Excel 数据透视表自动排序
- c# - 从消息检查器访问 HttpContext.Current 以进行异步 WCF 调用
- unity3d - Unity 跨平台