SQL — how to count? - sql

I have 2 tables:
users:
id | username
1 | alex
2 | max
orders:
id | user_id | status
1 | 1 | wait
2 | 1 | paid
3 | 2 | paid
What form should the SQL request take to take next?
username | wait_orders | paid_orders
alex | 1 | 1
max | 0 | 1

You join here using an INNER JOIN and then count your specific order statuses with a CASE statement and aggregate with SUM() and a GROUP BY:
SELECT
users.username
SUM(CASE WHEN orders.status='Wait' THEN 1 ELSE 0 END) as wait_orders,
SUM(CASE WHEN orders.status='Paid' THEN 1 ELSE 0 END) as paid_orders
FROM users
INNER JOIN orders ON
users.id = orders.user_id
GROUP BY username

Related

How to get count from one table which is mutually dependent to another table

I have two table
Let's name as first table: QC_Meeting_Master
Second table: QC_Project_Master I want to calculate count of problems_ID Which is mutually depend on second table
ID | QC_ID | Problems_ID |
___|_______|_____________|
1 | 1 | 2 |
2 | 1 | 7 |
ID | QC_ID | Problem_ID |
___|_______|_____________|
1 | 1 | 7 |
2 | 1 | 7 |
3 | 1 | 7 |
4 | 1 | 7 |
5 | 1 | 2 |
6 | 1 | 2 |
7 | 1 | 2 |
select COUNT(Problem_ID) from [QC_Project_Master] where Problem_ID in
(select Problems_ID from QC_Meeting_Master QMM join QC_Project_Master QPM on QMM.Problems_ID = QPM.Problem_ID)
I have to calculate Count of QC_Project_Master (problem_ID) on basis of QC_Meeting_Master (Problems_ID)
it means for first table: QC_Meeting_Master(Problems_ID) = 2,
then count should be 3
And for Second table: QC_Project_Master (Problems_ID) = 7,
then count should be 4
use conditional aggregation
select sum(case when t2.Problem_ID=2 then 1 else 0 end),
sum(case when t2.Problem_ID=7 then 1 else 0 end) from
table1 t1 join table2 t2 on t1.QC_ID=t2.QC_ID and t1.Problems_ID=t2.Problems_ID
if you need all the group count then use below
select t2.QC_ID,t2.Problems_ID, count(*) from
table1 t1 join table2 t2
on t1.QC_ID=t2.QC_ID and t1.Problems_ID=t2.Problems_ID
group by t2.QC_ID,t2.Problems_ID
As far as I understood your problem this is simple aggregation and JOIN as below:
SELECT mm.QC_ID, mm.Problem_ID, pm.cnt
FROM QC_Meeting_Master mm
INNER JOIN
(
SELECT QC_ID, Problem_ID, COUNT(*) cnt
FROM QC_Project_Master
GROUP BY QC_ID, Problem_ID
) pm
ON pm.QC_ID = mm.QC_ID AND pm.Problem_ID = mm.Problem_ID;

SQL count referrals for each user

My query:
SELECT COUNT(referrer) as refs, SUM(amount) as total, contracts.id, userid, fine
FROM contracts
JOIN users ON contracts.userid = users.id
WHERE active = 1
GROUP BY userid
my users table :
id | username | referrer (int)
1 | test | 2
2 | drekorig |
3 | maximili | 2
my contracts table:
id ! userid | amount | fine | active
1 | 1 | 50 | 23/10/2018 | 1
2 ! 2 | 120 | 24/10/2018 | 1
3 | 2 | 150 | 24/10/2018 | 1
How do I get the count of referrals for each User? My query actually gets the number of contracts instead...
Expected result:
refs | total | id | userid | fine
0 | 0 | 1 | 1 | 23/10/2018
2 | 270 | 2 | 2 | 24/10/2018
http://sqlfiddle.com/#!9/0a464d/5
SELECT r.count as refs,
SUM(amount) as total,
MAX(c.id),
u.id,
MAX(fine)
FROM users u
LEFT JOIN
(SELECT referrer, COUNT(*) `count`
FROM users
GROUP BY referrer
) r
ON u.id = r.referrer
JOIN contracts c
ON c.userid = u.id
WHERE active = 1
GROUP BY u.id

Return all rows from a table and indicate with a new column whether they exist or not in another table

If I have 2 tables:
TABLE_SEARCHFIELDS:
FieldID | FieldName
--------------------
1 | MyField1
2 | MyField2
3 | MyField3
4 | MyField4
5 | MyField5
and
TABLE_CUSTOMSEARCHFIELDS:
UserID | FieldID
--------------------
1 | 1
1 | 2
1 | 5
2 | 2
2 | 4
2 | 5
and I would like to return all of the Searchfields from the first table, but would also like indicated whether that Searchfield is active for a particular user.
E.g. I want to query UserID = 1 and get the result:
FieldID | FieldName | Active
------------------------------
1 | MyField1 | 1
2 | MyField2 | 1
3 | MyField3 | 0
4 | MyField4 | 0
5 | MyField5 | 1
What is the best way to achieve this?
I would do this using exists:
select sf.*,
(case when exists (select 1
from customsearchfields csf
where csf.userid = 1 and csf.fieldid = sf.fieldid
)
then 1 else 0
end) as Active
from searchfields sf;
Assuming you have no duplicate rows, you can also do this using a left join:
select sf.*, (case when csf.userid is not null then 1 else 0 end) as Active
from searchfields sf left join
customsearchfields csf
on csf.userid = 1 and csf.fieldid = sf.fieldid;

