繁体   English   中英

选择列作为唯一值SQL Server

[英]Selecting column as unique value sql server

我在MS SQL Server “ MyTable”中有一个表,如下所示-

PkId    |    Title   |   Some Column
-----------------------------------------------
1       |    User 2  | Some value for "User 2"
-----------------------------------------------
2       |    User    | Some value for the user
-----------------------------------------------
3       |    User    | Some value for the user
-----------------------------------------------
4       |    Admin   | Some value for the Admin
-----------------------------------------------
5       |    Guest 1 | Some value for "Guest 1"
-----------------------------------------------
6       |    Guest   | Some value for the guest

我想要一个输出-

User 1 - Some value for the user
User 2 - Some value for "User 2" [Note - this "User 2" title was existing and this keeps the "Some Column" value intact as well]
User 3 - Some value for the user
Admin 1 - Some value for the Admin
Guest 1 - Some value for "Guest 1" [Note - Existing title with existing value]
Guest 2 - Some value for the guest

[我不关心顺序,但想像上面那样映射用户,以便我可以在标题后得到数字(如果标题已经有编号,它将跳过该数字,并且不会重复相同的内容)列”值保持不变]

我已经尝试对分区进行排序,但是没有达到预期的结果。 请在这里帮助我。

该查询应该执行您想要的操作。 这可能是无效的,并且正如其他人所说的那样,将用户名和数字存储在这样的字符串中可能是一个好主意。

查询:

With titles as (
    SELECT distinct title = title FROM @MyTable
    WHERE NOT RIGHT(title, 1) LIKE '[0-9]'
), numbers as (
    SELECT n = ROW_NUMBER() over(PARTITION BY t.title ORDER BY pkid DESC)
        , pkid
        , Name 
        , grp = t.title
        , id = TRY_PARSE(CASE WHEN d.title NOT LIKE t.title THEN RIGHT(d.title, ABS(LEN(d.title) - LEN(t.title))) END as bigint)
        , missing = ROW_NUMBER() over(PARTITION BY t.title, CASE WHEN d.title NOT LIKE t.title THEN 0 ELSE 1 END ORDER BY pkid DESC)
    FROM @MyTable d
    INNER JOIN titles t ON d.title LIKE t.title+'%'
), new_n as (
    SELECT n, grp, id = ROW_NUMBER() over(PARTITION BY grp ORDER BY n)
    FROM (
        SELECT n, grp
        FROM numbers
        EXCEPT
        SELECT id, grp
        FROM numbers
        WHERE id IS NOT NULL
    ) as x
)
SELECT nb.pkid, n = coalesce(nb.id, nw.n), nw.grp+CAST(coalesce(nb.id, nw.n) as varchar(5)), nb.name--, *
FROM numbers nb
LEFT JOIN new_n nw ON nb.grp = nw.grp AND nb.missing = nw.id
ORDER BY nb.pkid
  • CTE titles查找不带数字(用户,管理员和来宾)的独特标题
  • CTE number按组标题(n)对其进行分区,获取现有标题的ID(id),并按组标题进行分区以及ID是否缺失(丢失)
  • CTE new_n获取每个组的未使用ID的列表
  • 最后选择将所有内容放在一起并使用现有ID或将其替换为可用ID中的1个(如果丢失)

输出:

pkid    n   title   name
1       2   User2   Some value for "User 2"
2       3   User3   Some value for the user
3       1   User1   Some value for the user
4       1   Admin1  Some value for the Admin
5       1   Guest1  Some value for "Guest 1"
6       2   Guest2  Some value for the guest

数据:

declare @MyTable table(pkid int, title varchar(100), name varchar(100));
insert into @MyTable(pkid, title, name) values
    (1, 'User 2', 'Some value for "User 2"')
    , (2, 'User', 'Some value for the user')
    , (3, 'User', 'Some value for the user')
    , (4, 'Admin', 'Some value for the Admin')
    , (5, 'Guest 1', 'Some value for "Guest 1"')
    , (6, 'Guest', 'Some value for the guest')
    ;

用这个 :

select 'user ' + (case when patindex('%[0-9]%',title) = 0  then row_number() over (partition by title order by (select 1)) else substring(title,patindex('%[0-9]%',title),1) end) +  '-' + somecolumn
from table1

如果数字始终在标题列的末尾,则可以使用-

select 'user ' + (case when isnumeric(right(title,1)) = 1 then right(title,1)  else  row_number() over (partition by title order by (select 1)) end) +  '-' + somecolumn
from table1

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM