How to create identity column in SQL Server using with statement - sql-server

I am looking for some help in SQL, I am using following query
with t AS
(
select
EmpID, mgrid, HierarchyLevel, Description
from
empdatatest
)
select *
from t
order by empid
I want a way so that table T has an identity column
Data output should be like
ID EmpID mgrid HierarchyLevel Description
------------------------------------------
1 201 7 1 Partner
2 202 201 2 Senior Manager
3 221 202 3 Manager
4 343 221 4 employee
5 534 221 4 employee
6 552 221 4 employee

Use ROW_NUMBER():
;With t As
(
Select Row_Number() Over (Order By EmpId) As ID,
EmpID,
mgrid,
HierarchyLevel,
Description
From empdatatest
)
Select *
From t
Order By empid;

Related

SQL server select statement to select the ids of a duplicated entries of another column

Consider the table 'Table1' as below
main_id main_item_id
-------- ---------
1 101
1 102
2 105
2 105
3 105
3 106
4 101
4 101
4 102
I need to fetch main_id 2 and 4 as it has duplicate main_item_id among 1 million other records
Thanks in advance.
This will select all unique main_id's which have 2 or more identical main_item_id's:
SELECT DISTINCT T.main_id
FROM YourTable T
GROUP BY T.main_id
, T.Main_item_id
HAVING COUNT(1) > 1
Use group by clause to check the duplication
SELECT main_id, main_item_id
FROM table
GROUP BY main_id, main_item_id
HAVING count(*) > 1

How to select specific records of groups based on criteria

I'm trying to group a set of data and for some of the fields I need to select a specific value based on the ttype, for example I have the following rows:
caseid age iss gcs ttype
00170 64 25 17 Transfer Out
00170 64 27 15 Transfer In
00201 24 14 40 Transfer In
If a caseID has ttype 'Transfer Out' I want to use the ISS and GCS values from this row, otherwise use the values from the 'Transfer In' row.
My desired output based on the above example would be:
caseid age iss gcs
00170 64 25 17
00201 24 14 40
My current select statement is:
select caseid, max(age), max(iss), max(gcs)
from Table1
group by caseid
Which I know is incorrect but how do I specify the values for ISS and GCS from a specific row?
Thanks
Edit - I will not always need to select from Row1, table below with expanded data:
caseid age iss gcs los ttype disdate
170 64 25 17 5 Transfer Out 2014-01-02 00:00:00.000
170 64 27 15 1 Transfer In 2014-01-04 00:00:00.000
201 24 14 40 4 Transfer In 2014-01-04 00:00:00.000
In this case, I want the max age and the ISS and GCS figure for row1 as before but I need to sum the LOS and select the disdate for row 2 (ie the latest date), so my output would be:
caseid age iss gcs los disdate
170 64 25 17 6 2014-01-04
201 24 14 40 4 2014-01-04
Is this possible?
You can use a CTE and ROW_NUMBER + Over-clause (edited acc. to your updated question):
WITH CTE AS
(
SELECT caseid, age, iss, gcs, los, ttype, disdate,
SumLos = SUM(los) OVER (PARTITION BY caseid),
LatestDisDate = MAX(disdate) OVER (PARTITION BY caseid),
rn = ROW_NUMBER() OVER (PARTITION BY caseid
ORDER BY CASE WHEN ttype = 'Transfer Out'
THEN 0 ELSE 1 END ASC, disdate ASC)
FROM dbo.Table1
)
SELECT caseid, age, iss, gcs, los = SumLos, disdate = LatestDisDate
FROM CTE
WHERE rn = 1
Demo
I think this is what you need -
;WITH CTE AS
(
SELECT case_id, age,iss,gcs, ROW_NUMBER () over (PARTITION BY ttype order by gcs DESC) Rn
from YOUR_TABLE_NAME
)
SELECT case_id,age,iss,gcs
from CTE where Rn =1

Removing Duplicates of two columns in a query

