I want to display daily report like this
Fulltime Contract Casual
2018/06/04 1 0 0
2018/06/05 1 0 0
2018/06/06 0 1 1
2018/06/07 2 1 0
2018/06/08 1 1 1
2018/06/09 0 1 1
but what I have is like this
Date Jobtype Meal
2018/06/04 Fulltime 1
2018/06/05 Fulltime 1
2018/06/06 Casual 1
2018/06/06 Contract 1
2018/06/07 Casual 1
2018/06/07 Contract 2
2018/06/08 Casual 1
2018/06/08 Contract 1
2018/06/08 Fulltime 1
2018/06/09 Casual 1
2018/06/09 Contract 1
What I have tried:
select Date, Jobtype,'Meal'=(COUNT(Date))
from CanLog
where WW BETWEEN '2018/06/06' and '2018/06/09'
group by Date, Jobtype
order by 1
I think you can try this:
SELECT Date,
(SELECT COUNT(*) FROM CanLog as c WHERE c.WW = clog.WW AND jobtype = 'fulltime') AS Fulltime,
(SELECT COUNT(*) FROM CanLog as c WHERE c.WW = clog.WW AND jobtype = 'contract') AS Contract,
(SELECT COUNT(*) FROM CanLog as c WHERE c.WW = clog.WW AND jobtype = 'casual') AS Casual
FROM CanLog AS clog
WHERE WW BETWEEN '2018/06/06' AND '2018/06/09'
GROUP BY Date, Jobtype
ORDER BY Date
Select in parenthesis count how much of given string is in the day.
And if you write from small all enlarged letters, it doesnt matter, sql is case insensitive
Not sure where your WW column comes from. I assumed it's the date column. If it's not, please adjust.
You need to use UNPIVOT operator and discard records that equal to 0:
select u.date, u.jobtype, u.meal
from canlog
unpivot
(
meal
for jobtype in ( fulltime, contract, casual )
) u
where
[Date] between '2018/06/06' and '2018/06/09'
and meal <> 0;
See Live DEMO.
Result:
date jobtype meal
2018-06-04 Fulltime 1
2018-06-05 Fulltime 1
2018-06-06 Contract 1
2018-06-06 Casual 1
2018-06-07 Fulltime 2
2018-06-07 Contract 1
2018-06-08 Fulltime 1
2018-06-08 Contract 1
2018-06-08 Casual 1
2018-06-09 Contract 1
2018-06-09 Casual 1
SELECT distinct Date,
(SELECT COUNT() FROM CanLog as c WHERE c.WW = clog.WW AND jobtype = 'fulltime') AS Fulltime,
(SELECT COUNT() FROM CanLog as c WHERE c.WW = clog.WW AND jobtype = 'contract') AS Contract,
(SELECT COUNT(*) FROM CanLog as c WHERE c.WW = clog.WW AND jobtype = 'casual') AS Casual
FROM CanLog AS clog
WHERE WW BETWEEN '2018/06/06' AND '2018/06/09'
GROUP BY Date, Jobtype
ORDER BY Date
Related
I have a table with data similar to this:
stat_id account_id discount date_from date_to type
1 1 50 2017-10-01 2017-10-31 1
2 2 40 2017-10-01 2017-10-31 1
3 1 0 2017-01-01 2017-11-30 2
I want to get all distinct account_ids, for a given period (date_from <= '2017-10-01' and date_to >= '2017-10-31'), each one with the highest type (type is either 1 or 2)
account_id discount type
1 0 2
2 40 1
I tried various queries, but I couldn't achieve this. What I get is one row with type = 1 and one row with type = 2 for account_id = 1
account_id discount type
1 50 1
1 0 2
2 40 1
I can filter them in my application, but for pure personal entertainment I want to do it in one query. Any help appreciated :)
Try this -
SELECT account_id, discount, type
FROM YOUR_TABLE
WHERE (account_id, type) IN (SELECT account_id, MAX(type)
FROM YOUR_TABLE
GROUP BY account_id)
AND date_from <= '2017-10-01'
AND date_to >= '2017-10-31'
I have data like this: (table name: Activities)
ActivityId CreatedOn TypeId
1 2017-01-01 1
1 2017-01-02 1
1 2017-01-02 2
2 2017-01-01 3
Where Type is a lookup value: (table name: Types)
TypeId Name
1 Question
2 Answer
3 Comment
Basically it's an activity history table.
I want to turn the above tables into a grouped sum row for types, for each ActivityId, like this:
ActivityId QuestionCount AnswerCount CommentCount
1 2 1 0
2 0 0 1
I know the answer is probably pretty simple, but it's eluding me for some reason.
Any help? Thanks in advance.
A simple join and conditional aggregation should do the trick (I suspect you were over-thinking it)
Select ActivityID
,QuestionCount = sum(case when Name='Question' then 1 else 0 end)
,AnswerCount = sum(case when Name='Answer' then 1 else 0 end)
,CommentCount = sum(case when Name='Comment' then 1 else 0 end)
From Activities A
Join Types B on A.TypeId=B.TypeId
Group By ActivityId
Returns
ActivityID QuestionCount AnswerCount CommentCount
1 2 1 0
2 0 0 1
You could also do it without the Join... Just less readable
Select ActivityID
,QuestionCount = sum(case when TypeId=1 then 1 else 0 end)
,AnswerCount = sum(case when TypeId=2 then 1 else 0 end)
,CommentCount = sum(case when TypeId=3 then 1 else 0 end)
From #Activities A
Group By ActivityId
You could also try a PIVOT
Select ActivityID
,[1] as QuestionCount
,[2] as AnswerCount
,[3] as CommentCount
From (Select ActivityId,TypeID,1 as Cnt From #Activities) A
Pivot (count(Cnt) For TypeId in ([1],[2],[3]) ) p
I am building a procedure that when given a customerID it will subtract an account's type 2 (Credit card) balance from an account type 1 (Savings) balance, if there is an savings account then it subtracts the credit card balance.
(ex savings balance - credit card balance = total balance)
My table is set up like such
ID Number Balance AccountType CustomerID
-----------------------------------------------------------
1 2434789 451.23 1 1
2 2435656 1425.12 1 2
3 2434789 12.56 2 1
4 4831567 45894.23 2 2
5 8994785 500.00 2 3
6 4582165 243.10 2 4
7 7581462 1567842.21 1 3
8 2648956 1058.63 2 5
9 4582165 4865.12 1 4
10 4186545 481.56 2 6
I have tried looking this up to get some guidance but everything I have found hasn't quite helped me. If someone can explain or show me what I need to do that would be great, this is the only part of my assignment I am stuck on.
You could group by CustomerId and get the sum of saving and credit balances
select
c.CustomerId,
SUM(CASE WHEN AccountType = 1 THEN Balance ELSE 0 END) Saving,
SUM(CASE WHEN AccountType = 2 THEN Balance ELSE 0 END) Credit,
from
Customer c
group by
c.CustomerId
And then you can easily get the total with below query:
Select
CustomerId,
Saving - Credit
from
(
select
c.CustomerId,
SUM(CASE WHEN AccountType = 1 THEN Balance ELSE 0 END) Saving,
SUM(CASE WHEN AccountType = 2 THEN Balance ELSE 0 END) Credit,
from Customer c
group by c.CustomerId
) cust
You join the table to itself, where each side of the join only includes the appropriate account type records:
SELECT coalesce(s.CustomerID, cc.CustomerID) CustomerID
,coalesce(s.Number, cc.Number) Number
coalesce(s.Balance,0) - coalesce(cc.Balance,0) Balance
FROM (SELECT * FROM [accounts] WHERE AccountType = 2) s
FULL JOIN (SELECT * FROM [accounts] WHERE AccountType = 1) cc on cc.customerID = s.customerID
and thank you all in advance for your help.
I'm trying to take the results from two separate queries and include them in a third query that has a CASE statement. I've had some success but I'm not able to present the results of the third query in the proper order. The purpose of this is to show the employee count for each department under the different managers. So far I can only load separately the manager names and their departments and employee department count totals by department. What I can't figure out is how to get the manager names in and the employee department count in for each manager row. Below are the two source queries I've used so far and the query with the CASE statement. I've also looked at UNPIVOT function with no success yet.
a) This simple query lists each primary manager name. There are also sub managers that will be returned using a hierarchy query later.
select name from employees "Boss" where employeeid in
(‘1’,'5','25','84','85');
b) This query returns the department id count for each main manager (‘1’,'5','25','84','85') as well as all sub-managers.
select departmentid, count(departmentid) COUNT from employees
where departmentid = departmentid and level <= 3
connect by prior employeeid = bossid
start with employeeid = 5
group by departmentid
order by departmentid;
c) Here’s a CASE statement that outputs exactly as desired. The problem here is the select statement currently outputs only the manager names and the manager departments into the columns. What I need to do is output both the manager names and the manager's employee department counts into the individual manager row columns. I've tried to do a separate select of the manager names to get the ‘Boss’ column and another select to include the department counts. But that got messy. Also passing the counts in a second statement would create an additional unwanted column.
select e.name "Boss",
COUNT(CASE WHEN d.departmentid = '1' THEN 1 END) AS "Finance",
COUNT(CASE WHEN d.departmentid = '2' THEN 1 END) AS "HR",
COUNT(CASE WHEN d.departmentid = '3' THEN 1 END) AS "IT",
COUNT(CASE WHEN d.departmentid = '4' THEN 1 END) AS "Marketing",
COUNT(CASE WHEN d.departmentid = '5' THEN 1 END) AS "Sales"
from employees e, departments d
where e.employeeid in (select distinct e.bossid from employees e)
and e.departmentid = d.departmentid (+)
group by e.name
order by e.name;
Boss Finance HR IT Marketing Sales
-------------------- ---------- ---------- ---------- ---------- ----------
Baxter Carney 0 0 0 0 1
Blythe Pierce 0 0 0 0 1
Here's an altered CASE query that loads the employee department counts but unfortunately it loads by department and not by individual manager. That is the problem I'm stuck on right now. How to pass the counts to the right manager and into the right column.
select departmentid "DEPTNO",
COUNT(CASE WHEN departmentid = '1' THEN 1 END) AS "Finance",
COUNT(CASE WHEN departmentid = '2' THEN 1 END) AS "HR",
COUNT(CASE WHEN departmentid = '3' THEN 1 END) AS "IT",
COUNT(CASE WHEN departmentid = '4' THEN 1 END) AS "Marketing",
COUNT(CASE WHEN departmentid = '5' THEN 1 END) AS "Sales"
from employees
where departmentid = departmentid and level <= 3
connect by prior employeeid = bossid
start with employeeid = 5
group by departmentid
order by departmentid
/
DEPTNO Finance HR IT Marketing Sales
3 0 0 1 0 0
5 0 0 0 0 21
And here's for all managers. You can see that it just keeps increasing the individual department count.
DEPTNO Finance HR IT Marketing Sales
1 4 0 0 0 0
2 0 23 0 0 0
3 0 0 20 0 0
4 0 0 0 1 0
5 0 0 0 0 28
I have 4 tables in my database.
Students (Idno, Name, CourseId)
Sample data:
Idno Name CourseId
------------------------
-101123456 Vijay 101
-101123457 John 102
-101123458 Sam 101
-101123459 Arvind 102
-101123460 Smith 101
Courses (CourseId, CourseNo, CourseName, StreamId)
Sample data:
CourseId CourseNo CourseName StreamId
------------------------------------------
-101 53245 C 1
-102 53245 C++ 2
Streams (StreamId, StreamName)
Sample data:
StreamId StreamName
---------------------------
-1 Engineering
-2 Medical
Booking (BId, Idno, BStatus)
Sample data:
Bid Idno BStatus
--------------------------------
-1110 101123456 Confirmed
-1111 101123456 Confirmed
-1112 101123457 Confirmed
-1113 101123458 Confirmed
-1114 101123459 Confirmed
-1115 101123460 Confirmed
-1116 101123456 Confirmed
-1117 101123457 Confirmed
-1118 101123458 Confirmed
-1119 101123459 Confirmed
-1119 101123460 Cancelled
I have a problem generating the following output
SNo Stream BookedOnce BookedTwice NonBooked
1 Engineering 2 3 0
2 Medical 3 1 1
Thanks
I think this requires a two step process. First, calculate the number of bookings by each student for a stream. Then per stream, count the number of students that have one, two or zero bookings.
Here's an example, with the first step in the inner query:
select StreamId
, StreamName
, sum(case when Bookings = 1 then 1 else 0 end) as BookedOnce
, sum(case when Bookings = 2 then 1 else 0 end) as BookedTwice
, sum(case when Bookings = 0 then 1 else 0 end) as NoneBooked
from (
select str.StreamId
, str.StreamName
, s.Idno
, count(b.BId) as Bookings
from Students s
left join
Booking b
on b.Idno = s.Idno
left join
Courses c
on c.CourseId = s.CourseId
left join
Streams str
on str.StreamId = c.StreamId
group by
str.StreamId
, str.StreamName
, s.Idno
) BookingsPerStudentPerStream
group by
StreamId
, StreamName