Sql 按名称相同的已更改列排序
我有一个表Sql 按名称相同的已更改列排序,sql,postgresql,replace,pattern-matching,sql-order-by,Sql,Postgresql,Replace,Pattern Matching,Sql Order By,我有一个表artist,有几个列,如name,type… 我希望返回列名称,并按字母顺序排列,但应调整列名。如果艺术家的姓名以“the”(不区分大小写)开头,则应将其删除并置于大写名称后面,例如“the Beatles”->“Beatles,the” 这是我的代码(不起作用): 问题1:name未被替换,它会创建一个新列 问题2:新列具有相同的名称=>columnname在orderbyname中不明确 如何轻松解决这些问题?在案例中使用ELSE子句: SELECT CASE WHE
artist
,有几个列,如name
,type
…我希望返回列
名称
,并按字母顺序排列,但应调整列名。如果艺术家的姓名以“the”(不区分大小写)开头,则应将其删除并置于大写名称后面,例如“the Beatles”->“Beatles,the”
这是我的代码(不起作用):
问题1:name
未被替换,它会创建一个新列
问题2:新列具有相同的名称=>columnname
在orderbyname
中不明确
如何轻松解决这些问题?在
案例中使用ELSE
子句
:
SELECT
CASE
WHEN UPPER(name) LIKE 'THE %' THEN CONCAT(RIGHT(name, length(name)-4),', THE')
ELSE name
END AS name
FROM artist
ORDER BY name
如果您只想将其用于排序,则可以将逻辑仅放在
order by
子句中:
order by (case when name ilike 'the%'
then substring(name from 5) || ', The'
else name
end)
如果您还希望在选择
子句中使用此列,请使用名称
以外的别名。已用于第一列的:
select name,
(case when name ilike 'the%'
then substring(name from 5) || ', The'
else name
end) as munged_name
. . .
order by munged_name
注意:ilike
是Postgres的扩展,用于不区分大小写的like
查询
根本原因
- 获取字符串减去n个前导字符的最简单、最快的表达式是:
比ILIKE
/lower()
upper()更简单,比如…
- 您不需要,普通连接运算符也可以更快地执行相同的操作,因为表达式
在此上下文中保证right(name,-4)
notnull
- 当与列名的SQL可见性规则混淆时,或者当存在重复的输出列名时(这在Postgres中是完全合法的),您还可以在
、GROUP BY
或ORDER BY
子句中使用位置引用:DISTINCT ON(…)
- 如果您经常运行此查询,我建议在同一表达式上使用一个查询,以获得更快的结果:
CREATE INDEX artist_name_sort_idx ON artist ((CASE WHEN name ILIKE 'THE %' THEN right(name, -4) || ', THE' ELSE name END));
name | artist_id | name
--------------+-----------+-------------
| 10 |
, THE | 9 | The -- remaining corner case
Abba | 7 | Abba
bEatles, THE | 2 | tHe bEatles
Beatles, THE | 1 | The Beatles
The, THE | 3 | The The
Then | 4 | Then
Theodor | 6 | Theodor
X, THE | 5 | The X
ZZ TOP | 8 | ZZ TOP
<NULL> | 11 | <NULL>
name |艺术家| id | name
--------------+-----------+-------------
| 10 |
| 9 | |剩余角案例
阿巴| 7 |阿巴
披头士乐队,披头士乐队
披头士乐队,披头士乐队
这个,这个| 3 |这个,
然后| 4 |然后
西奥多| 6 |西奥多
十、 |5 | X
ZZ顶部| 8 | ZZ顶部
| 11 |
请始终添加您的Postgres版本。这并不能解决以下问题:问题2:新列具有相同的名称=>按名称排列的列名不明确。
@ErwinBrandstetter问题1。名称不会被替换,它将创建一个新列。
。原始名称替换为大小写
和别名。我不明白为什么这是模棱两可的。是否可以提供SQLFIDLE with error?ORDER BY name
如果输出中有多个名为name的列,则引发异常。@ERWINBRANDSTETER该点在我的查询中没有多个列。作者明确表示,他希望替换名称,而不是创建新列,如果他想要两列,则需要别名。
CREATE INDEX artist_name_sort_idx ON artist
((CASE WHEN name ILIKE 'THE %' THEN right(name, -4) || ', THE' ELSE name END));
WITH artist(artist_id, name) AS (
VALUES
(1, 'The Beatles')
, (2, 'tHe bEatles')
, (3, 'The The')
, (4, 'Then')
, (5, 'The X')
, (6, 'Theodor')
, (7, 'Abba')
, (8, 'ZZ TOP')
, (9, 'The ') -- unlikely corner case, I don't think it would pay to test for it
, (10, '') -- empty string
, (11, NULL) -- NULL
)
SELECT CASE WHEN name ILIKE 'THE %' THEN right(name, -4) || ', THE' ELSE name END AS name
, *
FROM artist
ORDER BY 1;
name | artist_id | name
--------------+-----------+-------------
| 10 |
, THE | 9 | The -- remaining corner case
Abba | 7 | Abba
bEatles, THE | 2 | tHe bEatles
Beatles, THE | 1 | The Beatles
The, THE | 3 | The The
Then | 4 | Then
Theodor | 6 | Theodor
X, THE | 5 | The X
ZZ TOP | 8 | ZZ TOP
<NULL> | 11 | <NULL>