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