Select with Inner Join with Multipart Identifier and Having Clause - inner-join

I need to select certain fields for a multipart identifier that has duplicates.
I have the query to grab the duplicates correct.
SELECT b.MemEmpID, b.LastName, b.FirstName
FROM table1 As b
GROUP BY b.MemEmpID, b.LastName, b.FirstName
HAVING Count(*) > 1
But after finding the duplicates, I need to grab more information from the same table but only for the multipart identifier that has duplicates. So something like the following.
Can someone please help me with the correct syntax for this?
SELECT a.memempid, a.depkey, a.lastname, a.firstname, a.birthdate, a.memrelation
FROM table1 As a
INNER JOIN(SELECT b.MemEmpID, b.LastName, b.FirstName
FROM table1 As b
GROUP BY b.MemEmpID, b.LastName, b.FirstName
HAVING Count(*) > 1)
ON b.memempid = a.memempid
AND b.lastname = a.lastname
AND b.firstname = a.firstname

You were really close. You need to alias the subquery.
table1 As b looses it's scope with the grouping () so you need to alias the parenthesized subquery. You could reuse b - it will only know about the returned columns, but for clarity I chose (...) as c to disambiguate.
SELECT a.memempid, a.depkey, a.lastname, a.firstname, a.birthdate, a.memrelation
FROM table1 As a
INNER JOIN
(SELECT b.MemEmpID, b.LastName, b.FirstName
FROM table1 As b
GROUP BY b.MemEmpID, b.LastName, b.FirstName
HAVING Count(*) > 1
) as c
ON c.memempid = a.memempid
AND c.lastname = a.lastname
AND c.firstname = a.firstname

Related

Query in getting multiple duplicate rows in SQL Server

I have 2 tables Table1 and Table2 in which I want to get the total count of duplicate rows:
Expected output:
Query tested:
SELECT
t1.name,
t1.duplicates,
ISNULL(t2.active, 0) AS active,
ISNULL(t3.inactive, 0) AS inactive
FROM
(SELECT
t1.name, COUNT(*) AS duplicates
FROM
(SELECT c.name
FROM table1 c
INNER JOIN table2 as cd on cd.id = c.id)) t1
GROUP BY
name
HAVING
COUNT(*) > 1) t1
LEFT JOIN
(SELECT c.name, COUNT(*) AS active
FROM table1 c
WHERE name IN (SELECT c.name FROM table1 c)
GROUP BY c.name AND status = 'Active'
GROUP BY name) t2 ON t1.name = t2.name
LEFT JOIN
(SELECT c.name, COUNT(*) AS inactive
FROM table1 c
WHERE name IN (SELECT c.name FROM table1 c GROUP BY c.name)
AND status = 'InActive'
GROUP BY name) t3 ON t1.name = t3.name
ORDER BY
name
It is still returning duplicate rows and I'm unable to get the id and creator column
If you would pardon subquery and left join, i'd suggest the following query:
select b.*,
count(creator) as creator_count
from
(select a.mainid,
a.name,
sum(case when a.status = "active"
then 1 else 0 end) as active_count,
sum(case when a.status = "inactive"
then 1 else 0 end) as inactive_count,
count(a.name) as duplicate_count
from table1 as a
group by a.name
having count(a.name) > 1) as b
left join table2 as c
on b.mainid = c.mainid
group by c.mainid
having count(c.creator) > 1
rather than forcing our way to join the two table directly. First, derive the information we can get from the Table1 then join it with the Table2 to get the creator count.
SQL Fiddle: http://sqlfiddle.com/#!9/4daa19e/28

replace nested where condition with join

