SQL Select Count Statement - sql-server

I have two tables, one for Employees and the second for records. I want to get total entries for each employee and order the results by max total entry like:
Daniel 3
David 1
tblEmployee:
EID Name
1 Daniel
2 David
tblEntry:
ID Column1 EID
1 XX 1
2 XX 1
3 XX 2
4 XX 1

try this:
select emp.EID,emp.Name,COUNT(etr.EID)
as total_entries from Employee emp join Entry etr
on emp.EID=etr.EID
group by emp.EID,emp.Name

You must use group by
select count(*) from tblEmployee ee, tblEntry e where ee.eid = e.eid group by ee.name

There are several variations on this, and you don't say what version of SQL Server you're using, but I like doing it this way:
;
using A
as (
select EID
, RecordCount = COUNT(*)
from tblEntry
group by
EID
)
select a.EID
, e.Name
, a.RecordCount
from A
join tblEmployee e
on A.EID = e.EID
order by
RecordCount desc
I like doing it this way rather than joining and then summarizing because you only have to group on the minimum number of fields. EID in tblEntry is likely to already have an index on it, while Name in tblEmployee may not.

Related

Select mismatch column values from database

I want to select and fetch all mismatch value of two table having same Column Name But Id, Name and City are different. I am Using Sql Server Management Studio
Table A:
id Name City
1 John karachi
2 smith Capetown
3 liza Washington
Table B:
id Name City
7 Grey Dubai
8 Clarke Texas
9 liza Washington
OUTPUT:
7 Grey Dubai
8 Clarke Texas
This has been answered hundreds and hundreds of times. Not quite sure what you mean by "having same Column Name But Id, Name and City are different" but here are a couple of example of how you can do this.
You can use a left join where tablea is null,
select b.Name
, b.City
from tableb b
left join tablea a on a.name = b.name
and a.city = b.city
where a.name is null
You can use except.
select Name
, City
from tableb
except
select Name
, City
from tablea
You can try the below query. Assuming that the id column is never null
select tb.*
from tableB tb
left join tableA ta
on tb.Name=ta.Name and tb.City=ta.City
where ta.id is NULL
Link to demo sql fiddle: http://sqlfiddle.com/#!3/250e5/1

Rows where value in column A occurs > 1 but the corresponding value in column B doesn't

I have a table like this:
SchoolName|SchoolID
--------------------
School A |x
School B |x
School C |y
School D |z
School D |z
There are actually more columns, including a unique ID. The above is just for brevity.
What I need to do is select all columns, where the SchoolID occurs more than once, but only if the corresponding value in the SchoolName column doesn't.
So I'd like get all columns for the rows with School A and School B, but not the School C and School D rows.
The db is MS SQL 2008 R2.
The original question was terribly confused, hopefully I've managed to rephrase it correctly now!
You can use window version of COUNT to count SchoolID and SchoolName occurences:
SELECT *
FROM (
SELECT *,
COUNT(*) OVER (PARTITION BY SchoolID) AS cntSchoolID,
COUNT(*) OVER (PARTITION BY SchoolID, SchoolName) AS cntSchoolName
FROM mytable ) t
WHERE t.cntSchoolID > 1 AND t.cntSchoolName = 1
SQL Fiddle Demo
So do you want something like this?
SELECT A.*
FROM yourTable A
CROSS APPLY (
SELECT TOP 1 NULL col
FROM yourTable
WHERE A.SchoolID = SchoolID
AND A.SchoolName = SchoolName
GROUP BY SchoolID,SchoolName
HAVING COUNT(*) > 1
) CA
I would build a list of all the schoolnames that repeat, and all the schoolids that repeat, and then pull all of the rows where the schoolname or the schoolid match:
select
*
from
mytable
where
(schoolname in
(
select schoolname
from
mytable
group by schoolname
having count (*) > 1)
OR
schoolid in
(
select
schoolid
from
mytable
group by schoolid
having count (*) > 1)
)
Ugly, but I think it gives you your desired result.
SQL Fiddle

how to do a FOR EACH loop in T-Sql using join?

I have a table PRODUCT that is basically set up so there is an PRODUCTID, PRODUCTNAME... it looks sort of like this
PRODUCTID PRODUCTNAME
100 PNAME1
101 PNAME2
102 PNAME3
Now I have to insert a record into new table PRODUCTMAPPING for each row in the PRODUCT.
so my new table PRODUCTMAPPING should look like this
PRODUCTMAPPINGID PRODUCTID
1 100
1 101
1 102
2 100
2 101
2 102
3 100
and so on ....
I tried doing while but I need it using Join.
Can we acheive this using joins ?
Thanks in advance.
One way;
select
row_number() over(partition by a.PRODUCTID order by a.PRODUCTID) PRODUCTMAPPINGID,
a.PRODUCTID
from PRODUCT a, PRODUCT b
Using LOOP
The following example specifies that the JOIN operation in the query is performed by a LOOP join.
Select sp.Name,spqh.quota
FROM Sales.SalesPersonQuotaHistory AS spqh
INNER LOOP JOIN Sales.SalesPerson AS sp
ON spqh.SalesPersonID = sp.SalesPersonID
WHERE sp.SalesYTD > 2500000.00;
GO
Refer this MSDN link
INSERT
INTO dbo.PRODUCTMAPPING
(
PRODUCTMAPPINGID
,PRODUCTID
)
SELECT pmv.PRODUCTMAPPINGID
,p.PRODUCTID
FROM dbo.Product p
CROSS JOIN
(
SELECT pm.ProductMappingID
FROM dbo.ProductMappingValues pmv -- WHERE DO THESE COME FROM?
) pmv

