在重复项中选择不同的连续行

时间:2015-06-11 06:20:52

标签: sql sql-server sql-server-2008-r2

我有一张下面结构的表格:

create table roster
(
date date not null,
first nvarchar(20) not null,
second nvarchar(20) not null,
third nvarchar(20) not null,
fourth nvarchar(20) not null,
)
go

并且插入了以下数据:

insert into roster values ('2015-06-10 12:45:34', 'e', 'm', 'a', 'r')
insert into roster values ('2015-06-11 12:45:34', 'e', 'v', 'a', 'r')
insert into roster values ('2015-06-12 12:45:34', 'e', 'm', 'a', 'd') 
insert into roster values ('2015-06-13 12:45:34', 'e', 'm', 'a', 'd') *
insert into roster values ('2015-06-14 12:45:34', 'e', 'm', 'a', 'r')
insert into roster values ('2015-06-15 12:45:34', 'e', 'm', 'a', 'r') *
insert into roster values ('2015-06-16 12:45:34', 'z', 'm', 't', 'r')

注意:*标记重复。

如何只选择“第一”,“第二”,“第三”和“第四”的一个唯一连续组合?例如,使用上面插入的数据,所需的输出是:

Date                 First Second Third Fourth
2015-06-10 12:45:34, e     m      a     r
2015-06-11 12:45:34, e     v      a     r
2015-06-12 12:45:34, e     m      a     d
2015-06-14 12:45:34, e     m      a     r
2015-06-16 12:45:34, z     m      t     r

我正在寻找一种解决方案,当它们不再连续时(或序列被破坏时)保留条目,但删除连续条目的重复项。

我在这里发布了类似的问题,但我已经能够制定一个使用分组的解决方案。

任何帮助将不胜感激

2 个答案:

答案 0 :(得分:4)

如果您只需要一个private void shareContent() { UtuBaseActivity activity = (UtuBaseActivity) getActivity(); if (activity == null || activity.isFinishing()) return; if (promotionDetail == null) return; String title = getResources().getString(R.string.share_chooser_title); String app_name = getResources().getString(R.string.app_name); List<Intent> targetShareIntents = new ArrayList<>(); Intent shareIntent = new Intent(); shareIntent.setAction(Intent.ACTION_SEND); shareIntent.setType("text/plain"); List<ResolveInfo> resInfos = activity.getPackageManager().queryIntentActivities(shareIntent, 0); if (!resInfos.isEmpty()) { for (ResolveInfo resInfo : resInfos) { String packageName = resInfo.activityInfo.packageName; String parentName = resInfo.activityInfo.parentActivityName; if (packageName.contains("com.twitter.android") || packageName.contains("com.facebook.katana")) { if (packageName.contains("com.twitter.android")) if (!parentName.equals("com.twitter.android.MainActivity")) continue; Intent intent = new Intent(); intent.setComponent(new ComponentName(packageName, resInfo.activityInfo.name)); intent.setAction(Intent.ACTION_SEND); intent.setType("text/plain"); intent.putExtra(Intent.EXTRA_SUBJECT, app_name); intent.putExtra(Intent.EXTRA_TEXT, promotionDetail.getCoverpicture()); intent.setPackage(packageName); targetShareIntents.add(intent); } } if (!targetShareIntents.isEmpty()) { Intent chooserIntent = Intent.createChooser(targetShareIntents.remove(0), title); chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetShareIntents.toArray(new Parcelable[]{})); startActivity(chooserIntent); } else { // As fallback, launch sharer.php in a browser String sharerUrl = "https://www.facebook.com/sharer/sharer.php?u=" + promotionDetail.getCoverpicture(); Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse(sharerUrl)); startActivity(i); } } } ,为什么需要group by

exists()

SQL Fiddle

修改

;with data as
(
    select ROW_NUMBER() OVER (ORDER BY date) AS number, * from roster
)
select * from data where 
    not exists -- Just compare with the previous column, if match say bye
    (
        select * from data prev where 1 = 1
            and prev.first = data.first 
            and prev.second = data.second 
            and prev.third = data.third 
            and prev.fourth = data.fourth 
            and prev.number + 1 = data.number
    )

SQL Fiddle

答案 1 :(得分:0)

您可以按第一,第二,第三,第四的值进行分组 然后选择使用min(日期)遇到这些值的第一个日期,或选择最后一次使用max(date)

遇到的最后一个日期的示例:fiddle

SELECT min(date) as startdate ,max(date) as enddate,  first, second, third, fourth 
from roster
GROUP BY first, second, third, fourth

编辑:编辑上一个查询以包含开始和结束日期

EXTRA:等待你回复时我正在玩的东西:包括1个字段中出现值的日期列表:

SELECT first, second, third, fourth,
STUFF((
          SELECT ',' + convert(varchar(25),T.date)
          FROM roster T
          WHERE A.first = T.first
          AND A.second = T.second
          AND A.third = T.third
          AND A.fourth = T.fourth
          ORDER BY T.date
          FOR XML PATH('')), 1, 1, '') as dates

from roster A
GROUP BY first, second, third, fourth
编辑:我非常接近你想要的但不完全,但是我不知道如何让它更接近,我想这是我走的,其余的由其他人决定:D:{{ 3}}

SELECT b.date as startdate, a.date as enddate, a.first, a.second, a.third, a.fourth FROM
(Select ROW_NUMBER() 
        OVER (ORDER BY first, second, third, fourth,date ) AS Row,
        date,
        first,second,third,fourth
from roster) A
JOIN 
(Select ROW_NUMBER() 
        OVER (ORDER BY first, second, third, fourth,date ) AS Row,
        date,
        first,second,third,fourth
from roster) B
ON A.row = b.row + 1
WHERE a.first = b.first
and a.second = b.second
and a.third = b.third
and a.fourth = b.fourth
UNION
select max(date) as startdate, null as enddate, first, second, third, fourth
FROM roster
group by first, second, third, fourth
having count(*) = 1;