sql join gives cumulative results - sql

I want to join county and county_type tables and get only those county that doesnt have a type =30. From below example id = 1 and 3 should only be the expected output
county
id name zipcode
1 LC 12345
2 WC 98765
3 AC 09876
4 VC 90876
county_type
id type
1 10
1 20
2 10
2 20
2 30
3 10
3 20
4 10
4 20
4 30
output:
id name zipcode
1 LC 12345
3 AC 09876
Tried this:
select *.c from county c, county_type ct
where c.id = ct.id
and ct.id != 30
order by c.id asc;
what i am getting is cumulative:
id name zipcode
1 LC 12345
1 LC 12345
2 WC 98765
2 WC 98765........///

You want not exists:
select c.*
from county c
where not exists (select 1
from county_type ct
where ct.id = c.id and ct.type = 30
);

Related

How to make a view with 2 tables linked by another table?

I have 3 table
driver
id
first name
last_name
age
1
Joe
doe
26
2
John
smith
31
...
...
...
...
Location
id
name
zipcode
country
1
London
250 329
UK
2
NY
00501
USA
...
...
...
...
Travel
id
Person_id
location_id
nb_passenger
1
1
1
2
2
1
1
4
3
2
2
3
4
1
2
2
5
2
1
3
...
...
...
...
I'm looking to create a view to get the total number of passengers by destination and by driver, but it's taking the same row multiple times
I tried something like that but it didn't work
SELECT location.id AS location_id,
location.name AS location_name,
d.id AS driver_id,
d.name AS driver_name,
sum(tr.passenger) as passenger_count
FROM location
LEFT JOIN travel tr_0 ON location.id = tr_0.location_id
LEFT JOIN driver d ON tr_0.driver_id = d.id
LEFT JOIN travel tr ON location.id = tr.location_id AND tr.driver_id = d.id
GROUP BY location.id, location.name,...;
I'm sure it's simple but I'm not on the right way

join with lookup and group by

i have 2 tables like below:
lk_premier:
code descr
P Premier
N Non Premier
Case:
id taxPin
1 123
2 789
Status:
id voting_status premier
1 5 P
1 5 P
1 5 P
2 5 P
2 5 N
2 5 null
3 5 null
3 5 null
3 5 null
3 5 null
3 5 null
I used the below sql
select
decode(premier,
'P',
'PREMIER',
'N',
'NON PREMIER') as caseStatus,
count(*) as count
from
status s,
case c
where
c.id = s.id
and c.id = 1
and s.voting_status = 5
group by
premier
I want to join the lk_premier table, so my output looks like for id=2,
caseStatus count
PREMIER 1
NON PREMIER 1
for id = 3
caseStatus count
PREMIER 0
NON PREMIER 0
You should never do joins this way -- this way of doing joins was depreciated about 20 years ago. the join should look like this:
join status s on c.id = s.id
once you do joins the right way then how you do left joins is easier as seen below:
here you go
select
coalesce(p.desc,'unknown') as caseStatus,
count(*) as count
from case c
join status s on c.id = s.id
left join lk_premier p on p.code = c.premier
where c.id = 1 and s.voting_status = 5
group by coalesce(p.desc,'unknown')

Query the sum of some cells in a table based on an id in another table

Let assume that we have two tables named family_data and person_info as below:
# family_data
person_id | family_id
1 1
2 2
3 1
4 1
5 2
# person_info
person_id | weight
1 50
2 80
3 30
4 60
5 40
How can I have a table which contains pairs of (family_id, sum_of_members_weight) as below:
# Query output:
family_id | total_weight
1 140
2 120
You can join and aggregate:
select f.family_id, sum(p.weight) total_weight
from family_data f
inner join person_info p on p.person_id = f.person_id
group by f.family_id

I don't have the right answer in SQL

