减少SQL代码中的冗余/重复

时间:2011-04-07 09:32:08

标签: sql sql-server coding-style

在stackoverflow上的this question中,接受的答案涉及多次重复相同的代码片段。根据我的经验,许多人会出于各种原因,通过各种方式封装代码片段来努力减少这种情况; - 可维护性(更少的地方)
- 可读性(读取代码一次,然后每次都是“别名”)
- 等等

使用链接问题中的代码,您将如何开始减少相同代码段的重复?或者你会原样保留它吗?

(不使用替代逻辑,但坚持使用REPLACE等,只是改变相同逻辑的现状。)

Select  Case
        When CharIndex('.', Replace(URL, 'www.','')) > 0 then
           Left(Replace(URL, 'www.',''), CharIndex('.',Replace(URL, 'www.',''))-1)
        Else
           Replace(URL, 'www.','')
        End as [CleanURL]
From dbo.YourTable 

(接受的答案已更改,因此我将代码示例复制到此处。)

修改

只是澄清一下,因为我认为我引起了混乱。

这不是:
- 如何封装这整段代码以便重复使用?

但更确切地说:
- 如何减少这段代码中的冗余?

6 个答案:

答案 0 :(得分:4)

;with cte as
(
  select replace(URL, 'www.', '')+'.' as url
  from myTable
)
select
  left(url, charindex('.', url)-1)
from cte

编辑1 您可以使用执行重复代码的嵌套选择。与使用cte没什么不同。

Select  Case
        When CharIndex('.', URL) > 0 then
           Left(URL, CharIndex('.',URL)-1)
        Else
           URL
        End as [CleanURL]
From 
  (select Replace(URL, 'www.','') as URL
   from myTable) as T

Edit2 删除了重复的charindex。使用交叉申请

select
  case
    when c2.idx > 0 then
      left(c1.url, c2.idx)
    else
      c1.url
  end
from myTable as m
  cross apply (select replace(m.URL, 'www.', '')) as c1(url)
  cross apply (select charindex('.', c1.url)) as c2(idx)

答案 1 :(得分:1)

受UW Concept的启发,但使用表值函数和sub_query来避免与建议标量函数和内部变量的使用相关的性能损失。

SELECT
  myTable.*,
  cleanup.domain
FROM
  myTable
CROSS APPLY
  dbo.CleanupURL(myTable.myURL) as cleanup

使用以下功能...

CREATE FUNCTION
  dbo.CleanupUrl(@urlstring nvarchar(200))
RETURNS TABLE
AS
RETURN
(
  SELECT
    CASE WHEN suffix_pos = 0 THEN
      myURL
    ELSE
      LEFT(myURL, suffix_pos - 1)
    END AS domain
  FROM
  (
    SELECT
      myURL,
      CharIndex('.', myURL) AS suffix_pos
    FROM
    (
      SELECT
        REPLACE(@urlstring, 'www.', '') as myURL
    )
    AS no_prefix
  )
  AS suffix_found
)

答案 2 :(得分:0)

WITH
  prefix_removed
AS
(
  SELECT
    *,
    REPLACE(URL, 'www.','') AS myURL_NoPrefix
  FROM
    myTable
)
,
  suffix_start
AS
(
   SELECT
     *,
     CharIndex('.', myURL_NoPrefix) AS domain_end
   FROM
     prefix_removed
)
SELECT
  CASE WHEN
    doamin_end = 0
  THEN
    myURL_NoPrefix
  ELSE
    LEFT(myURL_NoPrefix, domain_end-1)
  END AS domain
FROM
  prefix_removed

答案 3 :(得分:0)

The WITH clause应该非常适合这个:

WITH replaced_urls AS (
    SELECT Replace(URL, 'www.','') AS url,
           CharIndex('.', Replace(URL, 'www.','')) AS idx
    FROM dbo.YourTable
)
Select  Case
    When idx > 0 then
       Left(url, idx-1)
    Else
       url
    End as [CleanURL]
From replaced_urls 

这将创建一个在查询期间存在的临时表,其中包含多次使用的结果。 (我没有测试过,但应该可以使用。)

答案 4 :(得分:0)

这是一个带函数的例子

SELECT dbo.CleanupUrl(URL) AS CleanURL FROM yourTable;

负责格式化的功能

CREATE FUNCTION dbo.CleanupUrl(@urlstring nvarchar(200))
RETURNS nvarchar(200)
AS
BEGIN
  DECLARE @SReturn nvarchar(200), @ReplacedURL nvarchar(200)
  SET @ReplacedURL = Replace(@urlstring, 'www.','')
  SELECT @SReturn = Case
        When CharIndex('.', @ReplacedURL) > 0 then
           Left(@ReplacedURL, CharIndex('.',@ReplacedURL)-1)
        Else
           @ReplacedURL
        End

RETURN @SReturn
END

然后,您可以从每个查询中调用此函数。

答案 5 :(得分:0)

SELECT
  myTable.*,
  LEFT(noPrefix.myURL, domain_end.pos) AS domain
FROM
  myTable
CROSS APPLY
  (SELECT REPLACE(myTable.myURL, 'www.', '') AS myURL) AS [noPrefix]
CROSS APPLY
  (SELECT CHARINDEX('.', noPrefix.MyURL) AS pos) AS [suffix_start]
CROSS APPLY
  (SELECT CASE WHEN suffix_start.pos = 0 THEN LEN(noPrefix.myURL) ELSE suffix_start.pos - 1 END AS pos) AS [domain_end]