I have a SQL query that looks like this
Select a.*
From table1 a
where a.ColumnName in
(Select MAX(b.ColumnName)
from table2 b
where b.ColumnName2 in
(
Select MAX(c.columnName)
from table3 c
Group by c.ColumnName2
)
Group by b.ColumnName2
)
I am trying to write this in a join statement. I am positive inner join is what I need to get the right information. If someone could translate this to a join statement, I would be really glad.
Thank you.
EDIT 1:
I tried the typical Join statement that a rookie would.
Select a.*
from table1 a
inner join table2 b
on a.columnname = (Select max(b.columnName) from table2)
inner join table3 c
on b.columnName = (select max(c.columnName) from table3)
Obviously, that didn't work because I get 100,000+ results when I should be getting 800. I tried using an alias for table2 and table3 INSIDE the subselect statements and selecting the columnname using THAT alias like this:
Select max(bPart.columnName from table2 bPart)
Select max(cPart.columnName from table3 cPart)
Still the same result.
PERHAPS....
Though I'm not sure why a join is needed. Performance wise exists would likely be fastest, and since you're not returning values from table2 or 3 it seems like it would be the best approach.
SELECT a.*
FROM table1 a
INNER JOIN (SELECT MAX(ColumnName) MColumnName, columnname2
FROM table2
GROUP BY columnName2) B
ON A.columnName = B.mColumnName
INNER JOIN (SELECT MAX(columnName) mColumnName
FROM table3
GROUP BY ColumnName2) C
ON B.columname2 = C.MColumnName

Oracle join query in sqlserver

Here is the sample oracle query i need to be changed to SQLSERVER 2008.Basically it gets the description from table2 for the scode and if there is no or null description using 'case' it is made to 'unknown'. How to do.
select a.scode,b.description,a.amt,a.purid
from
(select scode,ISNULL(SUM(AMOUNT),0) AS AMT,count(pur_ID)
from table1
where scode is not null
group by scode)A, table2 B WHERE A.SOURCE_CODE =+B.SOURCE
Try this (Please note I am joining with =):
Select A.Scode, A.Amt, A.Counts, IsNull(B.Description, 'Unknown') Descripton
From (
select Scode, SOURCE_CODE, Isnull(sum(amount),0) as Amt, count(pur_ID) Counts
from table1
where scode is not null
group by scode, SOURCE_CODE
) A left join table2 B on A.SOURCE_CODE = B.SOURCE
Edit as per comments:
Select A.Scode, Isnull(sum(A.amount),0) as Amt,
count(A.pur_ID) Counts, IsNull(Max(B.description), 'Unknown') description
From Table1 A Left Join Table2 B
On A.SOURCE_CODE = B.SOURCE
Where A.Scode is not null
Group by A.Scode

inner join on different qaunties

i have two Identical tables in my SQL database these tables consist of Item Code and QTY each.
I need to see which items in both tables that have different quantities AND the items that
don't exist in the other table
I tried using FULL OUTER JOIN ON ITEMCODE=ITEMCODE AND QTY<>QTY
IT IS NOT WORKING
the result i am getting is something like that:
http://www.sendspace.com/file/nmb7yu
Try something like this:
SELECT c.Code ,
t1.Code ,
t1.Qty ,
t2.Code ,
t2.Qty
FROM ( SELECT Code
FROM dbo.Table1
UNION
SELECT Code
FROM dbo.Table2
) c
LEFT OUTER JOIN dbo.Table1 t1 ON c.Code = t1.Code
LEFT OUTER JOIN dbo.Table2 t2 ON c.Code = t2.Code
WHERE t1.Code IS NULL
OR t2.Code IS NULL
OR t1.Qty <> t2.Qty
Since you have a test for inequality in the WHERE clause you're implicitly only including items that are in both tables. This way you include items that are in one table, but not the other, or have the difference in quantity.
select *
from table1 a full outer join table2 b
on a.code = b.code
where a.qty <> b.qty or a.code is null or b.code is null
my lucky guess is that you filtered out rows where code column is null

Can I use a column calculated in a SQL Server view later on in that same view?

