I am struggling with a SQL query in SQL Server - sql

From one table (i.e. tblCases), I can count and group each protocol based on its ID for a given date interval:
ALTER PROCEDURE [dbo].[sp_CountAndGroupByProtocol]
(#startDate datetime, #endDate datetime)
AS
BEGIN
SELECT
COUNT(C.protocolID) AS total, protocolID
FROM
tblCases C
WHERE
C.dateOpened BETWEEN #startDate and #endDate
GROUP BY
C.protocolID
ORDER BY
total DESC
END
EXEC [dbo].[sp_CountAndGroupByProtocol] '2015-01-01', '2016-08-01'
And I get the correct result:
total protocolID
1 60 3860
2 43 5829
...
Each protocol is linked to one scientist (i.e namePI). tblProtocols:
ID protocol_ID namePI
------------------------
1 3860 1
2 5829 5
..
tblPI:
ID firstName lastName
------------------------
1 John Smith
2 Davis Emma
...
I would like to add the person's last name and first name for each protocol:
total protocolID lastName firstName
---------------------------------------------------
1 60 3860 Smith John
2 43 5829 Davis Emma
...
I know that join should work, but wherever I put "JOIN", I get
error: incorrect syntax near JOIN
Is it because I am using SQL Server?
I would greatly appreciate the community's feedback. Thank you!

This should be what you want, but if you post your code that is erroring out we can likely give you a precise reason for it.
SELECT COUNT(C.protocolID) AS total, c.protocolID, lastName, firstName
FROM tblCases C
INNER JOIN tblProtocols P on P.Protocol_ID = C.ProtocolID
INNER JOIN tblPI PI on PI.ID = P.NamePI
WHERE C.dateOpened BETWEEN #startDate and #endDate
GROUP BY C.protocolID, lastName, firstName
ORDER BY total desc

Related

How to count by two fields and join with other table Postgres?

I have two tables, one table user and second table transactions related with the transactions done by a user. I want to do a query that give me the count by name and date, with the fields in user table. How can I do it?
Table user:
Name Id Card
-----------------
Alex 01 N
James 02 Y
Table transaction:
Name Date
-----------------
Alex 01/07/2012
Alex 01/12/2012
James 01/08/2012
Alex 01/07/2012
Alex 01/12/2012
James 01/07/2012
James 01/07/2012
I want sometihng like this:
Name Date Transactions ID Card
---------------------------------------------
Alex 01/07/2012 2 01 N
Alex 01/12/2012 2 01 N
James 01/08/2012 1 02 Y
James 01/07/2012 2 02 Y
First of all I tryed to count by two columns with something like this:
select name, date, count(name, date) from pm_transaction GROUP BY (name,date)
select count(distinct(machine, date)) from pm_transaction
But it does not work, I tried a lot of combinations but no one works
Try this
select tb1.name, tb2.date , tb2.transaction , tb1.Id, tb1.card
from tbUser as tb1
inner join
(select date,
name,
count(date) as transaction
from tbTransaction group by date)
as tb2 on tb1.name = tb2.name
This looks like simple aggregation task. Just check and correct table join condition and table names:
select u.name, t.date, count(1) as transactions, u.id, u.card
from transaction t
join user_table u on u.name = t.name
group by u.name, t.date, u.id, u.card;

Aggregate Functions To Pull More Record Field Data

I would like to know what would be the best way to get the data from a specific row when I use a Group By query. The real query is more complex than the example I'm providing here so I'm looking for something other than a sub-select on the Sales table.
I'm using MSSQL 2008 and I would like something that allow me to get the date field from the Sales record that has the max(amount).
Query
select uid, firstName, lastName, AmountFromTagetedRow, DateFromTargetedRow,
from users u inner join
sales s on u.uid = s.custID
group by uid, firstName, lastName
order by uid
USERS
uid firstName lastName
1 Sam Smith
2 Joe Brown
3 Kim Young
SALES
sid Custid date amount ...
1 1 2016-01-02 100
2 3 2016-01-12 485
3 1 2016-01-22 152
4 2 2016-02-01 156
5 1 2016-02-02 12
6 1 2016-03-05 84
7 2 2016-03-10 68
RESULTS
uid firstName LastName amount date
1 Sam Smith 152 2016-01-22
2 Joe Brown 156 2016-02-01
3 Kim Young 485 2016-01-12
Your posted query doesn't match your amount but something like this should get you pointed in the right direction.
with SortedResults as
(
select uid
, firstName
, lastName
, AmountFromTagetedRow
, DateFromTargetedRow
, ROW_NUMBER() over (partition by u.uid order by AmountFromTagetedRow desc) as RowNum
from users u inner join
sales s on u.uid = s.custID
group by uid
, firstName
, lastName
)
select *
from SortedResults
where RowNum = 1
order by uid

Select from two tables and set null column

I have two tables
Schedule:
scheduleID DriverID ScheduleDate
11 1 2015-05-20
22 2 2015-05-20
33 NULL 2015-05-21
44 NULL 2015-05-21
and
Employee:
ID Fname Lname
1 jack miller
2 kelly moore
3 mark sam
4 tom hanks
I want to select from these two tables based on ScheduleDate and show the driver full name from Employee table and show null columns.
The result should be like:
scheduleID Fname Lname
33 NULL NULL
44 NULL NULL
I used:
select row_number() over (order by scheduleID desc) as schedule, scheduleID, Driver_ID,FirstName,LastName
From Schedule, Employee
where scheduleDate= '2015-05-21' AND EmployeID=Driver_ID;
It works well if " scheduleDate= '2015-05-20' "
but I need to show null Columns too!
any help!
You need a left join for this -- just emphasizing why you should never using implicit join syntax. Simple rule: Always use explicit join syntax. Never use commas in the from clause.
select row_number() over (order by scheduleID desc) as schedule, scheduleID,
Driver_ID, FirstName, LastName
From Schedule left join
Employee
on EmployeID = Driver_ID
where scheduleDate = '2015-05-21';

SQL Select for each Age Group and COUNT Members

I have the following tables
[Members]:
MemberID DOB Name
------------------------------------
1 01/01/2000 Jon
2 01/01/2005 Bob
3 01/01/2009 Mike
4 01/01/1980 Greg
[AgeGroups]:
GroupID GroupTitle MinAge MaxAge
--------------------------------------------------
1 GroupA 0 5
2 GroupB 6 10
3 GroupC 11 18
[Events]:
EventID EventStart
---------------------------
1 01/01/2015
I want to be able to do a SQL select command which gets the Group Title and a count of the number of members who's age will be within the age range of each of the Age Groups at the date of the EventStart.
GroupTitle MemberCount
----------------------------------
GroupA 1
GroupB 2
GroupC 1
I've been trying to do this with SELECT CASE WHEN but have got stuck.
Any help would be greatly appreciated!
Take a look at Date and Time Data Types and Functions, and in particular at the DATEDIFF function.
You could try something like the following:
SELECT AgeGroups.GroupID, AgeGroups.GroupTitle, COUNT(1) AS MemberCount
FROM AgeGroups
JOIN Events ON EventID = 1
JOIN Members
ON DATEDIFF(year, Members.DOB, Events.EventStart) >= AgeGroups.MinAge
AND DATEDIFF(year, Members.DOB, Events.EventStart) <= AgeGroups.MaxAge
ORDER BY AgeGroups.GroupID
Does that help?

Oracle 11G R2 SQL rows to columns

I have a table of bank staff information that looks like this:
branchNumber Position firstName lastName staffNumber
------------ -------- --------- -------- -----------
25 Manager john doe 11111
25 Secretary robert paulson 11112
25 Secretary cindy lu 11113
66 Manager tim timson 22223
66 Manager jacob jacobson 22224
66 Secretary henry henryson 22225
66 Supervisor paul paulerton 22226
I am actually done with this, but I completed the assignment using SQL common table expressions, and I can't use them in this project, I need them in this format.
branchNumber numOfManagers numOfSecretaries numOfSupervisors totalEmployees
------------ ------------- ---------------- ---------------- --------------
25 1 2 0 3
66 2 1 1 4
My issue is getting multiple columns with information from a row, I have this so far,
SELECT branchNumber, COUNT(*) AS numOfManagers
FROM Staff
WHERE position = 'Manager'
GROUP BY branchNumber, Position;
This outputs the correct information for numOfManagers, but making the next three columns eludes me without using CTE's. I tried sub selects too, with no luck. Anybody have any ideas?
You can use something like this:
select branchnumber,
sum(case when Position ='Manager' then 1 else 0 end) numofManagers,
sum(case when Position ='Secretary' then 1 else 0 end) numofSecretaries,
sum(case when Position ='Supervisor' then 1 else 0 end) numofSupervisors,
count(*) totalEmployees
from yourtable
group by branchnumber
See SQL Fiddle with Demo
Or you can use the PIVOT function:
select branchnumber,
'Manager', 'Secretary', 'Supervisor',
TotalEmployees
from
(
select t1.branchnumber,
t1.position,
t2.TotalEmployees
from yourtable t1
inner join
(
select branchnumber, count(*) TotalEmployees
from yourtable
group by branchnumber
) t2
on t1.branchnumber = t2.branchnumber
) x
pivot
(
count(position)
for position in ('Manager', 'Secretary', 'Supervisor')
) p;
See SQL Fiddle with Demo