I have a select * query which gives lots of row and lots of columns of results. I have an issue with duplicates of one column A when given the same value of another column B that I would like to only include one of.
Basically I have a column that tells me the "name" of object and another that tells me the "number". Sometimes I have an object "name" with more than one entry for a given object "number". I only want distinct "numbers" within a "name" but I want the query to give the entire table when this is true and not just these two columns.
Name Number ColumnC ColumnD
Bob 1 93 12
Bob 2 432 546
Bob 3 443 76
This example above is fine
Name Number ColumnC ColumnD
Bob 1 93 12
Bob 2 432 546
Bill 1 443 76
Bill 2 54 1856
This example above is fine
Name Number ColumnC ColumnD
Bob 1 93 12
Bob 2 432 546
Bob 2 209 17
This example above is not fine, I only want one of the Bob 2's.
Try it if you are using SQL 2005 or above:
With ranked_records AS
(
select *,
ROW_NUMBER() OVER(Partition By name, number Order By name) [ranked]
from MyTable
)
select * from ranked_records
where ranked = 1
If you just want the Name and number, then
SELECT DISTINCT Name, Number FROM Table1
If you want to know how many of each there are, then
SELECT Name, Number, COUNT(*) FROM Table1 GROUP BY Name, Number
By using a Common Table Expression (CTE) and the ROW_NUMBER OVER PARTION syntax as follows:
WITH
CTE AS
(
SELECT
*,
ROW_NUMBER() OVER (PARTITION BY Name, Number ORDER BY Name, Number) AS R
FROM
dbo.ATable
)
SELECT
*
FROM
CTE
WHERE
R = 1
WITH
CTE AS
(
SELECT
*,
ROW_NUMBER() OVER (PARTITION BY Plant, BatchNumber ORDER BY Plant, BatchNumber) AS R
FROM dbo.StatisticalReports WHERE dbo.StatisticalReports. \!"FermBatchStartTime\!" >= DATEADD(d,-90, getdate())
)
SELECT
*
FROM
CTE
WHERE
R = 1
ORDER BY dbo.StatisticalReports.Plant, dbo.StatisticalReports.FermBatchStartTime

SQL Statement to get Unique vales and its count

I have data in table as below:
Database is SQL Server
TABLE Name: Employee
Emp_ID EMP_name Emp_Grade
101 Siddu B
102 harsha A
103 Patty B
104 Preeti A
105 Aarna C
Can some one please help me to get out as below?
Emp_Grade Count
B 2
A 2
C 1
Select Emp_Grade, Count(*) As [Count]
From Employee
Group by Emp_Grade
If you need the exact order then add
Order by [Count] desc, Emp_Grade desc

group by clause query

i have a table with values like this,
i want to group by cusotmer name where as sum of the local amount should exceed 50000 else i need to delete those records which do not satisfy?
how to achieve it in sql server 2005?
TRN 259 3 9/9/2010 6622 68667(Rs) ABHIJIT KATARE
TRN 260 3 9/9/2010 6622 14635(Rs) ABHIJIT KATARE
TRN 235 3 9/9/2010 6586 68128 AJAY PARASRAMPURIA
TRN 236 3 9/9/2010 6586 14490 AJAY PARASRAMPURIA
TRN 257 3 9/9/2010 6621 68667 ANAND DESAI
TRN 258 3 9/9/2010 6621 14635 ANAND DESAI
TRN 287 3 9/9/2010 6817 119095 ANAND KATAKAM
TRN 242 3 9/9/2010 6594 95689 ANILKUMAR MUTHUNPARA
TRN 211 3 9/9/2010 6507 52239 ARBIND KUMAR GUPTA
TRN 212 3 9/9/2010 6538 63183 ASHOK KELKAR
TRN 185 3 9/9/2010 6431 140610 BANSAL Y.K
TRN 186 3 9/9/2010 6431 46845 BANSAL Y.K
TRN 248 3 9/9/2010 6600 72565 BENNO HANS LUKE
Try this for the select:
SELECT * FROM Table
GROUP BY CustomerName
HAVING SUM(LocalAmount) > 50000
Try this for delete (modified version of #RedFilter's):
delete from MyTable
where CustomerName in (
select CustomerName
from Table
group by CustomerName
having sum(LocalAmount) <= 50000
)
select * from MyTable group by CustomerName having sum(LocalAmount) > 50000
to see the good rows use:
SELECT
cusotmerName ,SUM(localAmount)
FROM YourTable
GROUP BY cusotmerName
HAVING SUM(localAmount)>50000
to delete the bad rows use:
DELETE YourTable
WHERE
CustomerName IN (SELECT
cusotmerName
FROM YourTable
GROUP BY cusotmerName
HAVING SUM(localAmount)<50000
)
This will show you the customers that have less than 50000:
select CustomerName, sum(LocalAmount)
from MyTable
group by CustomerName
having sum(LocalAmount) <= 50000
Note that you are better off grouping by CustomerID if there is one, as there could be duplicate names. Then, you can delete by doing this:
delete from MyTable
where CustomerID in (
select CustomerID
from MyTable
group by CustomerID
having sum(LocalAmount) <= 50000
)
this syntax looks a bit weird but it works!
;with cte as
(
select sum(LocalAmount) over (partition by cname) s
from yourtable
)
delete from cte where s <= 50000

Resources