Add a zero record when count is 0 - sql

I want to list BR, BRANCHNAME and the number of people employed in it. There are 5 branches it total and only 4 of them have people employed in it; Branch 05 has no employees in it. After using the following code, the branch 05 will not be shown as the row of branch 05 will not be included after the where statement. I want to show a row of "05 Br05 0".
SELECT EMPLOYEE.BR, BRANCHNAME, Count(*) AS Number
FROM EMPLOYEE, BRANCH
WHERE (EMPLOYEE.BR = BRANCH.BR)
GROUP BY EMPLOYEE.BR, BRANCHNAME;
The result is:
BR BRANCHNAME Number
01 Br01 6
02 Br02 4
03 Br03 5
04 Br04 6
I want to have the following result:
BR BRANCHNAME Number
01 Br01 6
02 Br02 4
03 Br03 5
04 Br04 6
05 Br05 0

It would seem you want a LEFT JOIN which gives a countable row with a null result even if there is no matching employee.
Since you've not added your table structure, I assume branchname is a field in the branch table.
SELECT branch.br, branch.branchname, COUNT(employee.br) AS Number
FROM branch
LEFT JOIN employee
ON branch.br = employee.br
GROUP BY branch.br, branch.branchname
An SQLfiddle to test with (based on SQL Server since Access is not available)

Related

SQL sum up sales volume for different customer locations

