我们所有使用关系数据库的人都知道(或正在学习)SQL是不同的。获得期望的结果,并有效地这样做,涉及到一个乏味的过程,其部分特征是学习不熟悉的范例,并发现一些我们最熟悉的编程模式在这里不起作用。常见的反模式是什么?


当前回答

没有使用With子句或适当的连接并依赖子查询。

反模式:

select 
 ...
from data
where RECORD.STATE IN (
          SELECT STATEID
            FROM STATE
           WHERE NAME IN
                    ('Published to test',
                     'Approved for public',
                     'Published to public',
                     'Archived'
                    ))

好: 我喜欢使用with子句使我的意图更易于阅读。

with valid_states as (
          SELECT STATEID
            FROM STATE
           WHERE NAME IN
                    ('Published to test',
                     'Approved for public',
                     'Published to public',
                     'Archived'
                    )
select  ... from data, valid_states
where data.state = valid_states.state

最好的:

select 
  ... 
from data join states using (state)
where 
states.state in  ('Published to test',
                     'Approved for public',
                     'Published to public',
                     'Archived'
                    )

其他回答

我一直对大多数程序员倾向于在数据访问层混合他们的ui逻辑感到失望:

SELECT
    FirstName + ' ' + LastName as "Full Name",
    case UserRole
        when 2 then "Admin"
        when 1 then "Moderator"
        else "User"
    end as "User's Role",
    case SignedIn
        when 0 then "Logged in"
        else "Logged out"
    end as "User signed in?",
    Convert(varchar(100), LastSignOn, 101) as "Last Sign On",
    DateDiff('d', LastSignOn, getDate()) as "Days since last sign on",
    AddrLine1 + ' ' + AddrLine2 + ' ' + AddrLine3 + ' ' +
        City + ', ' + State + ' ' + Zip as "Address",
    'XXX-XX-' + Substring(
        Convert(varchar(9), SSN), 6, 4) as "Social Security #"
FROM Users

通常,程序员这样做是因为他们想要将数据集直接绑定到一个网格上,而且在服务器端使用SQL Server格式比在客户端使用SQL Server格式更方便。

像上面所示的查询是非常脆弱的,因为它们将数据层与UI层紧密耦合在一起。最重要的是,这种编程风格彻底阻止了存储过程的可重用性。

有一张桌子

code_1
value_1
code_2
value_2
...
code_10
value_10

而不是有3个表

Code, value和code_value

你永远不知道什么时候你可能需要10对以上的代码,价值。

如果只需要一对,就不会浪费磁盘空间。

像这样将冗余表连接到查询中:

select emp.empno, dept.deptno
from emp
join dept on dept.deptno = emp.deptno;

在他们职业生涯的前6个月学习SQL,在接下来的10年里从不学习其他任何东西。特别是没有学习或有效地使用窗口/分析SQL特性。特别是over()和partition by的使用。

窗口函数,比如聚合 函数时,对对象进行聚合 定义的行集(组),但是 而不是返回一个值 组,窗口函数可以返回 每个组有多个值。

请参阅O'Reilly SQL Cookbook附录A,以获得窗口函数的良好概述。

把东西放在临时表中,特别是那些从SQL Server切换到Oracle的人有过度使用临时表的习惯。只需使用嵌套的选择语句。