Efficent way to generate a summery table in SQL. Please see explanation

I am very new to sql.I need some help in generating summery information
MemberTable
MonthID | UserID | TeamID
-----------------------------
1 | 1 | 1
1 | 2 | 1
1 | 3 | 1
1 | 4 | 1
1 | 5 | 2
1 | 6 | 2
1 | 7 | 2
AND
ReportTable
ID* | MonthID | UserID | IsSend
-----------------------------------
1 | 1 | 2 | False
2 | 1 | 3 | True
3 | 1 | 5 | True
I want to generate a summery like the following
TeamID | Total Count | Send Count | Not Send Count
-----------------------------------------------------------
1 | 4 | 1 | 3
2 | 3 | 1 | 2
Total Count : No of users in a team
Send Count : Total User in a team with IsSend = True
Not Send Count : Total Count - Send Count
What would be the efficent way?
Give this a try:
select mt.teamId, count(*) totalCount,
count(case when rt.isSend = 'True' then 1 end) sendCount,
count(case when rt.isSend != 'True' then 1 end) notSendCount
from memberTable mt
join reportTable rt on mt.userId = rt.userId
group by mt.teamId
Note that your expected result does not reflect your data. The result based on your data should be:
+--------+------------+-----------+--------------+
| TEAMID | TOTALCOUNT | SENDCOUNT | NOTSENDCOUNT |
+--------+------------+-----------+--------------+
| 1 | 2 | 1 | 1 |
| 2 | 1 | 1 | 0 |
+--------+------------+-----------+--------------+
select MT.TeamID,
count(distinct MT.UserID) as "Total Count",
count(distinct case when RT.IsSend = 1 then MT.UserID end) as "Send Count",
count(distinct MT.UserID) - count(distinct case when RT.IsSend = 1 then MT.UserID end) as "Not Send Count"
from MemberTable as MT
left outer join ReportTable as RT
on MT.MonthID = RT.MonthID and
MT.UserID = RT.UserID
group by MT.TeamID
Result:
TeamID Total Count Send Count Not Send Count
----------- ----------- ----------- --------------
1 4 1 3
2 3 1 2
Try here: https://data.stackexchange.com/stackoverflow/query/66347
Without havign the tables to try this on, I can't check that this will work, but this shoul get you most of the way:
SELECT TeamID, count(userID) as "Total count", Sum(IsSend) as "Send Count" FROM MemberTable JOIN ReportTable ON UserID GROUP BY TeamID;

Is it possible to select multiple conditional counts across three tables in a single SQL query?

My SQL-fu is too weak for this, and I'm not even sure it's possible in a single SQL call.
Given I have the following tables:
PARTNER
+----+--------+
| id | name |
+----+--------+
| 1 | bloggs |
| 2 | jones |
PARTNER MANAGER
+----+--------------+------+
| id | partner_id | name |
+----+--------------+------+
| 1 | 1 | fred |
| 2 | 2 | dave |
COMPANY
+----+--------------------+--------+----------+
| id | partner_manager_id | name | active |
+----+--------------------+--------+----------+
| 1 | 1 | comp1 | true |
| 2 | 1 | comp2 | false |
| 3 | 2 | comp3 | true |
| 4 | 2 | comp4 | true |
| 5 | 2 | comp5 | true |
| 6 | 2 | comp6 | true |
I'd like to output the following in a single SQL call:
+--------------+--------------------+----------------------+
| partner_name | n_active_companies | n_inactive_companies |
+--------------+--------------------+----------------------+
| bloggs | 1 | 1 |
| jones | 4 | 0 |
I can join the three tables using two LEFT JOINs but how I can aggregate the counts (with or without the WHERE clause) is eluding me.
Am I barking up the wrong tree, so to speak?
This gets you most of the way there:
SELECT
partner_manager_id,
SUM(CASE WHEN active THEN 1 ELSE 0 END) AS n_active_companies,
SUM(CASE WHEN active THEN 0 ELSE 1 END) AS n_inactive_companies
FROM COMPANY
GROUP BY partner_manager_id
The rest of your question is basically asking how to join this result to the remaining tables. As you point out, to do this use JOINs.
SELECT
PARTNER.name,
T1.n_active_companies,
T1.n_inactive_companies
FROM
PARTNER
LEFT JOIN PARTNER_MANAGER ON partner_id = PARTNER.id
LEFT JOIN
(
SELECT
partner_manager_id,
SUM(CASE WHEN active THEN 1 ELSE 0 END) AS n_active_companies,
SUM(CASE WHEN active THEN 0 ELSE 1 END) AS n_inactive_companies
FROM COMPANY
GROUP BY partner_manager_id
) T1
ON T1.partner_manager_id = PARTNER_MANAGER.id
select p.name "Partner Name"
, c1.cnt "n_active_companies"
, c2.cnt "n_inactive_companies"
from partner p
, (select partner_manager_id id, count(partner_manager_id) cnt from company where active = 'true' group by partner_manager_id) c1
, (select partner_manager_id id, count(partner_manager_id) cnt from company where active = 'false' group by partner_manager_id) c2
where c1.id = p.id
and c2.id = p.id
select p.name as 'partner_name',
sum(case when active then 1 else 0) as 'n_active_companies',
sum(case when active then 0 else 1) as 'n_inactive_companies'
from COMPANY c
join PARTNER_MANAGER pm on c.partner_manager_id = pm.id
join PARTNER p on pm.partner_id = p.id
group by p.name