如何在一列中获得具有多个可能值的不同值?

时间:2012-01-19 14:47:33

标签: sql postgresql

如果可能的话,我正在尝试解决,让我举个例子。如果你能引导我走向正确的方向,那将是非常棒的。

Table = names
--------------------
Marks & Spencer
Marks & Spencer
marks & spencer

我要做的是返回不同的值,我已经转换了所有&标志并改为大写。

所以我的查询是:

SELECT regexp_replace(UPPER(name), '&(amp;)*|\\+', '&', 'gi') AS name FROM names GROUP BY names;

但是,我想要做的还是返回一个原始值,哪个没关系,但我只想要返回1行,比如

Result
----------------
name            original
------------------------
MARKS&SPENCER   Marks & Spencer

这可能吗?因为目前我得到的是:

Result
----------------
name            original
------------------------
MARKS&SPENCER   Marks & Spencer
MARKS&SPENCER   Marks & Spencer
MARKS&SPENCER   marks & spencer

感谢您的阅读,非常感谢您的帮助。

==========

修改

我用来获得上述结果的查询是:

SELECT names.name, T.result FROM names 
INNER JOIN 
(
    SELECT DISTINCT regexp_replace(UPPER(name), '&(amp;)*|\\+', '&', 'gi') AS result FROM names 
) AS T 
ON regexp_replace(UPPER(name), '&(amp;)*|\\+', '&', 'gi')=T.result 
GROUP BY T.result, names.name 
ORDER BY T.result ASC

我正在使用PostgreSQL btw,它可以做的不仅仅是MySQL改变了吗?

3 个答案:

答案 0 :(得分:1)

您需要按新名称进行分组才能获得一行,并且由于您不关心出现哪个原始名称,请使用min之类的内容进行汇总:

SELECT min(name),regexp_replace(UPPER(name), '&(amp;)*|\\+', '&', 'gi') AS name
FROM names
GROUP BY regexp_replace(UPPER(name), '&(amp;)*|\\+', '&', 'gi')

答案 1 :(得分:1)

仍有改进的余地:

SELECT regexp_replace(upper(name), E'&(?:AMP;)+|\\+', '&', 'g') AS name
     , min(name) AS min_org_name
--   , string_agg(name) AS org_names  -- if you want a list of originals
--   , array_to_string(array_agg(name), ', ') AS org_names -- for pg < 9.0+
     , count(*) AS ct
FROM  (   
    SELECT *
    FROM  (VALUES
          ('Marks & Spencer')
        , ('Marks &amp; Spencer')
        , ('marks &amp; spencer')
        , ('marks &amp; speNceR + sons')
        , ('marks &amp;amp;AMP; speNceR & sons')
       ) AS names(name)
    ) name
GROUP  BY 1;

重点

  • 改进正则表达式:
    • 使用相同的&amp;(amp;)*
    • 替换&(amp;)+
    • 在原件上使用upper()后,'i'标志只会减慢执行速度。相反大写模式:&(AMP;)+
    • 使用non-capturing parenthesis(?:)
    • 在使用转义序列\\+时,请使用正确的语法E''
  • 使用位置参数简化GROUP BY,无需拼写两次

答案 2 :(得分:0)

目前,您要按原始字段进行分组(您不能按照选择中的字段进行分组)

你想要其中一个吗?

SELECT DISTINCT
  name                                                       AS original,
  regexp_replace(UPPER(name), '&amp;(amp;)*|\\+', '&', 'gi') AS name
FROM
  names

或者...

SELECT
  name                                                       AS original,
  regexp_replace(UPPER(name), '&amp;(amp;)*|\\+', '&', 'gi') AS name
FROM
  names
GROUP BY
  name,
  regexp_replace(UPPER(name), '&amp;(amp;)*|\\+', '&', 'gi')

或者...

SELECT
  original,
  name
FROM
(
  SELECT
    name                                                       AS original,
    regexp_replace(UPPER(name), '&amp;(amp;)*|\\+', '&', 'gi') AS name
  FROM
    names
)
  AS clean_data
GROUP BY
  original,
  name