March 2, 2012 at 4:34 am
Hi,
i have below tables with below fields:
TableWO
CreatedBY UpdatedBY
user1 user2
user1 user1
user2 user3
TableData
UpdatedBy DataType[if =1 means Event else Data]
user1 1
user3 2
user3 2
user2 1
user1 1
TableUser
UserID Fisrtname
Lastname
user1 Bill Luther
user2 Charlie Martin
user3 Dean John
Now i wish to have a select query that should display the below columns:
UserID - from TableUser
Fullname - from TableUser
Count of CreatedBy - from TableWO
Count of UpdatedBy - from TableWO
Count of EventUpdated - - from TableData
Count of DataUpdated - - from TableData
any help is really appreciated
Good day ,Bhavtosh
March 2, 2012 at 4:46 am
plase read this:
http://www.sqlservercentral.com/articles/Best+Practices/61537/
March 2, 2012 at 4:52 am
You need to post DDL, sample data and expected results for a tested answer.
Here's a best guess
SELECT u.UserID,
u.Firstname,
COUNT(wcb.CreatedBY) AS CountCreatedBY,
COUNT(wub.UpdatedBY) AS CountUpdatedBY,
COUNT(CASE WHEN d.DataType=1 THEN d.DataType END) AS EventUpdated,
COUNT(CASE WHEN d.DataType<>1 THEN d.DataType END) AS EventDataUpdated
FROM TableUser u
LEFT OUTER JOIN TableWO wcb ON wcb.CreatedBY=u.UserID
LEFT OUTER JOIN TableWO wub ON wub.UpdatedBY=u.UserID
LEFT OUTER JOIN TableData d ON d.UpdatedBy=u.UserID
GROUP BY u.UserID,u.Firstname
____________________________________________________
Deja View - The strange feeling that somewhere, sometime you've optimised this query before
How to get the best help on a forum
http://www.sqlservercentral.com/articles/Best+Practices/61537March 2, 2012 at 4:55 am
Not going to comment on the table design, as I'm sure others will mention that it's not exactly "best".
BEGIN TRAN
SELECT CreatedBY, UpdatedBY
INTO TableWO
FROM (VALUES('user1', 'user2'),('user1', 'user1'),('user2', 'user3'))a(CreatedBY, UpdatedBY)
SELECT UpdatedBy, DataType --[if =1 means Event else Data]
INTO TableData
FROM (VALUES('user1', 1),('user3', 2),('user3', 2),('user2', 1),('user1', 1))a(UpdatedBy, DataType)
SELECT UserID, Fisrtname, Lastname
INTO TableUser
FROM (VALUES('user1', 'Bill', 'Luther'),('user2', 'Charlie', 'Martin'),('user3', 'Dean', 'John'))a(UserID, Fisrtname, Lastname)
--Solution
SELECT UserID, COALESCE(Fisrtname + SPACE(1),'') + COALESCE(Lastname,'') AS Fullname,
countCreated AS [Count of CreatedBy],
countUpdated AS [Count of UpdatedBy],
Ent AS [Count of EventUpdated],
Dta AS [Count of DataUpdated]
FROM TableUser us
LEFT OUTER JOIN (SELECT CreatedBY, COUNT(CreatedBY)
FROM TableWO
GROUP BY CreatedBY) cr(CreatedBY, countCreated) ON us.UserID = cr.CreatedBY
LEFT OUTER JOIN (SELECT UpdatedBY, COUNT(UpdatedBY)
FROM TableWO
GROUP BY UpdatedBY) up(UpdatedBY, countUpdated) ON us.UserID = up.UpdatedBY
LEFT OUTER JOIN (SELECT UpdatedBy,
SUM(CASE WHEN DataType = 1 THEN 1 ELSE 0 END),
SUM(CASE WHEN DataType = 1 THEN 0 ELSE 1 END)
FROM TableData
GROUP BY UpdatedBy) updt(UpdatedBy, Ent, Dta) ON us.UserID = updt.UpdatedBy
ROLLBACK
Returns:
UserID Fullname Count of CreatedBy Count of UpdatedBy Count of EventUpdated Count of DataUpdated
------ -------------- ------------------ ------------------ --------------------- --------------------
user1 Bill Luther 2 1 2 0
user2 Charlie Martin 1 1 1 0
user3 Dean John NULL 1 0 2
March 2, 2012 at 5:17 am
As everyone else I would suggest to read through forum etiquette article by Jeff Moden, link also can be found at the bottom of my signature.
Here I try to show how your case should be present to forum:
-- sample table and data setup:
declare @TableWO table (CreatedBY varchar(20), UpdatedBY varchar(20))
insert @TableWO
values ('user1','user2'),
('user1','user1'),
('user2','user3')
declare @TableData table (UpdatedBy varchar(20), DataType tinyint)
insert @TableData
values ('user1',1),
('user3',2),
('user3',2),
('user2',1),
('user1',1)
declare @TableUser table (UserID varchar(20), Firstname varchar(50), Lastname varchar(50))
insert @TableUser
values ('user1','Bill','Luther'),
('user2','Charlie','Martin'),
('user3','Dean','John')
People can easely cut-&-paste this code to their SSMS and re-create the case setup.
Actully, it also will be much clear if you would not only include the definition of business requirements but also the exact results you expect based on the data you gave. It would help your helpers to validate their solution against your reqs, something like that:
I want results as per:
UserId,FullName,CountCreatedBY,CountUpdatedBY,CountEventUpdated,CountDataUpdated
user1,Bill Luther,2,1,2,0
user2,Charlie Martin,1,1,1,0
user3,Dean John,0,1,0,2
I just have a lot of free time today morning, that why I've proved the above. Usually you would have from me only the link to etiquette article ... 😀
And finally the soultion, using CTE's for a bit clear layout (together with setup, so you can run it straight a way:
declare @TableWO table (CreatedBY varchar(20), UpdatedBY varchar(20))
insert @TableWO
values ('user1','user2'),
('user1','user1'),
('user2','user3')
declare @TableData table (UpdatedBy varchar(20), DataType tinyint)
insert @TableData
values ('user1',1),
('user3',2),
('user3',2),
('user2',1),
('user1',1)
declare @TableUser table (UserID varchar(20), Firstname varchar(50), Lastname varchar(50))
insert @TableUser
values ('user1','Bill','Luther'),
('user2','Charlie','Martin'),
('user3','Dean','John')
;with cte_CountOfCreatedBy
as
(
select CreatedBY, COUNT(*) as CountCreatedBY
from @TableWO
group by CreatedBY
)
, cte_CountOfUpdatedBy
as
(
select UpdatedBy, COUNT(*) as CountUpdatedBy
from @TableWO
group by UpdatedBy
)
, cte_CountOfEventData
as
( select UpdatedBy
,SUM(CASE WHEN isnull(DataType,0) = 1 THEN 1 ELSE 0 END) as CountEventUpdated
,SUM(CASE WHEN isnull(DataType,0) != 1 THEN 1 ELSE 0 END) as CountDataUpdated
from @TableData
group by UpdatedBy
)
select u.UserId
,u.FirstName + ' ' + u.LastName as FullName
,ISNULL(cc.CountCreatedBY, 0) as CountCreatedBY
,ISNULL(cu.CountUpdatedBY, 0) as CountUpdatedBY
,ISNULL(ed.CountEventUpdated, 0) as CountEventUpdated
,ISNULL(ed.CountDataUpdated, 0) as CountDataUpdated
from @TableUser as u
left join cte_CountOfCreatedBy as cc
on cc.CreatedBY = u.UserId
left join cte_CountOfUpdatedBy as cu
on cu.UpdatedBY = u.UserId
left join cte_CountOfEventData as ed
on ed.UpdatedBy = u.UserId
It also worth to mention why the solution by Mark-101232 will not pruduce right counts.
As soon as it can find more than one row per user in any of the tables he LEFT JOINs to, it mulitplies number of row occurances (eg. for all other LEFT JOIN's), you can see it easely by removing counts and grouping from his query:
SELECT u.UserID,
u.Firstname,
--COUNT(wcb.CreatedBY) AS CountCreatedBY,
--COUNT(wub.UpdatedBY) AS CountUpdatedBY,
--COUNT(CASE WHEN d.DataType=1 THEN d.DataType END) AS EventUpdated,
--COUNT(CASE WHEN d.DataType<>1 THEN d.DataType END) AS EventDataUpdated
wcb.CreatedBY,
wub.UpdatedBY,
d.DataType
FROM @TableUser u
LEFT OUTER JOIN @TableWO wcb ON wcb.CreatedBY=u.UserID
LEFT OUTER JOIN @TableWO wub ON wub.UpdatedBY=u.UserID
LEFT OUTER JOIN @TableData d ON d.UpdatedBy=u.UserID
--GROUP BY u.UserID,u.Firstname
You can see that User1 will be found 4 times in wcb.CreatedBY and in wcb.UpdatedBY, when it should be only 2 and 1 respectively.
March 2, 2012 at 6:24 am
Eugene Elutin (3/2/2012)
As everyone else I would suggest to read through forum etiquette article by Jeff Moden, link also can be found at the bottom of my signature.
Here I try to show how your case should be present to forum:
-- sample table and data setup:
declare @TableWO table (CreatedBY varchar(20), UpdatedBY varchar(20))
insert @TableWO
values ('user1','user2'),
('user1','user1'),
('user2','user3')
declare @TableData table (UpdatedBy varchar(20), DataType tinyint)
insert @TableData
values ('user1',1),
('user3',2),
('user3',2),
('user2',1),
('user1',1)
declare @TableUser table (UserID varchar(20), Firstname varchar(50), Lastname varchar(50))
insert @TableUser
values ('user1','Bill','Luther'),
('user2','Charlie','Martin'),
('user3','Dean','John')
People can easely cut-&-paste this code to their SSMS and re-create the case setup.
Actully, it also will be much clear if you would not only include the definition of business requirements but also the exact results you expect based on the data you gave. It would help your helpers to validate their solution against your reqs, something like that:
I want results as per:
UserId,FullName,CountCreatedBY,CountUpdatedBY,CountEventUpdated,CountDataUpdated
user1,Bill Luther,2,1,2,0
user2,Charlie Martin,1,1,1,0
user3,Dean John,0,1,0,2
I just have a lot of free time today morning, that why I've proved the above. Usually you would have from me only the link to etiquette article ... 😀
And finally the soultion, using CTE's for a bit clear layout (together with setup, so you can run it straight a way:
declare @TableWO table (CreatedBY varchar(20), UpdatedBY varchar(20))
insert @TableWO
values ('user1','user2'),
('user1','user1'),
('user2','user3')
declare @TableData table (UpdatedBy varchar(20), DataType tinyint)
insert @TableData
values ('user1',1),
('user3',2),
('user3',2),
('user2',1),
('user1',1)
declare @TableUser table (UserID varchar(20), Firstname varchar(50), Lastname varchar(50))
insert @TableUser
values ('user1','Bill','Luther'),
('user2','Charlie','Martin'),
('user3','Dean','John')
;with cte_CountOfCreatedBy
as
(
select CreatedBY, COUNT(*) as CountCreatedBY
from @TableWO
group by CreatedBY
)
, cte_CountOfUpdatedBy
as
(
select UpdatedBy, COUNT(*) as CountUpdatedBy
from @TableWO
group by UpdatedBy
)
, cte_CountOfEventData
as
( select UpdatedBy
,SUM(CASE WHEN isnull(DataType,0) = 1 THEN 1 ELSE 0 END) as CountEventUpdated
,SUM(CASE WHEN isnull(DataType,0) != 1 THEN 1 ELSE 0 END) as CountDataUpdated
from @TableData
group by UpdatedBy
)
select u.UserId
,u.FirstName + ' ' + u.LastName as FullName
,ISNULL(cc.CountCreatedBY, 0) as CountCreatedBY
,ISNULL(cu.CountUpdatedBY, 0) as CountUpdatedBY
,ISNULL(ed.CountEventUpdated, 0) as CountEventUpdated
,ISNULL(ed.CountDataUpdated, 0) as CountDataUpdated
from @TableUser as u
left join cte_CountOfCreatedBy as cc
on cc.CreatedBY = u.UserId
left join cte_CountOfUpdatedBy as cu
on cu.UpdatedBY = u.UserId
left join cte_CountOfEventData as ed
on ed.UpdatedBy = u.UserId
It also worth to mention why the solution by Mark-101232 will not pruduce right counts.
As soon as it can find more than one row per user in any of the tables he LEFT JOINs to, it mulitplies number of row occurances (eg. for all other LEFT JOIN's), you can see it easely by removing counts and grouping from his query:
SELECT u.UserID,
u.Firstname,
--COUNT(wcb.CreatedBY) AS CountCreatedBY,
--COUNT(wub.UpdatedBY) AS CountUpdatedBY,
--COUNT(CASE WHEN d.DataType=1 THEN d.DataType END) AS EventUpdated,
--COUNT(CASE WHEN d.DataType<>1 THEN d.DataType END) AS EventDataUpdated
wcb.CreatedBY,
wub.UpdatedBY,
d.DataType
FROM @TableUser u
LEFT OUTER JOIN @TableWO wcb ON wcb.CreatedBY=u.UserID
LEFT OUTER JOIN @TableWO wub ON wub.UpdatedBY=u.UserID
LEFT OUTER JOIN @TableData d ON d.UpdatedBy=u.UserID
--GROUP BY u.UserID,u.Firstname
You can see that User1 will be found 4 times in wcb.CreatedBY and in wcb.UpdatedBY, when it should be only 2 and 1 respectively.
Good catch!. If the OP had provided tables with primary keys, things would have been easier
declare @TableWO table (PK int not null primary key, CreatedBY varchar(20), UpdatedBY varchar(20))
insert @TableWO
values (1, 'user1','user2'),
(2, 'user1','user1'),
(3, 'user2','user3')
declare @TableData table (PK int not null primary key, UpdatedBy varchar(20), DataType tinyint)
insert @TableData
values (1,'user1',1),
(2,'user3',2),
(3,'user3',2),
(4,'user2',1),
(5,'user1',1)
declare @TableUser table (UserID varchar(20), Firstname varchar(50), Lastname varchar(50))
insert @TableUser
values ('user1','Bill','Luther'),
('user2','Charlie','Martin'),
('user3','Dean','John')
SELECT u.UserID,
u.Firstname,
u.LastName,
COUNT(DISTINCT wcb.PK) AS CountCreatedBY,
COUNT(DISTINCT wub.PK) AS CountUpdatedBY,
COUNT(DISTINCT CASE WHEN d.DataType=1 THEN d.PK END) AS EventUpdated,
COUNT(DISTINCT CASE WHEN d.DataType<>1 THEN d.PK END) AS EventDataUpdated
FROM @TableUser u
LEFT OUTER JOIN @TableWO wcb ON wcb.CreatedBY=u.UserID
LEFT OUTER JOIN @TableWO wub ON wub.UpdatedBY=u.UserID
LEFT OUTER JOIN @TableData d ON d.UpdatedBy=u.UserID
GROUP BY u.UserID,u.Firstname,u.LastName;
____________________________________________________
Deja View - The strange feeling that somewhere, sometime you've optimised this query before
How to get the best help on a forum
http://www.sqlservercentral.com/articles/Best+Practices/61537March 2, 2012 at 6:50 am
Mark-101232 (3/2/2012)
...Good catch!. If the OP had provided tables with primary keys, things would have been easier
...
Could be easier, but also it may not be the case, depends on real PK's
Also, after reviewing the query again (both my and yours), I've found that it's possible to get rid of the second table scan of TableWO:
;with cte_CountOfCUBy
as
(
select u.UserId
,u.FirstName + ' ' + u.LastName as FullName
,sum(case when w.CreatedBY = u.UserID then 1 else 0 end) CountCreatedBy
,sum(case when w.UpdatedBY = u.UserID then 1 else 0 end) CountUpdatedBy
from @TableUser as u
left join @TableWO as w
on w.CreatedBY = u.UserID or w.UpdatedBY = u.UserId
group by u.UserId, u.FirstName + ' ' + u.LastName
)
, cte_CountOfEventData
as
( select UpdatedBy
,SUM(CASE WHEN isnull(DataType,0) = 1 THEN 1 ELSE 0 END) as CountEventUpdated
,SUM(CASE WHEN isnull(DataType,0) != 1 THEN 1 ELSE 0 END) as CountDataUpdated
from @TableData
group by UpdatedBy
)
select ucc.UserId
,ucc.FullName
,ISNULL(ucc.CountCreatedBY, 0) as CountCreatedBY
,ISNULL(ucc.CountUpdatedBY, 0) as CountUpdatedBY
,ISNULL(ed.CountEventUpdated, 0) as CountEventUpdated
,ISNULL(ed.CountDataUpdated, 0) as CountDataUpdated
from cte_CountOfCUBy as ucc
left join cte_CountOfEventData as ed
on ed.UpdatedBy = ucc.UserId
March 3, 2012 at 11:41 pm
thank you all for quick responses..... the solution is just i was looking for and i will try to be more detailed and clear in my queries in future....
Viewing 8 posts - 1 through 7 (of 7 total)
You must be logged in to reply to this topic. Login to reply