我正在使用 SQL-Server 2008 。我需要将行与相同的Name
组合在一起,并在以下情况下增加计数器:
Id's
的{{1}} Name
为blank
Id
为NULL
,则不合并行Name
但不同的Ids
现在输出:
Name Id Cnt
John 1 1
Peter 2 2 -- This Peter with the same Id have 2 entries so Cnt = 2
Peter 3 1 -- This is other Peter with 1 entry so Cnt = 1
Lisa 4 1
Lisa NULL 1
David 5 1
David 1 -- here Id is blank ''
Ralph 2 -- Ralph have both rows with blank Id so Cnt = 2
期望的输出:
Name Id Cnt
John 1 1
Peter 2 2
Peter 3 1
Lisa 4 1
Lisa NULL 1 -- null still here
David 5 2 -- merged with blank '' so Cnt = 2
Ralph 2 -- merged both blanks '' so Cnt = 2
SQL-Query:
这是我现在正在使用的示例查询:
SELECT Name,
Id,
COUNT(Id) AS Cnt
FROM Employees
WHERE Condition = 1
GROUP BY Name, Id
我尝试了什么:
在MAX
子句中向Id
添加了汇总SELECT
,仅按Name
分组,但在这种情况下,合并的行具有NULL
值并且具有相同的值不同Id's
的名字对我来说有什么不对。
SELECT Name,
MAX(Id), -- added aggregate
COUNT(Id) AS Cnt
FROM Employees
WHERE Condition = 1
GROUP BY Name -- grouped by Name only
你有什么想法吗?如果对问题一无所知 - 请问我,我会提供更多细节。
更新
DDL
CREATE TABLE Employees
(
Name NVARCHAR(40),
Id NVARCHAR(40)
);
DML
INSERT INTO Employees VALUES
('John' , '1')
,('Peter', '2')
,('Peter', '2')
,('Peter', '3')
,('Lisa' , '4')
,('Lisa' , NULL)
,('David', '5')
,('David', '')
,('Ralph', '')
,('Ralph', '')
DEMO: this link
答案 0 :(得分:1)
您可以在$(document).on('mouseup', '.m1', function(){
alert('div mouseup ');
});
$(document).on('click', 'ul li', function(){
alert("ul li- clicked");
});
内使用CASE
声明。它允许您为员工空白时设置Id = [some value]。查询可以是这样的:
SELECT
答案 1 :(得分:1)
修改强>
DECLARE @Data table (Name varchar(10), Id varchar(10)) -- Id must be varchar for blank value
INSERT @Data VALUES
('John', '1'),
('Peter', '2'),('Peter', '2'),
('Peter', '3'),--('Peter', ''), --For test
('Lisa', '4'),
('Lisa', NULL),
('David', '5'),
('David', ''),
('Ralph', ''), ('Ralph', '')
SELECT
Name,
Id,
COUNT(*) + ISNULL(
(SELECT COUNT(*) FROM @data WHERE Name = d.Name AND Id = '' AND d.Id <> '')
, 0) AS Cnt
FROM @data d
WHERE
Id IS NULL
OR Id <> ''
OR NOT EXISTS(SELECT * FROM @data WHERE Name = d.Name AND Id <> '')
GROUP BY Name, Id
答案 2 :(得分:1)
具有窗口功能的版本:
SELECT Name,ID, Cnt from
( select *, sum(1-AmtBlank) over (partition by Name, ID) + sum(case id when 0 then 1 else 0 end) over (partition by Name) Cnt,
rank() over (partition by Name order by AmtBlank ) rnk,
row_number() over (partition by Name, ID order by AmtBlank) rnr
FROM (select * , case id when '' then 1 else 0 end AmtBlank from Employees /*WHERE Condition = 1*/ ) e
) c where rnr=1 and rnk = 1
这使用case id when '' then 1 else 0 end AmtBlank
来保留每行空白金额(使非空白1-AmtBlank的金额)和2个窗口函数的金额,一个id为每个名称和id的计数({{1 }和)名称部分中所有空格的计数(sum(1-AmtBlank) over (partition by Name, ID)
)
sum(case id when 0 then 1 else 0 end) over (partition by Name)
用于随后仅获取组的第一行,而row_number
仅用于在没有id的记录时包含空白记录。
答案 3 :(得分:0)
试试这个。使用cte和join
;with cte as (
SELECT Name,
Id,
COUNT(*) AS Cnt
FROM Employees
WHERE isnull(Id,1)<>''
GROUP BY Name, Id
),
cte2 as (SELECT Name,id, COUNT(*) AS Cnt FROM Employees WHERE Id='' GROUP BY Name,id)
select cte.Name,cte.Id,(cte.cnt + ISNULL(cte2.Cnt,0)) as cnt
from cte
left JOIN cte2
on cte.Name = cte2.Name
union all
select cte2.Name,cte2.Id,cte2.cnt
from cte2
left JOIN cte
on cte.Name = cte2.Name
where cte.Name is null
答案 4 :(得分:0)
这个简单的语法与旧版本或其他RDBMS兼容
- 自我解释评论
的编辑:强>
select name, id, count(*) from (
-- adds "normal" records
select name, id from Employees where id is null or id <> ''
-- adds one record to each name-notBlankId for each blank id (David, Peter if you add 'Peter','')
-- uncomment /*or id is null*/ if you want even null ids to recieve merged blanks
union all
select e1.name, e1.id
from (select distinct name, id from Employees where id <> '' /*or id is null*/ ) as e1
inner join (select name, id from Employees where id = '') as e2 on e1.name = e2.name
-- adds records that can't be merged (Ralph)
union all
select name, id from Employees e1
where e1.id = ''
and not exists(select * from Employees e2 where e1.name = e2.name and e2.id <> '')
) as fullrecords
group by name, id
答案 5 :(得分:0)
你可以尝试这样的事情。
;WITH NonBlanks AS
(
SELECT Name,
Id,
COUNT(ISNULL(Id, 1)) AS Cnt
FROM Employees
WHERE ISNULL(Id,0) <> ''
GROUP BY Name, Id
)
,Blanks AS
(
SELECT Name,
Id,
COUNT(ISNULL(Id, 1)) AS Cnt
FROM Employees
WHERE ID = ''
GROUP BY Name, Id
)
SELECT CASE WHEN nb.NAME IS NULL THEN b.NAME ELSE nb.NAME END NAME,
CASE WHEN nb.NAME IS NULL THEN b.Id ELSE nb.Id END Id,
(ISNULL(nb.Cnt,0) + ISNULL(b.Cnt,0)) Cnt
FROM NonBlanks nb FULL JOIN Blanks b
ON nb.Name = b.Name