Removing Duplicate Values within Group By - sql-server

I am using SQL-Server 2012 in Microsoft Visual Studio 2010.
As a preface, I cannot use ROW_NUMBER() OVER(PARTITION BY Col) as the OVER() method is not supported by the Visual Studio Version I am using. I am not in a place, unfortunately, where I can get new software.
I have a group of department and job IDs such that:
SELECT
Department,
Job_ID
FROM
Table1
JOIN Table2 on
Table1.id = Table2.id
Department Job_ID
__________________________
Marketing J3
Engineering J1
Marketing J2
Recruiting J2
Marketing J8
Administration J3
Recruiting J1
Administration J5
Administration J1
I am trying to group by Job_ID, show the distinct Departments associated with each Job_ID, and only include groups that have more than 2 departments. The end results would be:
Department Job_ID
__________________________
Administration J1
Recruiting J1
Engineering J1
Marketing J2
Recruiting J2
Marketing J3
Administration J3
I have tried:
SELECT Job_ID, count(distinct(Department)) as Dept_CountD
FROM Table1 JOIN Table2 on Table1.id=Table2.id
GROUP BY Job_ID
HAVING count(distinct(Department)) >1
This works, however, it does not group the departments along with each ID. I also know (and have tested) that I cannot insert Department into the Group By statement, as that would return distinct department counts only equal to 1!
I have tried building the above statement into a CTE and inner joining on the Job_ID so I only have Job_IDs that have more than 2 distinct departments associated with them, however, I end up with duplicate Departments in the grouping from the join.
I'm thinking perhaps joining to a sub query or doing a semi join?

How about this:
SELECT
Department,
Job_ID
FROM Table1
JOIN Table2 on Table1.id = Table2.id
WHERE Job_ID IN (SELECT Job_ID
FROM Table1 JOIN Table2 on Table1.id=Table2.id
GROUP BY Job_ID
HAVING count(distinct(Department)) >1)

Use COUNT() Over() window aggregate
select * from
(
select count(1)over(partition by Job_ID) as cnt,*
From <<join>>
) A
Where cnt > 1