List the project numbers (PR_NO) for projects that have only received parts that are stored in (P_CITY) the same city as the project (show output of the query).
Table: EMP
Primary Key: E_NO
E_NO E_NAME E_RATE E_DEPT
1 A $400.00
2 B $200.00 1
3 C $150.00 2
4 D $150.00 3
5 E $120.00 1
6 F $100.00 1
7 G $100.00 2
8 H $50.00 2
9 I $50.00 3
10 J $50.00 3
11 K $150.00 3
Table: PART
Primary Key: P_NO
P_NO P_NAME P_CITY
1 P1 NY
2 P2 NY
3 P3 LA
4 P4 SF
5 P5 LA
6 P6 NY
Table: PROJECT
Primary Key: PR_NO
PR_NO PR_MGR PR_DEPT PR_LOC
1 2 1 NY
2 3 2 LA
3 2 1 NY
Table: SUPPLIER
Primary Key: S_NO
S_NO S_NAME S_LOC
1 S1 NY
2 S2 NY
3 S3 LA
Table: SUPPLY
Primary Key: P_NO + PR_NO + S_NO
Foreign Key: P_NO references PART
Foreign Key: PR_NO references PROJECT
Foreign Key: S_NO references SUPPLIER
P_NO PR_NO S_NO QTY
1 1 1 111
1 1 2 112
1 1 3 113
1 2 1 121
1 2 2 122
1 2 3 123
1 3 1 131
1 3 2 132
1 3 3 133
2 1 1 211
3 1 1 311
4 1 1 411
5 1 1 511
6 1 1 611
Table: WORK
Primary Key: E_NO + PR_NO
Foreign Key: E_NO references EMP
Foreign Key: PR_NO references PROJECT
E_NO PR_NO HRS
2 1 10
3 2 20
5 1 20
5 2 20
5 3 20
6 1 10
6 2 10
select distinct P.PR_NO
from PROJECT P, PART PA
where PA.P_CITY = P.PR_LOC;
The right answer question should be :
PR_NO
3
This is the error:
PR_NO
1
3
2
In order to achieve this task, you also need to use Supply table as follows:
select s.pr_no
from supply s
inner join part p
on p.p_no = s.p_no
group by s.pr_no
having max(p.p_city) = min(p.p_city)
and min(p.p_city) = (select pr_loc
from project
where pr_no = s.pr_no
)
I tested this query with your example data and it returns project #3 as expected:
SELECT DISTINCT S.PR_NO
FROM
SUPPLY S
INNER JOIN PROJECT PR
ON S.PR_NO = PR.PR_NO
INNER JOIN PART P
ON S.P_NO = P.P_NO
WHERE
PR.PR_LOC = P.P_CITY AND
NOT S.PR_NO IN
(
SELECT S2.PR_NO
FROM
SUPPLY S2
INNER JOIN PROJECT PR2
ON S2.PR_NO = PR2.PR_NO
INNER JOIN PART P2
ON S2.P_NO = P2.P_NO
WHERE PR2.PR_LOC <> P2.P_CITY
)
The SUPPLY table creates the link between PART and PROJECT. The main query looks for parts that are stored in the same city as the project. The sub-select in the where clause looks almost the same, except that it looks for parts stored in a different city. Projects with such cities are excluded with NOT S.PR_NO IN (...).
The main issue in your query is that you should correctly join the 2 tables PROJECT and PART before filtering; so in this case you should use the table SUPPLY.
SELECT DISTINCT S.PR_NO
FROM SUPPLY S
INNER JOIN PROJECT PR
ON S.PR_NO = PR.PR_NO
INNER JOIN PART P
ON S.P_NO = P.P_NO
WHERE PR.PR_LOC = P.P_CITY
AND S.PR_NO NOT IN ( SELECT DISTINCT S.PR_NO
FROM SUPPLY S
INNER JOIN PROJECT PR
ON S.PR_NO = PR.PR_NO
INNER JOIN PART P
ON S.P_NO = P.P_NO
WHERE PR.PR_LOC <> P.P_CITY );
Hope this helps!

Show COUNT of each possible grade for an employee, showing zero when there are no grade entries

I have only one table available. I want to show the grade and the count of the number of times an employee has that grade recorded, but it must show a 0 for the grade if there are no records for that employee. I know how to do this using left join when two tables are present, but I only have 1 table.
How is this possible?
For example:
TABLE
empID | dept | grade
1 | 11 | a
2 | 11 | a
3 | 11 | b
1 | 22 | c
2 | 22 | f
3 | 22 | d
1 | 33 | a
2 | 33 | a
3 | 33 | a
If I run SELECT grade, count(grade) from table where empID = 1 Group by grade;, for example, it ends up printing out only grades the employee got and the count. Now I want to also print out the 0s for grades the employee did not have.
i think you're asking for this?
SQL> select e.grade, count(e2.empid)
2 from (select distinct grade from e) e
3 left outer join e e2
4 on e2.grade = e.grade
5 and e2.empid = 1
6 group by e.grade
7 order by grade;
G COUNT(E2.EMPID)
- ---------------
a 2
b 0
c 1
d 0
f 0
or as you have no rows with "e" grade then if you have a lookup table called grade:
SQL> select * from grade;
G
-
a
b
c
d
e
f
SQL> select e.grade, count(e2.empid)
2 from grade emp
3 left outer join emp e2
4 on e2.grade = e.grade
5 and e2.empid = 1
6 group by e.grade
7 order by grade;
G COUNT(E2.EMPID)
- ---------------
a 2
b 0
c 1
d 0
e 0
f 0
Let's say your query to select a value is:
select value from tbl;
You can ensure a 0 is returned if there are no rows in tbl t:
select nvl(t.value, 0) value
from dual d
left join tbl t on 1=1;
Sounds like you want the NVL function. With NVL, you can conditionally return an alternate value if the value is null. See the documentation.
So, if you had the following...
SELECT fooName, fooNumber FROM foo
and these were your results
fooName, fooNumber
Blah, 1
Asdf, null
Qwer, 3
poiu, null
you could rewrite the query like this...
SELECT fooName, NVL(fooNumber, 0) FROM foo
and your results would now be...
fooName, fooNumber
Blah, 1
Asdf, 0
Qwer, 3
poiu, 0
http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions105.htm