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
);
3 tables:
Mark table:
student_id sa_id marks
1 1 75
1 2 80
1 3 100
2 4 85
2 5 90
2 6 60
course table:
course_code sat_id name_code
AAA 100 1 midterm1
AAA 100 2 midterm2
AAA 100 3 final
BBB 200 4 midterm1
BBB 200 5 midterm2
BBB 200 6 final
transform table:
sa_id sat_id
1 1
2 2
3 3
4 4
5 5
6 6
select course.course_code, mark.marks
from mark
left outer join transform on transform.sa_id = mark.sa_id
left outer join course on course.sat_id = transfrom.sat_id
where course.name_code = 'midterm1'
At the above query only midterm1 result, also we can extract mid2 and final
select mark.student_id,course.course_code, mark.marks, course.name_code
from mark
left outer join transform on transform.sa_id = mark.sa_id
left outer join course on course.sat_id = transfrom.sat_id
order by mark.student_id, course.course_code
Result will give:
student_id course_code marks name_code
1 AAA 100 75 midterm1
1 AAA 100 80 midterm2
1 AAA 100 100 final
2 BBB 200 85 midterm1
2 BBB 200 90 midterm2
2 BBB 200 60 final
So how to build query that should be
student_id course_code midterm1 midterm2 final
1 AAA 100 75 80 100
2 BBB 200 85 90 60
You can use case when , group by (and a fake aggregation function)
select
student_id
, course_code
, max(case when name_code ='midterm1' then mark else null) midterm1
, max(case when name_code ='midterm2' then mark else null) midterm2
, max(case when name_code ='final' then mark else null) final
from mark
left outer join transform on transform.sa_id = mark.sa_id
left outer join course on course.sat_id = transfrom.sat_id
group by student_id, course_code
order by mark.student_id, course.course_code
But if you don't like aggregation functio you can use a 3 seleft join on mark
select
mm1.student_id
, mm1.course_code
, mm1.mark midterm1
, mm2.mark midterm2
, mm3.mark finale
from mark as mm1
left join mark as mm2 on mm1.student_id = mm2.student_id and mm1.course_code = mm2.course_code
left join mark as mm3 on mm1.student_id = mm3.student_id and mm1.course_code = mm3.course_code
left outer join transform on transform.sa_id = mm1.sa_id
left outer join course on course.sat_id = transfrom.sat_id
where mm1.name_code = 'midterm1'
and mm2.name_code = 'midterm2'
and mm3.name_code = 'final'
I have a Location table in SQL Server:
LocationId | LocationName | Address
========================================
15 AA 111 AAA
17 CC 999 CCC
And I have a Worksite table with WorksiteMark = Null
WorksiteId | WorksiteName | Address | LocationId | WorksiteMark
======================================================================
1 AA 111 AAA 15 Null
2 P 23 P 15 Null
3 F 78 F 15 Null
4 H 16 H 17 Null
5 CC 999 CCC 17 Null
6 W 78 W 17 Null
Finally I need to update WorksiteMark = WorksiteId reference with Location table and I will delete the Location table
WorksiteId | WorksiteName | Address | WorksiteMark
========================================================
1 AA 111 AAA 1
2 P 23 P 1
3 F 78 F 1
4 H 16 H 5
5 CC 999 CCC 5
6 W 78 W 5
Can you help me to create a script for updating WorksiteMark = WorksiteId referencing the Location table?
Thanks
Hope This works for you.
Update W
SET W.WorksiteMark = L1.WorksiteId
FROM #Worksite AS W
INNER JOIN (Select L.LocationId,W2.WorksiteId FROM #Location L INNER JOIN
#Worksite W2 ON L.LocationName = W2.WorkSiteName) AS L1
ON W.LocationId = l1.LocationId
UPDATE [dbo].[Worksite]
SET WorksiteMark = (SELECT WorksiteId FROM [dbo].[Worksite] B WHERE B.WorksiteNAME = [dbo].[Location].LocationName)
from [dbo].[Worksite]
inner join [dbo].[Location] on [dbo].[Location].[LocationId] = [dbo].[Worksite].LocationId
You need a double JOIN with your update, something like;
UPDATE W
SET W.WorksiteMark = W2.WorksiteId
FROM Worksite AS W
INNER JOIN Location AS L
ON L.LocationId = W.LocationId
INNER JOIN Worksite AS W2
ON W2.WorksiteName = L.LocationName
i need help from your side:
I have two tables t1 and t2 having below data:
TABLE t1
ID PROP_ID County_code prop_type
1 abc IE A
2 bcd US P
3 cde CA P
4 def IND P
5 efg CHINA P
table T2
ID PROP_IND PROD_ID Amount
10 A 200
20 P US 300
30 P CA 400
40 P IND 500
50 P CHINA 600
60 P 700
in table t2 1 prop_id is null for Prop_ind A and one for prop_id p.
I am making a join between these two tables like below:
decode(t1.prop_type,'A',t1.prop_id,'P',t1.country_code) =
NVL(t2.prop_id, decode(t2.prop_ind,'A',t1.prop_id,'P',t1.country_code))
But this join gives me incorrect result. As null prop_id for prop_ind A and P in table t2 are default values.
select *
from t1,t2
where decode(t1.prop_type,'A',t1.prop_id,'P',t1.county_code) = NVL(t2.prop_id, decode(t2.prop_ind,'A',t1.prop_id,'P',t1.county_code))
this query gives me 9 records however i am looking only 5 records – user2862073 7 mins ago
output came in as:
ID PROP_ID COUNTY_CODE PROP_TYPE ID PROP_IND PROP_ID AMOUNT
3 cde CA P 60 P - 700
3 cde CA P 30 P CA 400
5 efg CHINA P 50 P CHINA 600
5 efg CHINA P 60 P - 700
1 abc IE A 10 A - 200
4 def IND P 40 P IND 500
4 def IND P 60 P - 700
2 bcd US P 60 P - 700
2 bcd US P 20 P US 300
however i am looking only 5 records and it should be
ID PROP_ID County_code prop_type Amount
1 abc IE A 200
2 bcd US P 300
3 cde CA P 400
4 def IND P 500
5 efg CHINA P 600
Please suggest me how to make join on this in correct way.
This is bound to happen.
For example:
select Decode(t1.prop_type, 'A', t1.prop_id,
'P', t1.county_code) from t1;
Gives you
abc
US
CA
IND
CHINA
Whereas
select Nvl(t2.prop_id,
Decode(t2.prop_ind, 'A', t1.prop_id,
'P', t1.county_code)) from t1,t2;
And this gives you
abc
US
CA
IND
CHINA
IE
bcd
US
CA
IND
CHINA
US
cde
US
CA
IND
CHINA
CA
def
US
CA
IND
CHINA
IND
efg
US
CA
IND
CHINA
CHINA
Since there is no unique column to be joined in t1 and t2, it goes on for a cartesian join on 6*5 = 30 rows. So the last row in T2 will not be able to find one single match in T1.
Hence when you run
SELECT t1.id,
t1.prop_id,
t1.county_code,
t1.prop_type,
t2.amount
FROM t1,
t2
WHERE Decode(t1.prop_type, 'A', t1.prop_id,
'P', t1.county_code) = Nvl(t2.prop_id,
Decode(t2.prop_ind, 'A', t1.prop_id,
'P', t1.county_code)) ;
you get
ID PROP_ID COUNTY_CODE PROP_TYPE AMOUNT
1 abc IE A 200
2 bcd US P 300
2 bcd US P 700
3 cde CA P 400
3 cde CA P 700
4 def IND P 500
4 def IND P 700
5 efg CHINA P 600
5 efg CHINA P 700
May be this would do
If you want to avoid hardcoding, then you need to select the decode options from a inline query
SELECT t1.id,
t1.prop_id,
t1.county_code,
t1.prop_type,
nvl (t2.amount,decode(t1.prop_type,'A',200,'P',700))
from t1 left outer join t2 on t1.prop_type = t2.PROP_IND
and t1.County_code = t2.prop_id
order by t1.id;
I think you need this join:
select t1.id, t1.prop_id, t1.county_code, t1.prop_type, t2.amount
from t1 join t2
on (t1.prop_type = 'A' and t2.prop_ind='A' and t2.prod_id is null)
or (t1.prop_type = 'P' and t1.county_code = t2.prod_id)
Output:
ID PROP_ID COUNTY_CODE PROP_TYPE AMOUNT
---------- ------- ----------- --------- ----------
1 abc IE A 200
2 bcd US P 300
3 cde CA P 400
4 def IND P 500
5 efg CHINA P 600
SQL Fiddle
Oracle 11g R2 Schema Setup:
CREATE TABLE t1 ( ID, PROP_ID, County_code, prop_type ) AS
SELECT 1, 'abc', 'IE', 'A' FROM DUAL
UNION ALL SELECT 2, 'bcd', 'US', 'P' FROM DUAL
UNION ALL SELECT 3, 'cde', 'CA', 'P' FROM DUAL
UNION ALL SELECT 4, 'def', 'IND', 'P' FROM DUAL
UNION ALL SELECT 5, 'efg', 'CHINA', 'P' FROM DUAL;
CREATE TABLE t2 ( ID, PROP_IND, PROD_ID, Amount ) AS
SELECT 10, 'A', NULL, '200' FROM DUAL
UNION ALL SELECT 20, 'P', 'US', '300' FROM DUAL
UNION ALL SELECT 30, 'P', 'CA', '400' FROM DUAL
UNION ALL SELECT 40, 'P', 'IND', '500' FROM DUAL
UNION ALL SELECT 50, 'P', 'CHINA', '600' FROM DUAL
UNION ALL SELECT 60, 'P', NULL, '700' FROM DUAL
Query 1:
select t1.*, t2.AMOUNT
from t1 INNER JOIN t2
ON ( t1.PROP_TYPE = t2.PROP_IND
AND ( ( t1.PROP_TYPE = 'P' AND t1.County_Code = t2.prod_id )
OR ( t1.PROP_TYPE = 'A' AND (t1.PROP_ID = t2.PROD_ID OR t2.PROD_ID IS NULL ) )
)
)
Results:
| ID | PROP_ID | COUNTY_CODE | PROP_TYPE | AMOUNT |
|----|---------|-------------|-----------|--------|
| 1 | abc | IE | A | 200 |
| 2 | bcd | US | P | 300 |
| 3 | cde | CA | P | 400 |
| 4 | def | IND | P | 500 |
| 5 | efg | CHINA | P | 600 |
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