try this: ( I am only guessing which table has the Departments and which has the Jobs cause you did not provide schema.
SELECT Job_ID, count(*) Dept_CountD
FROM Table1 a JOIN Table2 b on a.id=b.id
where (Select count(*) from table1
Where JobId = a.JobId) > 1

Related

List customers who sold most in mssql

I'm new to sql.
I have to select top 3 companies who have the highest sells
Company Table:
CompanyId, Compnayname,etc
Orders Table:
OrderId, companyId,price,etc
select top 3 companyname , (select sum(price) from ordes) as Maximum from company order by Maximum Desc?
I think i need to join these but i cant find a way around it
Join these tables, group by company's name and order by their total sales:
select top 3 c.Companyname, sum(o.price) as TotalSales
from Orders o
inner join Company c on c.CompanyId = o.companyid
group by c.Companyname
order by TotalSales desc

Selecting count of exist rows in other table and join it to our SQL server table

I have two tables in SQL server. first one is table of customers info and second includes all purchases,
At first Table i have id of our customers, and the purchases table although has the id of who bought that product. so how can i select all customers table that include how many time they purchased products?
i tried this
SELECT TOP 2000 COUNT(tblpurchase.id) as id2,tblcustomers.* From tblpurchase
right join on tblpurchase.id=tblcustomers.id
but didn't word. how can i solve this?
Use OUTER APPLY
SELECT TOP 2000 tblcustomers.* ,M.CustomerCount
From tblcustomers
OUTER APPLY(
SELECT COUNT(*) as CustomerCount
from tblpurchase
WHERE tblpurchase.CustomerIDColumn = tblcustomers.id
)M
Here tblpurchase.CustomerIDColumn use actual name of customerID column
Also you can with LEFT JOIN
SELECT TOP 2000
C.*,
P.CustomerCount
From
tblcustomers C LEFT JOIN
(
SELECT
TP.CustomerId,
COUNT(*) as CustomerCount
FROM
tblpurchase TP
GROUP BY
TP.CustomerId
) P ON C.Id = P.CustomerId

Subtracting two columns within the sql query

I have been trying to subtract two columns in sql server to form a third one. Below is my query
select AD.Id, Sum(APS.Amount) AS TotalDue,
isnull((select sum(Amount) from Activation where InvoiceId in (select InvoiceId from Invoices where AgreementId = AD.Id)),0)
As AllocatedToDate
from AdvantageDetails AD
inner join AllPaymentsSubstantial APS
on APS.AgreementId=AD.Id
where AD.OrganizationId=30
group by AD.Id
What I tried is below but it is not working. :
select AD.Id, Sum(APS.Amount) AS TotalDue,
isnull((select sum(Amount) from Activation where InvoiceId in (select InvoiceId from Invoices where AgreementId = AD.Id)),0)
As AllocatedToDate , (TotalDue-AllocatedToDate) as NewColumn
from AdvantageDetails AD
inner join AllPaymentsSubstantial APS
on APS.AgreementId=AD.Id
where AD.OrganizationId=30
group by AD.Id
At last I tried it using a CTE which worked fine. But I want to do it without creating CTE. Can there be any other way for performing the same functionality. I do not want to use CTE because it is forcasted that there
can be other columns which will be calculated in future.
with CTE as(select AD.Id, Sum(APS.Amount) AS TotalDue,
isnull((select sum(Amount) from Activation where InvoiceId in (select InvoiceId from Invoices where AgreementId = AD.Id)),0)
As AllocatedToDate , (TotalDue-AllocatedToDate) as NewColumn
from AdvantageDetails AD
inner join AllPaymentsSubstantial APS
on APS.AgreementId=AD.Id
where AD.OrganizationId=30
group by AD.Id) select * , (CTE.TotalDue-CTE.AllocatedToDate)As Newcolumn from CTE
You can do it without a CTE by repeating the entire formula that makes up AllocatedToDate.
You cannot use the alias of a column in the SELECT list, so you cannot do this:
SELECT {some calculation} AS ColumnA, (ColumnA - ColumnB) AS ColumnC
If you don't want to use a CTE or derived table, you have to do this:
SELECT {some calculation} AS ColumnA, ({some calculation} - ColumnB) AS ColumnC
And by the way, I can't imagine why the possibility of future columns being added is a reason not to use a CTE. To me, it sounds like a reason TO use a CTE, as you will only have to make changes in one place in the code, and not duplicate the same code in different places in the same query.
You can just use nested queries:
select Id, TotalDue, AllocatedToDate, (TotalDue-AllocatedToDate) as NewColumn
from (
select AD.Id, Sum(APS.Amount) AS TotalDue,
isnull((select sum(Amount) from Activation where InvoiceId in (select InvoiceId from Invoices where AgreementId = AD.Id)),0)
As AllocatedToDate
from AdvantageDetails AD
inner join AllPaymentsSubstantial APS
on APS.AgreementId=AD.Id
where AD.OrganizationId=30
group by AD.Id
) x

rank() equivalent for SQL Server 2000

I am using SQL Server 2000 so sadly common table expressions are out but I have the following 2 table structure:
Invoices
id
InvoiceQueryReasons
id
invoice_id
reason
date_queried
I want to inner join from Invoices to InvoiceQueryReasons and only get 1 row for each invoice that selects the most recent InvoiceQueryReasons record.
If I was using a CTE with postgress I would do something like:
SELECT *
FROM
(SELECT
"i"."id", "iq"."reason", "iq"."date_queried",
rank() OVER (PARTITION BY "invoice_id" ORDER BY "date_queried" DESC) AS "invoice_query_rnk",
FROM "invoices" i
INNER JOIN "InvoiceQueryReasons" iq ON ("i"."id" = "iq"."invoice_id")
) AS "iqrs"
INNER JOIN
"invoices" ON ("iqrs"."id" = "invoices"."id")
WHERE
("invoice_query_rnk" = 1)
Apologies if the query is not exactly right, I am writing this on a non-dev machine.
How could I write a similar query in SQL Server 2000 where I do not have common table expression?
This is the way I always used to do this in SQL Server 2000:
FROM Table1
INNER JOIN Table2 ON Table2.PrimaryKey=(
SELECT TOP 1 t2.PrimaryKey
FROM Table2 t2
WHERE t2.ForeignKey=Table1.PrimaryKey
ORDER BY t2 DateColumn DESC
)

MS SQL Server select statement: display all combinations from two tables

I have two tables in a MS SQL Server database:
Table1
Emp_ID, First_Name, Last_Name
1 Joe Smith
2 Bob Jones
Table2
Emp_ID, Dept_ID, Status
1 1 Active
1 2 NotActive
1 3 NotActive
2 1 Active
What I would like to do is create a SQL select statement that displays a row for every employee and department combination along with the status even if the employee has never been in the department (table 2). For the sample data, this should bring back 6 records since there are 2 employees and 3 departments.
Any help would be appreciated!
Thank you
If you don't have a departments table, you'll need to create a subquery to get the distinct list of dept_ids to cross join on:
select emp_id, first_name, last_name, dept.dept_id, status
from empl
cross join (select distinct dept_id from empdept) dept
left join empdept on empl.emp_id = empdept.empt_id
and dept.dept_id = empdept.dept_id
SQL Fiddle Demo
SELECT *
FROM table1 T1 FULL OUTER JOIN table2 T2
ON T1.EMP_ID=T2.EMP_ID

Resources