SQL Server Finding Duplicates

Say I have a table as follows
Employee RecNumber
Joe Bloggs 123456
Joe Bloggs 123456
Bob Bloggs 123457
Dup Bloggs 123456
And I just want to return all Rec Numbers where 2 People have had the same RecNumber which shouldn't happen.
Note that one person can have same request number multiple times I just want returned where 2 people have the same rec Number
So all I want returned is
123456
select record_number
from my_table
group by record_number
having count(distinct employee) > 1
SELECT A.RECNUMBER,COUNT(B.EMPLOYEE)
(SELECT DISTINCT RECNUMBER FROM YOURTABLE) A,
YOURTABLE B
WHERE A.RECNUMBER = B.RECNUMBER
GROUP BY A.RECNUMBER
HAVING COUNT(B.EMPLOYEE)=2;
Something like this?
SELECT RecNumber FROM Table GROUP BY RecNumber HAVING COUNT(*) > 1
SELECT RecNumber FROM [a table]
GROUP BY RecNumber HAVING COUNT(*) > 1;
Or perhaps
SELECT RecNumber FROM (SELECT RecNumber, Employee
FROM [a table]
GROUP BY RecNumber, Employee HAVING COUNT(*) > 1
) AS x;
You can write something like that, i think it's working :
use *DATABASE_NAME*
go
select *Your_Field*, Nbre=count(*Your_Field*) from *TABLE_NAME*
group by *Your_Field*
having count(*Your_Field*)>1
order by 2 desc
Enjoy

Query to collect data from previous rows

I have a table with records as, in example data below a CO.Nr are TH-123,Th-456 and so on... I need to collect the data..
Nr. CO.Nr Employee Resp Description Date
1 TH-123 ABC NULL HELLO 10.05.2010
2 TH-123 NULL S14 NULL 18.05.2010
3 TH-123 DEF NULL 13.05.2010
4 TH-456 XYZ NULL NULL 1.07.2010
5 TH-456 NULL S19 SOME NULL
6 TH-456 TEXT 08.05.2010
7 TH-456 NULL 28.05.2010
For TH-123,
If Nr. is maximum, that is the record i need to start with group by CO.Nr, so it is the record with Nr as 3,
if the value in the other columns is NULL or space, go to a record above that is the record with Nr as 2, even if it has null value go to a record above that record with Nr. as 1 in this case.
In the 3 records i need to take the maximum of date.
For the above data, i need to have output as,
CO.Nr Employee Resp Description Date
TH-123 DEF S14 HELLO 18.05.2010
TH-456 XYZ S19 TEXT 01.07.2010
Thanks in advance!
You can do it many ways
select [co.nr],
(select top(1) employee from mytable b where b.[co.nr]=a.[co.nr] and
employee is not null order by nr desc) as employee,
(select top(1) resp from mytable b where b.[co.nr]=a.[co.nr] and
resp is not null order by nr desc) as resp,
(select top(1) description from mytable b where b.[co.nr]=a.[co.nr] and
description is not null order by nr desc) as description,
(select max([date]) from mytable b where b.[co.nr]=a.[co.nr]) as Date
from (
select distinct [co.nr]
from mytable ) as a
You can use a subselect to choose the record you want, then join on that. Something like the following for the employees one (I'll leave the rest of the columns as an exercise):
SELECT MyTable.[CO.Nr], Employees.Employee
FROM MyTable
LEFT OUTER JOIN (SELECT FIRST(Employee) as Employee, [CO.Nr]
FROM MyTable
WHERE Employee IS NOT NULL AND Employee <> ''
GROUP BY [CO.Nr]
ORDER BY [Nr.] DESC) Employees
ON MyTable.[CO.Nr] = Employees.[CO.Nr]
GROUP BY MyTable.[CO.Nr]
Or, if FIRST() is not a valid aggregate function, as mentioned in your comments, you can try subselects in your SELECT clause, like:
SELECT t.MyTable.[CO.Nr],
(SELECT TOP(1) x.Employee
FROM MyTable x
WHERE x.[CO.Nr] = t.[CO.Nr]
AND x.Employee IS NOT NULL AND x.Employee <> ''
ORDER BY [Nr.] DESC) as Employee
FROM MyTable t
GROUP BY t.[CO.Nr]

Resources