Sql server 使用第二个表中不同值的T-SQL联接查询
我知道这个问题听起来像是重复的,但我已经把我能找到的每一个问题都考虑过了;虽然这仍然有可能是一个重复的问题,我可能错过了 我有一个表面上看起来微不足道的要求,但无论我如何编写脚本,总有一些警告是行不通的。我尝试了Sql server 使用第二个表中不同值的T-SQL联接查询,sql-server,tsql,sql-server-2016,Sql Server,Tsql,Sql Server 2016,我知道这个问题听起来像是重复的,但我已经把我能找到的每一个问题都考虑过了;虽然这仍然有可能是一个重复的问题,我可能错过了 我有一个表面上看起来微不足道的要求,但无论我如何编写脚本,总有一些警告是行不通的。我尝试了组,独立,加入,聚合函数等 情景: PRIMARYTABLE包含一组活动,SECONDARYTABLE包含活动运行的日期。每个活动可以有多个运行,我为每个运行添加了一个子项 要求: 我需要能够将最近运行的活动放入列表中,以便用户可以更轻松地从运行最频繁的活动中进行选择 PRIMARYTA
组
,独立
,加入
,聚合函数等
情景:
PRIMARYTABLE
包含一组活动,SECONDARYTABLE
包含活动运行的日期。每个活动可以有多个运行,我为每个运行添加了一个子项
要求:
我需要能够将最近运行的活动放入列表中,以便用户可以更轻松地从运行最频繁的活动中进行选择
PRIMARYTABLE
KEYCOLUMN INFOCOLUMN
100000 Test 1
100001 Test Campaign
100002 Test Image 2
100003 Test Img
100004 Image Test
100005 Test
100006 Test Image 3
100007 Test Image 4
100008 Test Image 5
100009 Image Comparison Test 2
100010 Testing
100011 Test Fields
100012 Test 5
100013 test
SECONDARYTABLE
KEYCOLUMN SUBKEY DATECOLUMN
100000 100000 2017-06-02 04:09:57.593
100001 100001 2017-06-19 12:09:54.093
100001 100002 2017-06-27 10:51:14.140
100004 100003 2017-06-27 12:33:47.747
100006 100004 2017-06-28 10:29:53.387
100007 100005 2017-06-28 10:36:23.710
100008 100006 2017-06-29 22:31:03.790
100009 100007 2017-06-29 23:07:52.870
100009 100010 2017-10-04 16:05:40.583
100009 100011 2017-10-04 16:09:55.470
100011 100008 2017-09-08 14:02:28.017
100012 100009 2017-09-11 16:17:23.870
100013 100012 2017-11-07 16:55:55.403
100013 100013 2017-11-08 15:37:16.430
下面是一个或多或少的想法,我在追求什么
SELECT DISTINCT( a.[INFOCOLUMN] )
FROM [PRIMARYTABLE] a
INNER JOIN [SECONDARYTABLE] b ON ( a.[KEYCOLUMN] = b.[KEYCOLUMN] )
ORDER BY a.[DATECOLUMN]
希望在我看到应该怎么做的时候,能有一个荷马·辛普森的“Doh!”时刻
非常感谢。您可以尝试以下方法:
DECLARE @PRIMARYTABLE TABLE
(
[KEYCOLUMN] INT
,[INFOCOLUMN] VARCHAR(24)
);
DECLARE @SECONDARYTABLE TABLE
(
[KEYCOLUMN] INT
,[SUBKEY] INT
,[DATECOLUMN] DATETIME2
);
INSERT INTO @PRIMARYTABLE ([KEYCOLUMN], [INFOCOLUMN])
VALUES (100000, 'Test 1')
,(100001, 'Test Campaign')
,(100002, 'Test Image 2')
,(100003, 'Test Img')
,(100004, 'Image Test')
,(100005, 'Test')
,(100006, 'Test Image 3')
,(100007, 'Test Image 4')
,(100008, 'Test Image 5')
,(100009, 'Image Comparison Test 2')
,(100010, 'Testing')
,(100011, 'Test Fields')
,(100012, 'Test 5')
,(100013, 'test');
INSERT INTO @SECONDARYTABLE ([KEYCOLUMN], [SUBKEY], [DATECOLUMN])
VALUES (100000, 100000, '2017-06-02 04:09:57.593')
,(100001, 100001, '2017-06-19 12:09:54.093')
,(100001, 100002, '2017-06-27 10:51:14.140')
,(100004, 100003, '2017-06-27 12:33:47.747')
,(100006, 100004, '2017-06-28 10:29:53.387')
,(100007, 100005, '2017-06-28 10:36:23.710')
,(100008, 100006, '2017-06-29 22:31:03.790')
,(100009, 100007, '2017-06-29 23:07:52.870')
,(100009, 100010, '2017-10-04 16:05:40.583')
,(100009, 100011, '2017-10-04 16:09:55.470')
,(100011, 100008, '2017-09-08 14:02:28.017')
,(100012, 100009, '2017-09-11 16:17:23.870')
,(100013, 100012, '2017-11-07 16:55:55.403')
,(100013, 100013, '2017-11-08 15:37:16.430');
SELECT a.[INFOCOLUMN]
,b.[DATECOLUMN]
FROM @PRIMARYTABLE A
CROSS APPLY
(
SELECT TOP 1 [DATECOLUMN]
FROM @SECONDARYTABLE B
WHERE A.[KEYCOLUMN] = B.[KEYCOLUMN]
ORDER BY [DATECOLUMN] DESC
) b;
它将为您提供每个活动的最后一次执行。然后,您可以按日期或顺序进行筛选,并从最终查询中获得前N名
或者您可以使用行号
:
WITH DataSource AS
(
SELECT A.[INFOCOLUMN]
,B.[DATECOLUMN]
,ROW_NUMBER() OVER (PARTITION BY A.[KEYCOLUMN] ORDER BY B.[KEYCOLUMN]) AS [RowID]
FROM @PRIMARYTABLE A
INNER JOIN @SECONDARYTABLE B
ON A.[KEYCOLUMN] = B.[KEYCOLUMN]
)
SELECT [INFOCOLUMN]
,[DATECOLUMN]
FROM DataSource
WHERE [RowID] = 1;
尝试此操作,它将以最频繁的使用顺序返回活动列表。注意:从不运行的活动不会出现在您的列表中。在这种情况下,您需要执行左连接
SELECT a.[INFOCOLUMN]
FROM [PRIMARYTABLE] a
/* left */ JOIN [SECONDARYTABLE] b ON a.[KEYCOLUMN] = b.[KEYCOLUMN]
group BY a.[infocolumn]
order by max(datecolumn) desc
这是我用来测试它的存根
select 10000 id,'Campain A' cname into #a1 union all
select 10002,'Campain B' union all
select 10004,'Campain C' union all
select 10009,'Campain E'
select 10000 id,'20170101' thedate into #a2 union all
select 10000,'20170102' union all
select 10009,'20170103' union all
select 10002,'20170104' union all
select 10004,'20170105' union all
select 10000,'20170201' union all
select 10000,'20170302' union all
select 10009,'20170403' union all
select 10002,'20170104' union all
select 10004,'20170205' union all
select 10000,'20170101' union all
select 10004,'20170302' union all
select 10000,'20170103' union all
select 10002,'20170404' union all
select 10002,'20170105'
select #a1.cname
from #a1 join #a2 on #a1.id = #a2.id
group by #a1.cname
order by max(thedate) desc
最近运行的活动
>在(…order by…DESC)上使用行号()
运行频率最高的使用count(*)over(分区依据..)
使用窗口函数row_number()over()
和count()over()
可以按“最近”的数据行进行选择,并按“最频繁”排序。请注意,日期的降序导致“最近”=1
select
p.*, s.*
from PRIMARYTABLE p
inner join (
select KEYCOLUMN, SUBKEY, DATECOLUMN
, row_number() over(partition by KEYCOLUMN order by DATECOLUMN DESC) recent
, count(*) over(partition by KEYCOLUMN) frequency
from SECONDARYTABLE
) s on p.KEYCOLUMN = s.KEYCOLUMN and s.recent = 1
order by s.frequency DESC, p.INFOCOLUMN