选择特定值

时间:2017-07-14 15:49:41

标签: sql sql-server

我在表格中有一列包含以下示例数据:

20170426-31974-B
20170426-31980
20170426-32014
20170426-32609
20170426-32069-B
20170426-32649
20170426-32659
20170426-32669-B
20170426-32849

-B的值是参考值。所有其他文件(不带-B)应该有一个与之关联的引用文件。因此,引用(-B)之间的所有差距应该与之前的" -B"相关联。

  • 无论如何,通过查询,将行与引用相关联" -B"?

我的意思是:

20170426-31980 -> reference to 20170426-31974-B
20170426-32014 -> reference to 20170426-31974-B
20170426-32609 -> reference to 20170426-31974-B
20170426-32649 -> reference to 20170426-32069-B
20170426-32659 -> reference to 20170426-32069-B
20170426-32849 -> refence to 20170426-32669-B

换句话说,我需要在-B之间获取所有文件。所有这些文件都应与之前的-B。

相关联

选择应返回类似

的内容
20170426-31980 || 20170426-31974-B
20170426-32014 || 20170426-31974-B
20170426-32609 || 20170426-31974-B
20170426-32649 || 20170426-32069-B
20170426-32659 || 20170426-32069-B
20170426-32849 || 20170426-32669-B

我尝试了this idea

SELECT  FILE_NAME
FROM TBL_FILE_NAMES
CROSS APPLY(SELECT FILE_NAME) FROM TBL_FILE_NAMES WHERE file_name LIKE '%-B') CA_min(file_name)
CROSS APPLY(SELECT FILE_NAME) FROM TBL_FILE_NAMES WHERE file_name LIKE '%-B') CA_max(file_name)
WHERE [DATE] BETWEEN start_dt AND end_dt

但我相信我的逻辑错了。我应该尝试使用光标而不是查询吗?

经过一些评论后,订单很重要。这些名称是关于时间创建的。该文件的第一部分是yearmonthday-seconds。我的问题是每个文件都应该有一个引用(-B)。如何知道哪些文件与-B相关联?它是参考文件之间的日期。

20170426-31974-B.csv
20170426-31980.csv
20170426-31987.csv
20170426-31994.csv
20170426-32004.csv
20170426-32014.csv
20170426-32069-B.csv
20170426-32073.csv
20170426-32079.csv
20170426-32639.csv
20170426-32659.csv
20170426-32669-B.csv
20170426-32674.csv  

在这种情况下,我有我的第一个参考号20170426-31974-B.csv。所有即将到来的文件(按时间顺序)直到我们达到第二个参考应该指向第一个参考。

  1. 参考文献1 = 20170426-31974-B.csv
  2. 相关的值
    20170426-31980.csv
    20170426-31987.csv
    20170426-31994.csv
    20170426-32004.csv
    20170426-32014.csv
    
    1. 参考文献2 = 20170426-32069-B.csv
    2. 相关联的值
      20170426-32073.csv
      20170426-32079.csv
      20170426-32639.csv
      20170426-32659.csv
      
      1. 参考文献3:20170426-32669-B.csv
      2. 相关的值
        20170426-32674.csv
        

2 个答案:

答案 0 :(得分:2)

尝试

declare @t table(col varchar(100));
insert @t(col)
values
('20170426-31974-B')
,('20170426-31980')
,('20170426-32014')
,('20170426-32609')
,('20170426-32069-B')
,('20170426-32649')
,('20170426-32659')
,('20170426-32669-B')
,('20170426-32849');

with parent as (
    select col, strt = left(col,14), nxt = coalesce(left(lead(col) over(order by col), 14), '99999999-99999')
    from @t
    where right(col,2) ='-B' 
)
select parent.col, t1.col
from parent
-- left -- probably
join @t t1 on len(t1.col) = 14 and t1.col between parent.strt and parent.nxt
order by parent.col, t1.col

答案 1 :(得分:1)

根据描述,我认为这正是你要找的......

IF OBJECT_ID('tempdb..#TestData', 'U') IS NOT NULL 
DROP TABLE #TestData;

CREATE TABLE #TestData (
    SomeValue VARCHAR(20) NOT NULL PRIMARY KEY CLUSTERED
    );
INSERT #TestData (SomeValue) VALUES 
    ('20170426-31974-B.csv'),
    ('20170426-31980.csv'),
    ('20170426-32014.csv'),
    ('20170426-32609.csv'),
    ('20170426-32069-B.csv'),
    ('20170426-32649.csv'),
    ('20170426-32659.csv'),
    ('20170426-32669-B.csv'),
    ('20170426-32849.csv');

-- SELECT * FROM #TestData td;

--==================================

WITH 
    cte_BaseStarts AS (
        SELECT 
            td.SomeValue,
            BaseValue = IIF(RIGHT(td.SomeValue, 5) = 'B.csv', td.SomeValue, NULL)
        FROM 
            #TestData td
        ),
    cte_FillAssocBase AS (
        SELECT 
            bs.SomeValue,
            AssocBaseValue = MAX(bs.BaseValue) OVER (ORDER BY bs.SomeValue ASC)
        FROM 
            cte_BaseStarts bs
        )
SELECT 
    fab.SomeValue,
    fab.AssocBaseValue
FROM 
    cte_FillAssocBase fab
WHERE 
    fab.SomeValue NOT LIKE '%B.csv';