查询两个表以使用select case过滤数据

时间:2016-04-21 17:48:31

标签: sql sql-server join filtering

我有两张桌子 表1看起来像这样

ID  Repeats
-----------
A   1
A   1
A   0
B   2
B   2
C   2
D   1

表2看起来像这样

ID  values
-----------
A   100
B   200
C   100
D   300

使用视图我需要这样的结果

ID  values  Repeats
-------------------
A   100 NA
B   200 2
C   100 2
D   300 1

这意味着,我想要唯一的IDvaluesRepeats。当单Repeats有多个values时,ID值应显示为NA,如果Repeats存在单个值,则应显示repeats值。< / p>

最初我需要显示repeats的最大值,所以我尝试了以下视图

ALTER VIEW [dbo].[BookingView1]
AS
SELECT bv.*, bd2.Repeats FROM Table1 bv 
JOIN
(
    SELECT distinct bd.id, bd.Repeats FROM table2 bd
    JOIN
    (
      SELECT Id, MAX(Repeats) AS MaxRepeatCount
      FROM table2
      GROUP BY Id
    ) bd1
    ON bd.Id = bd1.Id
    AND bd.Repeats = bd1.MaxRepeatCount
) bd2
ON bv.Id = bd2.Id;

这会返回正确的结果,但在尝试实施CASE时,它无法返回唯一的ID结果。请帮忙!!

2 个答案:

答案 0 :(得分:1)

一种方法使用outer apply

select t2.*, t1.repeats
from table2 t2 outer apply
     (select (case when max(repeats) = min(repeats) then max(repeats)
                   else 'NA'
              end) as repeats
      from table1 t1
      where t1.id = t2.id
     ) t1;

两个注释:

  • 这假定repeats是一个字符串。如果是数字,则需要将其强制转换为字符串。
  • repeats不为空。

答案 1 :(得分:0)

为了完整起见,我将包括另一种方法,如果repeatsNULL,该方法将有效。但是,Gordon's回答有一个更简单的查询计划,应该是首选。

选项1 (适用于NULL s):

SELECT 
    t1.ID, t2.[Values], 
    CASE 
        WHEN COUNT(*) > 1 THEN 'NA' 
        ELSE CAST(MAX(Repeats) AS VARCHAR(2)) 
    END Repeats
FROM (
        SELECT DISTINCT t1.ID, t1.Repeats
        FROM #table1 t1
    ) t1 
    LEFT OUTER JOIN #table2 t2
    ON t1.ID = t2.ID
GROUP BY t1.ID, t2.[Values]

选项2 (不包含显式子查询,但不适用于NULL):

SELECT DISTINCT 
    t1.ID, 
    t2.[Values], 
    CASE 
        WHEN COUNT(t1.Repeats) OVER (PARTITION BY COUNT(DISTINCT t1.Repeats), t1.ID) > 1 THEN 'NA' 
        ELSE CAST(t1.Repeats AS VARCHAR(2)) 
    END Repeats
FROM #table1 t1
    LEFT OUTER JOIN #table2 t2
    ON t1.ID = t2.ID
GROUP BY t1.ID, t2.[Values], t1.Repeats

注意: 如果table2对同一values的{​​{1}}不同,则可能无法获得预期效果。