I'm using Oracle SQL-developer and I got the following output-table, which shows the monthly sales value of our customers. The customers have several locations.
month
year
customer_name
sales_volume
01
2022
Farming company Berlin
150
01
2022
Farming company London
200
01
2022
Farming company Amsterdam
350
01
2022
XY Company Berlin
200
01
2022
customer 5
7
01
2022
customer 7
7
01
2022
X_Person
2
02
2022
XY Company London
100
02
2022
Hello Company Berlin
150
02
2022
Hello Company Amsterdam
150
02
2022
customer 1
20
02
2022
customer 2
10
02
2022
customer 3
5
02
2022
Y-Person
1
Now I'd like to get the sales_volume per customer_name for month/year. I want to add the sales_volume per month/year for all the different locations of the Farming company, the XY Company and the Hello Company. The rest (customer 1-7, X-Person, Y-Person) should be summed up in an own row named "Other"
The new output table would be the following:
month
year
customer_name
sum_Sales_volume
01
2022
Farming Company
700
01
2022
XY Company
300
01
2022
Other
16
02
2022
XY Company
100
02
2022
Hello Company
300
02
2022
Other
36
So far I tried to sum the customer_name with LIKE function but I don't understand how the "when then" works in this case.
My code:
Select
month,
year,
sum(sales_volume)
CASE
WHEN customer_name LIKE '%Farming%' Then 'Farming Company'
WHEN customer_name LIKE '%XY%' Then 'XY Company'
WHEN customer_name LIKE '%Hello%' Then 'Hello Company'
ELSE THEN 'Standard'
END AS "sum_Sales_volume"
I don't understand how the "when then" works in this case.
In a LIKE comparison, % is a wildcard character that matches zero-or-more of any character.
So, for WHEN customer_name LIKE '%Farming%', you are testing to see if the customer_name value has:
The start-of-the-string; then
Zero-or-more of any character; then
The sub-string Farming; then
Zero-or-more of any character; and
Finally, the end-of-the-string.
If it matches then the value of the THEN clause of the CASE expression is returned; otherwise the next WHEN clause is tested and so on until if none of the WHEN clauses are matched then the value from the ELSE clause is returned.
how can I sum up the values from the sales_volume column based on this string I'm searching in customer name.
Just use your CASE expression in the GROUP BY clause:
Select month,
year,
CASE
WHEN customer_name LIKE '%Farming%'
THEN 'Farming Company'
WHEN customer_name LIKE '%XY%'
THEN 'XY Company'
WHEN customer_name LIKE '%Hello%'
THEN 'Hello Company'
ELSE 'Standard'
END AS customer_name,
sum(sales_volume) AS sum_sales_volume
FROM table_name
GROUP BY
month,
year,
CASE
WHEN customer_name LIKE '%Farming%'
THEN 'Farming Company'
WHEN customer_name LIKE '%XY%'
THEN 'XY Company'
WHEN customer_name LIKE '%Hello%'
THEN 'Hello Company'
ELSE 'Standard'
END;
As MTO already answered the question, but from the comment it seems there are some more things to explain I'll try to clarify some possible missunderstandings about LIKE() function with % wildcard and especially about CASE expression. All of the below code and results refers to your sample data.
% wildcard character stands for (replaces) none or any string/array of characters
Oracle character comparisons are case sensitive
Just a few samples:
Select A_NAME From tbl Where A_NAME Like('%Berlin%'); -- any string containing 'Berlin' -with first capital letter
-- Result: Farming company Berlin
-- XY Company Berlin
-- Hello Company Berlin
Select A_NAME From tbl Where A_NAME Like('%berlin%'); -- any string containing 'berlin' -with first small letter
-- Result: no rows selected
Select A_NAME From tbl Where A_NAME Like('%1'); --any string that ends with character '1' -including just '1'
-- Result: customer 1
Select A_NAME From tbl Where A_NAME Like('cust%3'); --any string starting with 'cust' and ending with '3'
-- Result: customer 3
Select A_NAME From tbl Where A_NAME Like('Far%on'); -- any string starting with 'Far' and ending with 'on'
-- Result: Farming company London
CASE expresssion - the most important thing to know is the fact that CASE evaluates WHEN conditions until the first one satisfied (True). When that happens CASE returns the value and ends checking possible other WHEN conditions. It is very important to have this in mind when using CASE with multiple WHEN conditions.
In the below code compare two CASE expressions selected - with coresponding values of columns DESCRIPTION_1 and DESCRIPTION_2. The ressulting differences are more than obvious and the only difference between the CASE expressions used is the order of WHEN conditions.
Select A_MONTH, A_YEAR, A_NAME, VOLUME,
CASE WHEN VOLUME >= 100 THEN '100 plus'
WHEN VOLUME >= 200 THEN '200 plus'
WHEN VOLUME >= 300 THEN '300 plus'
ELSE 'less than 100'
END "DESCRIPTION_1",
CASE WHEN VOLUME >= 300 THEN '300 plus'
WHEN VOLUME >= 200 THEN '200 plus'
WHEN VOLUME >= 100 THEN '100 plus'
ELSE 'less than 100'
END "DESCRIPTION_2"
From tbl
/* R e s u l t :
A_MONTH A_YEAR A_NAME VOLUME DESCRIPTION_1 DESCRIPTION_2
------- ---------- ------------------------- ---------- ------------- -------------
01 2022 Farming company Berlin 150 100 plus 100 plus
01 2022 Farming company London 200 100 plus 200 plus
01 2022 Farming company Amsterdam 350 100 plus 300 plus
01 2022 XY Company Berlin 200 100 plus 200 plus
01 2022 customer 5 7 less than 100 less than 100
01 2022 customer 7 7 less than 100 less than 100
01 2022 X_Person 2 less than 100 less than 100
02 2022 XY Company London 100 100 plus 100 plus
02 2022 Hello Company Berlin 150 100 plus 100 plus
02 2022 Hello Company Amsterdam 150 100 plus 100 plus
02 2022 customer 1 20 less than 100 less than 100
02 2022 customer 2 10 less than 100 less than 100
02 2022 customer 3 5 less than 100 less than 100
02 2022 Y-Person 1 less than 100 less than 100
*/
Hopefuly this could help you to better understand the % wildcard, LIKE() function and CASE expression and what to have in mind combining them.
Regards...

inner join when the key is two columns

I need to create a summary table Which is a summary of the targets and sales.
Here are the tables.
target_table
customer_id
month
target
101
05
60
101
06
60
102
05
80
102
05
85
selse_table
customer_id
month
selse
101
05
40
101
06
70
102
05
90
102
05
60
Here is my query
CREATE TABLE SUMMERY
AS SELECT SALSE.customrt_id, SALSE.month, SALSE.selse, targets.target
FROM SALSE
Inner join TARGETS
on SALSE.CUSTOMER_ID=TARGETS.customer_ID
I try to use INNER JOIN but the problem is that it is not enough for me just the customer_id column because the same customer has different destinations every month.
Is my query correct? How to do the INNER JOIN right?
Don't understand your question very well,like this?
on SALSE.CUSTOMER_ID=TARGETS.customer_ID and SALSE.[MONTH]=TARGETS.[MONTH]

