【问题标题】:how do i return only a part of value in a row using sql我如何使用sql只返回一行中的一部分值
【发布时间】:2018-12-29 12:08:39
【问题描述】:

下面是我在 SQL server 中的表,

Title           value
-------------   -------
abc_ef_1_123    53.2
abc_ef_1_1      43.2
abc_ef_1_11     23.1
abc_ef_1_12     45.2
abc_ef_1_13     56.4
def_cef_3_23    98.1
def_cef_3_3     53.2
def_cef_3_12    43.2
def_cef_3_13    23.1
def_cef_3_123   45.2

需要按照下面第三个'_'之前的值对行进行分组,

从table1中按标题分组选择标题,最大值(值)作为值;

结果应该是,

title     value
--------- -----
abc_ef_1  56.4
def_cef_3 98.1

请帮忙。

【问题讨论】:

  • 只是为了后代,这就是为什么您不发明自己的列格式。字符串中的每个标记都应该是不同的列

标签: sql sql-server


【解决方案1】:

我相信这会很好地完成工作(将“测试”替换为您的表名):

;with cte as (
  select 
    left(Title, len(Title) - charindex('_', reverse(Title) + '_')) as Title, 
    Value
  from Test
)

select cte.Title, MAX(cte.value)
from cte
group by cte.Title

现在,准确地射出第三个下划线, 创建下面文章指示的函数,然后应用以下查询以获得所需的结果。将凌乱的逻辑内联有点反直觉,所以使用这样的函数是一种方法。 http://www.sqlservercentral.com/scripts/Miscellaneous/30497

使用上面链接中的 Sql Server 函数进行查询:

;with cte as (
  select 
    LEFT(Title, dbo.CHARINDEX2('_', Title, 3) - 1) as Title, 
    Value
  from Test
)

select cte.Title, MAX(cte.value)
from cte
group by cte.Title

祝你好运!

【讨论】:

  • 只是注意到文本中总是正好有三个下划线的假设。
  • 好吧,我假设最后一个下划线是分裂点,当然是样本中的第三个。我已经编辑了我的答案以满足您的确切情况。
【解决方案2】:
with
  sample_data (title, value) as (
    select 'abc_ef_1_123' , 53.2 from dual union all
    select 'abc_ef_1_1'   , 43.2 from dual union all
    select 'abc_ef_1_11'  , 23.1 from dual union all
    select 'abc_ef_1_12'  , 45.2 from dual union all
    select 'abc_ef_1_13'  , 56.4 from dual union all
    select 'def_cef_3_23' , 98.1 from dual union all
    select 'def_cef_3_3'  , 53.2 from dual union all
    select 'def_cef_3_12' , 43.2 from dual union all
    select 'def_cef_3_13' , 23.1 from dual union all
    select 'def_cef_3_123', 45.2 from dual
  )
select   substr(title, 1, instr(title, '_', 1, 3) - 1) as title, max(value) as value
from     sample_data
group by substr(title, 1, instr(title, '_', 1, 3) - 1);

TITLE       VALUE
----------- -----
abc_ef_1     56.4
def_cef_3    98.1

主要的收获是您可以按您喜欢的任何表达式进行分组,您不限于按列分组。此外,您必须在GROUP BYSELECT 中重复相同的表达式;唉,在 SELECT 中给出的别名(名称,标签)不能在 GROUP BY 中使用。 (如果表达式比这种情况复杂得多,您将首先在子查询中创建别名,然后在聚合外部查询中使用它。)

当然,在这种情况下情况更糟,因为您想在输出中使用相同的列名title。如果您要在GROUP BY 中按title 分组,那将按输入表中的列分组,而不是按SELECT 中的表达式分组。这就是为什么您在输出中所做的通常是一种不好的做法:因为新列与您在基表中的不同,所以给它一个不同的名称,而不是 title。我只是不情愿地听从了你的引导。

【讨论】:

  • 我正在 SQL 服务器上尝试。我以前没提过这件事是我的错。 Instr 在 SQL Server 中不可用
  • @Chand - 在帖子中不仅提到了 SQL Server,标签也是错误的(我看到你现在已经修复了)。在任何情况下 - 在 SQL Server 中找到类似的函数,它与 Oracle 中的 INSTR 执行相同的操作。可能SUBSTR的语法也不同——我不懂SQL Server,也许其他人会给你更好的建议。
【解决方案3】:

你可以使用regexp_substr():

select regexp_substr(title, '[^_]*_[^_]*_[^_]*', 1, 1),
       max(value)
from t
group by regexp_substr(title, '[^_]*_[^_]*_[^_]*', 1, 1);

【讨论】:

  • 我正在 SQL 服务器上尝试。我以前没提过这件事是我的错。 Instr 在 SQL Server 中不可用
【解决方案4】:

选择

Left(Title, charindex('[ _ ]' , Title, charindex('[ _ ]' , Title, charindex('[ _ ]' , 标题))))

,最大值(值)

来自Tbl

分组

Left(Title, charindex('[ _ ]' , Title, charindex('[ _ ]' , Title, charindex('[ _ ]' , 标题))))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-08-03
    • 1970-01-01
    • 1970-01-01
    • 2014-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-25
    相关资源
    最近更新 更多