Can I use a column calculated in a SQL Server view later on in that same view?
Let's say I have the following view:
Select
t1.StartMile, t2.EndMile, t2.EndMile- t1.StartMile as TotMile
from
TableStarts as t1
inner join
TableEnds as t2 on t1.Id = t2.Id
Is there a way to edit the view to do the following
Select
t1.StartMile, t2.EndMile, t2.EndMile - t1.StartMile as TotMile,
TotMile + 30 as EvenMoreMiles
I tried this and got error:
Invalid column name 'TotMile'
Please don't tell me to use t2.EndMile - t1.StartMile + 30 as EvenMoreMiles. TotMiles is a long case statement in my actual code.
I rather not have to create an intermediate view.
I am using SQL Server 2005.
ADDED LATER
Thanks for all the answers. I will upvote all.
The answers raise the following new question:
Given that there are thousands of rows, and TotMiles looks like the following, which of the answers given would be the most efficient? Or would it be most efficient to create an intermediary view?
CASE WHEN t .TaskType = 1 and t .StartTime < '1/1/2012'
THEN (tv.EndMile - tv.StartMile )
WHEN NOT (t .Location1_PKey = c.pkey OR t .Location2_PKey = c.pkey)
then (tv.EndMile - tv.StartMile )
WHEN (tv.EndMile - tv.StartMile ) < 31 Then 0
ELSE (tv.EndMile - tv.StartMile - 30 )
END AS MilesAdjusted2012,
You can also use CROSS APPLY which can be more concise, particularly if you are building up chains of aliases that reference preceding ones.
SELECT t1.StartMile,
t2.EndMile,
TotMile,
EvenMoreMiles,
AndYetMoreMiles
FROM TableStarts AS t1
INNER JOIN TableEnds AS t2
ON t1.Id = t2.Id
CROSS APPLY (SELECT t2.EndMile - t1.StartMile) A(TotMile)
CROSS APPLY (SELECT TotMile + 30) A2(EvenMoreMiles)
CROSS APPLY (SELECT EvenMoreMiles + 100) A3(AndYetMoreMiles)
You can't directly, but you can build up sub-selects:
select StartMile,EndMile,TotMile,TotMile+30 as EvenMoreMiles from (
Select t1.StartMile, t2.EndMile, t2.EndMile- t1.StartMile as TotMile
from
TableStarts as t1
inner join
TableEnds as t2
on t1.Id = t2.Id
) t
Or use Common Table Expressions:
;with FirstCalcs as (
Select t1.StartMile, t2.EndMile, t2.EndMile- t1.StartMile as TotMile
from
TableStarts as t1
inner join
TableEnds as t2
on t1.Id = t2.Id
)
select StartMile,EndMile,TotMile,TotMile+30 as EvenMoreMiles from FirstCalcs
I'd generally prefer to use CTEs if there's going to be a number of levels that build up the final calculations, because otherwise most formatting schemes struggle to make select, sub-select, sub-sub-select, etc, easy to read. CTEs can include references to previously defined CTEs:
;with CTE1 as (
SELECT ...
), CTE2 as (
SELECT ... FROM CTE1
), CTE3 as (
SELECT ... FROM CTE2
), CTE4 as (
SELECT ... FROM CTE2 ... CTE3
)
SELECT ... FROM CTE4 ... CTE1
Try using a Derived Table.
SELECT
DerivedTable.*,
TotMile + 30 as EvenMoreMiles
From (Select
t1.StartMile,
t2.EndMile,
t2.EndMile- t1.StartMile as TotMile
FROM Table t1
Inner Join table2 t2 on t1.PK = t2.FK) DerivedTable
You can do this using a Common Table Expression (CTE). Lots on that here: https://web.archive.org/web/20210927200924/http://www.4guysfromrolla.com/webtech/071906-1.shtml
Basically,
CREATE VIEW ... AS
WITH Mileage (StartMile, EndMile, TotMile) AS (Select t1.StartMile, t2.EndMile, t2.EndMile- t1.StartMile as TotMile
from
TableStarts as t1
inner join
TableEnds as t2
on t1.Id = t2.Id)
SELECT TotMile FROM Mileage

Resources