SQL - 从组

时间:2016-05-24 17:08:14

标签: sql postgresql

每次用户搜索记录到桌面的内容时。

也会记录子搜索。它们用星号记录。

我正在尝试为每次搜索拉出最长的字符串。

用户可以进行多次搜索。

例如,User1搜索"数据管理"和"状态信息"。我想忽略记录的部分搜索(子搜索),例如"数据管理*","数据管理*","状态在*"并完成已完成的搜索。

                id user   data
                ---------------
                1  user1  data manag*
                2  user1  confer*
                3  user1  incomplete sear*
                4  user1  data managem*
                5  user1  conference c*
                6  user1  data management
                7  user1  conference call*
                8 user1  status in*
                9 user1  status information

输出应为

            user1 data management
            user1 conference call*
            user1 incomplete sear*
            user1 status information

你能帮帮忙吗?

3 个答案:

答案 0 :(得分:1)

主要想法是按p列排序数据,并将每个值与下一个值进行比较。如果下一个值不以current开头,那么当前值就是所需的结果。

简化,中间查询:

data

如您所见,所需的值位于with t(x) as (values ('data manag*'),('confer*'),('incomplete sear*'), ('data managem*'),('conference c*'),('data management'), ('conference call*'),('status in*'),('status information')) select *, case when right(x,1) != '*' then 1 when replace(x,'*','') = substring(y,1,length(replace(x,'*',''))) then 0 else 1 end hit from ( select x, lead(x) over (order by x) as y /*lag(x,-1) can be used instead of lead(x)*/ from t) r; x | y | hit --------------------+--------------------+------ confer* | conference c* | 0 conference c* | conference call* | 0 conference call* | data manag* | 1 data manag* | data managem* | 0 data managem* | data management | 0 data management | incomplete sear* | 1 incomplete sear* | status in* | 1 status in* | status information | 0 status information | | 1 (9 rows) x。将其用作子查询或视图以获得最终结果。

答案 1 :(得分:1)

这样做很好:

with
  searches (id, "user", data) as ( values
    (1, 'user1', 'data manag*'),
    (2, 'user1', 'confer*'),
    (3, 'user1', 'incomplete sear*'),
    (4, 'user1', 'data managem*'),
    (5, 'user1', 'conference c*'),
    (6, 'user1', 'data management'),
    (7, 'user1', 'conference call*'),
    (8, 'user1', 'status in*'),
    (9, 'user1', 'status information')
    )
select "user", data
from searches s
where data not like '%*'
   or not exists (
            select 1
            from searches
            where "user" = s."user"
              and id <> s.id
              and data like (left(s.data, -1)||'%')
          )

答案 2 :(得分:0)

SELECT user, data
FROM (
        SELECT user,
               data,
               ROW_NUMBER() over ( PARTITION BY user
                                   ORDER BY char_length(data) DESC) rn
        FROM table
     ) t
WHERE t.rn = 1