Fantasy Football Data postgre sql Get first instance

So i have a table that has draft history. call it "Draft Results".
team_id pick_number round position playerID
0002 01 01 WR 12
0002 01 02 QB 09
0002 01 03 TE 32
0002 01 04 RB 23
0034 02 01 WR 43
0034 02 02 WR 24
0034 02 03 QB 04
0034 02 04 QB 11
Only each team id has a pick for 20 rounds. I have about 7000 team_ids. I want to total which round each team took their first qb and I need help figuring out a sql query to accomplish that.
SELECT "Round", COUNT("Team_Id") FROM public."Draft Results"
WHERE "Position" = 'QB'
GROUP BY "Round"
ORDER BY "Round" asc
there are 5 different positions: 'QB', 'RB', 'WR', 'TE', 'D'
In this instance i would want the query to show that here was 1 team with a first qb selected in the 2nd round and 1 team where their first QB was selected in the 3rd. Currently my query would show what i mentioned AND that 1 team selected a QB in the 4th round. Even though that was not that teams FIRST QB selected (they already picked one in the 3rd)
Isn't it simple aggregation with min:
select team_id,
min(round) as round
from "Draft Results"
where position = 'QB'
group by team_id;
Perhaps try MIN() aggregate function on the "Round" column
SELECT MIN("Round"), COUNT("Team_Id") FROM public."Draft Results"
WHERE "Position" = 'QB'
GROUP BY "Round"
ORDER BY "Round" asc
This would then grab the minimum value for the "Round" column which would be the first or lowest 'round' that Position would be 'QB'. In your example, team_id 0034 selected a 'QB' in round 03 and round 04 but selecting the MIN() value of those two would select the first instance or lowest round they chose a 'QB' in which would be the 3rd round. I hope this helps and that I understand what you are trying to accomplish.
If you want to see the whole table, but constrained to the rows you want returned by virtue of the earliest round logic, I would use this:
SELECT *
FROM draft_results d
INNER JOIN (
SELECT team_id, MIN(round_id) minRndQBPicked
FROM draft_results d
WHERE position = 'QB'
GROUP BY team_id
) minRnd ON d.team_id = minRnd.team_id AND d.round_id = minRnd.round_id

Count matching pairs

This is a little complicated so bear with me. Below is a table named "list" with 2 columns. The table has data of each member and the films that they like. i.e member 01 likes film 02, 05, 14, 21 and 25. What I want to find out is how many similar films does each member have with another member. For example, member 01 and member 02 have one film in common (film 14). Is there any way to write this in SQL?
List
------ ------
member film
------ ------
01 02
01 05
01 14
01 21
01 25
02 03
02 09
02 14
03 01
03 05
03 17
03 21
You can write a general query for this using a self-join and aggregation. The following summarizes the results for each pair of users:
select l1.member, l2.member, count(*) as NumFilmsInCommon
from list l1 join
list l2
on l1.member < l2.member and l1.film = l2.film
group by l1.member, l2.member;
The < condition just ensures that each pair of members only appears once in the result set.

SQL: how to select IDs according to a condition?

I just started to program in SQL and I have a bit of a problem (n.b., I am working of a tabl that come from a game). My table is something like this, where ID refers to a single person, H to a certain hour of playing and IF to a certain condition:
ID H IF
01 1 0
01 2 0
01 3 0
02 1 0
02 2 1
03 1 0
03 2 1
03 3 0
03 4 1
In this case player 01 played for three hours, player 02 for two hours and player 03 for four hours. In each of these hours they may or may have not performed an action. If they did, a 1 appears in the IF column.
Now, my doubt is: how can I query so that I have a table with only the ID of the people who never performed the action? I do not want to rule out only the row with IF = 1, I want to rule out all the row with that ID. In this case it should become:
01 1 0
01 2 0
01 3 0
Any help?
This should do it.
select *
from table
where Id not in (select Id from table where IF = 1)
SELECT ID FROM Table GROUP BY ID HAVING SUM(IF)=0