如何将第一行与下面的N相比较

时间:2019-01-24 10:55:05

标签: sql sql-server tsql

我们如何比较第一行和下面几行。 我有示例数据

tbl_Name    Emp_cnt
Emp1         20
Emp1         20
Emp1         20
Emp2         22
Emp2         21
Emp2         20

如何与下面的员工姓名行进行比较。如果下面的行重复,则需要显示“ Y”条件,否则需要“ N”条件。

输出:

tbl_Name    Emp_cnt condition
Emp1         20          Y
Emp1         20
Emp1         20
Emp2         22          N
Emp2         21
Emp2         20

请问您可以提出建议吗?

3 个答案:

答案 0 :(得分:0)

您可以将last -n "$1" $(whoami) 表达式与case一起使用:

exists

答案 1 :(得分:0)

我的建议将通过整洁的分组绕过随机排序顺序的问题:

DECLARE @mockup TABLE (EmpName VARCHAR(50), Emp_cnt INT)
INSERT INTO @mockup VALUES
('Emp1', 20),
('Emp1', 20),
('Emp1', 20),
('Emp2', 22),
('Emp2', 21),
('Emp2', 20);

-该查询将仅向每位员工返回一行,其中YN取决于Emp_cnt中仅存在一个或多个值:

SELECT EmpName
      ,CASE COUNT(DISTINCT Emp_cnt) WHEN 1 THEN 'Y' ELSE 'N' END AS condition 
FROM @mockup 
GROUP BY EmpName;

结果;

EmpName condition
Emp1    Y
Emp2    N

更新

正如您已经被告知的那样,在没有显式排序顺序的情况下,第一行没有任何意义。因此,您需要的输出是随机的。

那呢:

SELECT m1.EmpName
      ,CASE COUNT(DISTINCT m1.Emp_cnt) WHEN 1 THEN 'Y' ELSE 'N' END AS condition 
      ,STUFF(
        (SELECT CONCAT(', ',Emp_cnt ) FROM @mockup m2 WHERE m1.EmpName=m2.EmpName GROUP BY Emp_cnt FOR XML PATH('')),1,2,'') AS Cnt_Values
FROM @mockup m1
GROUP BY m1.EmpName

结果:

EmpName condition   Cnt_Values
Emp1    Y           20
Emp2    N           20, 21, 22

更新2

这似乎是您所需要的,但要警告:从我的角度来看,这是-从技术上讲-一种非常糟糕的方法:

SELECT m1.EmpName
      ,m1.Emp_cnt
      ,CASE WHEN ROW_NUMBER() OVER(PARTITION BY EmpName ORDER BY Emp_cnt) = 1 
            THEN (SELECT CASE WHEN COUNT(DISTINCT Emp_cnt)=1 THEN 'Y' ELSE 'N' END FROM @mockup AS m2 WHERE m2.EmpName=m1.EmpName ) 
            ELSE ''  END AS condition   
FROM @mockup m1;

答案 2 :(得分:0)

这可以通过常见表表达式中的某些窗口函数根据您的问题来完成,尽管我一生都无法弄清楚为什么要这么做...

如果EmpName有一些重复的值但不是全部,那么您要做什么就模棱两可了,当前将其视为N条件,而不是“下面的所有行”是重复项:

declare @t table (EmpName varchar(50), Emp_cnt int);
insert into @t values('Emp1', 20),('Emp1', 20),('Emp1', 20),('Emp2', 22),('Emp2', 21),('Emp2', 20),('Emp3', 21),('Emp3', 21),('Emp3', 20);

with r as
(
    select EmpName
            ,Emp_cnt
            ,row_number() over (partition by EmpName order by Emp_cnt) as rne
            ,count(EmpName)  over (partition by EmpName, Emp_cnt order by Emp_cnt) as c
    from @t
)
,rg as
(
    select *
        ,row_number() over (order by EmpName, rne) as rn
    from r
)
select EmpName
        ,Emp_cnt
        ,case when rne = 1 and c = 3
                then 'Y'
            when rne = 1 and c = 1
                then 'N'
            else ''
            end as condition
from rg;

输出

+---------+---------+-----------+
| EmpName | Emp_cnt | condition |
+---------+---------+-----------+
| Emp1    |      20 | Y         |
| Emp1    |      20 |           |
| Emp1    |      20 |           |
| Emp2    |      20 | N         |
| Emp2    |      21 |           |
| Emp2    |      22 |           |
| Emp3    |      20 | N         |
| Emp3    |      21 |           |
| Emp3    |      21 |           |
+---------+---------+-----------+