I have those given tables:
In table2 could be multiple rows for "Kost_ID", in output these "Kost_ID" should be only one row. "MW_ID" should be in result "MW"+ number (here "MW5" and "MW6" for "MW_ID" 5+6). Hope this is clear enough.
How could I do this with sql in an oracle db? thanks
Table1
ID Kost_ID Col1
2016 1 bla
2016 2 bla
2016 3 bla1
2016 4 abl
2016 5
2016 6
2016 7
2017 2
2017 3
Table2
ID Kost_ID MW_ID Euro
2016 1 1 10
2016 2 2 20
2016 3 6 30
2016 3 5 40
2016 5 5 50
2016 6 6 60
2016 7 3 70
2016 4 4 80
Result:
ID Kost_ID Col1 MW1 MW2 MW3 MW4 MW5 MW6
2016 1 bla 10
2016 2 bla 20
2016 3 bla1 40 30
2016 4 abl 80
2016 5 50
2016 6 60
2016 7 70
If you don't want to use Pivot Queries you can try with left joins, maybe a little boring, manual and old style
select t1.*,
t21.euro mw1,t22.euro mw2, t23.euro mw3,t24.euro mw4,t25.euro mw5,t26.euro mw6
from
table1 t1 left join table2 t21
on t1.id=t21.id
and t1.kost_id=t21.kost_id
and t21.mw_id=1
left join table2 t22
on t1.id=t22.id
and t1.kost_id=t22.kost_id
and t22.mw_id=2
left join table2 t23
on t1.id=t23.id
and t1.kost_id=t23.kost_id
and t23.mw_id=3
left join table2 t24
on t1.id=t24.id
and t1.kost_id=t24.kost_id
and t24.mw_id=4
left join table2 t25
on t1.id=t25.id
and t1.kost_id=t25.kost_id
and t25.mw_id=5
left join table2 t26
on t1.id=t26.id
and t1.kost_id=t26.kost_id
and t26.mw_id=6
order by t1.id, t1.kost_id
For completness pivot solution mentioned in comments:
select *
from table1 join table2 using (id, kost_id)
pivot (sum(euro) for mw_id in (1 mw1, 2 mw2, 3 mw3, 4 mw4, 5 mw5, 6 mw6))
order by id
Test example
(sorry for the delay)
i came close but it needs some improvement.
select a.ID, a.Kost_ID,a.Col1,
case b.MW_ID when 1 then b.Euro else null end MW1,
case b.MW_ID when 2 then b.Euro else null end MW2,
case b.MW_ID when 3 then b.Euro else null end MW3,
case b.MW_ID when 4 then b.Euro else null end MW4,
case b.MW_ID when 5 then b.Euro else null end MW5,
case b.MW_ID when 6 then b.Euro else null end MW6
from table1 a join table2 b
on (a.ID=b.ID and a.Kost_ID=b.Kost_ID )
ID Kost_ID Col1 MW1 MW2 MW3 MW4 MW5 MW6
2016 1 bla 10 NULL NULL NULL NULL NULL
2016 2 bla NULL 20 NULL NULL NULL NULL
2016 3 bla1 NULL NULL NULL NULL NULL 30
2016 3 bla1 NULL NULL NULL NULL 40 NULL
2016 4 abl NULL NULL NULL 80 NULL NULL
2016 5 NULL NULL NULL NULL NULL 50 NULL
2016 6 NULL NULL NULL NULL NULL NULL 60
2016 7 NULL NULL NULL 70 NULL NULL NULL
Related
I would like to get the representation of one record based on the primary key value from multiple tables. As shown below, each table can have multiple values based on this primary key value.
TABLE-1
ID
NAME
1
AA
2
BB
3
CC
4
DD
5
EE
TABLE-2
ID
SCHOOL
AUT
1
11
A
2
11
A
2
12
B
3
11
A
4
12
A
4
13
B
5
13
A
TABLE-3
ID
TC
1
101
2
102
2
103
2
104
3
105
4
106
4
107
5
108
The result below is the value obtained with an OUTER JOIN.
SELECT
T1.ID, T2.SCHOOL, T3.TC, T2.AUT
FROM
T1
LEFT OUTER JOIN
T2 ON T1.ID = T2.ID
LEFT OUTER JOIN
T3 ON T1.ID = T3.ID
ORDER BY
T1.ID ASC
ID
SCHOOL
TC
AUT
1
11
101
A
2
11
102
A
2
12
102
B
2
11
103
A
2
12
103
B
2
11
104
A
2
12
104
B
3
11
105
A
4
12
106
A
4
13
106
B
4
12
107
A
4
13
107
B
5
13
106
A
How can I get the result like below?
ID
SCHOOL
TC1
TC2
TC3
1
11
101
2
11
102
103
104
3
11
105
4
12
106
107
5
13
108
The important thing here is that in the result value, SCHOOL only shows that AUT is 'A'.
I would appreciate it if you let me know your query.
It looks, from your desired results, you just need to use row_number in combination with a conditional aggregate. Your sample data seems a little inadequate, I can't see any requirement for table1 at all.
Try the following:
with t as (
select t2.id,t2.school,t3.tc, Row_Number() over(partition by t2.id order by t3.tc) col
from t2 join t3 on t2.id=t3.id
where aut='A'
)
select id,school,
max(case when col=1 then tc end) TC1,
max(case when col=2 then tc end) TC2,
max(case when col=3 then tc end) TC3
from t
group by id, school
Example SQL Fiddle
SELECT
T1.ID, T2.SCHOOL,
GROUP_CONCAT(T3.TC),
GROUP_CONCAT(T2.AUT)
FROM
T1
LEFT OUTER JOIN
T2 ON T1.ID = T2.ID
LEFT OUTER JOIN
T3 ON T1.ID = T3.ID
GROUP BY
T1.ID, T2.SCHOOL
WHERE
T2.AUT = ‘A’
ORDER BY
T1.ID ASC
Notice that GROUP_CONCAT concatenates the values in the row.
EDIT: oh my, haven't seen that it's a SQL Server question!
Just replace GROUP_CONCAT with STRING_AGG if you’re using SQL Server 2017 or newer.
I have three tables which look like those:
TABLE 1
id j_id
1 1
2 2
3 3
TABLE 2
id j_id table1_id
1 57 1
2 84 1
3 1 1
4 9 2
5 2 2
and every j has a value in a third table
id value
1 1abc
2 2bcd
3 3abc
57 57abc
84 84abc
9 9abc
I am trying to write a query which will join table 1 and table 2 and use the J value from the third table instead of the j_id, but the problem is that I want to use the j value from the second table if it exists and otherwise use the value from the first table.
in order the make it clearer this is my query result without using the third table:
tbl1.j_id tbl2.j_id
1 1
1 84
1 57
2 2
2 9
3 null
I want the end query result to use the second table's j value unless it is null:
tbl1.j_id tbl2.j_id j_id
1 1 1abc
1 84 84abc
1 57 57abc
2 2 2abc
2 9 9abc
3 null 3abc
(Question and title edits are more than welcome, weren't that sure how to phrase them..)
You can simply JOIN to table3 on the COALESCE of table2.j_id and table1.j_id:
SELECT t1.j_id AS t1_j_id, t2.j_id AS t2_j_id, t3.value
FROM table1 t1
LEFT JOIN table2 t2 ON t2.table1_id = t1.id
JOIN table3 t3 ON t3.id = COALESCE(t2.j_id, t1.j_id)
Output:
t1_j_id t2_j_id value
1 1 1abc
1 57 57abc
1 84 84abc
2 2 2bcd
2 9 9abc
3 null 3abc
Demo on dbfiddle
One solution is to left join table3 twice:
select
t1.j_id,
t2.j_id,
coalesce(t31.value, t32.value) j_value
from
table1 t1
left join table2 t2 on t2.table1_id = t1.id
left join table3 t31 on t31.id = t2.j_id
left join table3 t32 on t32.id = t1.j_id
I have a tree tables table_1, table_2 and table_3, its structures its
table_1
table_2
table_3
In table_1 I have a unit_id and it is general, I want to select data in all tables, for example unit_id = 5 used in table_2 and table_3 and buildings rows is six, parcel rows is two, I want to select six rows building_id, building_area and beside two rows parcel_id and parcel_area, for unit_id = 6 conversely 4 rows parcels and two rows buildings, and one row buildings when unit_id = 7 and one row parcel when unit_id = 8
select result example
unit_id building_id building_area parcel_id parcel_area
5 2 20 15 20
5 3 10 null null
5 4 30 null null
5 5 15 16 10
5 7 25 null null
5 8 15 null null
6 null null 21 30
6 null null 22 50
6 9 18 23 80
6 10 20 24 70
7 30 10 null null
8 null null 27 52
Seems like you want to left join table_2 and table_3 to table_1.
SELECT t1.unit_id,
t2.building_id,
t2.area building_area,
t3.parcel_id,
t3.area parcel_area
FROM table_1 t1
LEFT JOIN table_2 t2
ON t2.unit_id = t1.unit_id
LEFT JOIN table_3 t3
ON t3.unit_id = t1.unit_id;
You do want a left join between all three tables, but by looking at your sample data it seems like you need the relationship between tables 2 and 3 to include the area.
That would be :
SELECT
t1.unit_id,
t2.building_id,
t2.area AS building_area,
t3.parcel_id,
t3.area AS parcel_area
FROM
table_1 AS t1
LEFT JOIN table_2 AS t2
ON t2.unit_id = t1.unit_id
LEFT JOIN table_3 AS t3
ON t3.unit_id = t1.unit_id
AND t3.area = t2.area
I have 2 tables:
Table1 - Criteria
Office_ID Bus_Stream Bus_Criteria Crit_Value
1 ABC 0 20
1 ABC 1 21
1 ABC 2 7
2 ABC 0 15
2 ABC 1 12
2 ABC 2 21
3 XYZ 1 17
3 XYZ 2 3
Table2 - Limit
Bus_Stream GroupID TypeID SubgroupID Bus_Limit
ABC 20 21 7 50
ABC 15 12 21 100
XYZ 99 17 3 120
I need to create a join that allows me to pull back:
Result
Bus_Stream Office_ID GroupID TypeID SubgroupID Bus_Limit
ABC 1 20 21 7 50
ABC 2 15 12 21 100
XYZ 3 (null) 17 3 120
Essentially, I need to join Table1.Crit_Value based on the following:
Table1.Bus_Criteria Table2
0 GroupID
1 TypeID
2 SubGroupID
with the added complication that if one or two of the 0/1/2 values from Bus_Criteria is missing, the joins will still occur on the remaining criteria.
I have tried a number of combinations of AND/OR on the join to no avail.
Any ideas folks?
This may be what you're after.. use a case statement on the join.
The problem here is your data in t2 isn't normalized, you could also unpivot the 3 data columns in t2 so the join is more natural.
SELECT T2.Bus_Stream, T1.Office_ID, T2.GroupID, T2.TypeID, T2.SubGroupId, T2.bus_Limit
FROM T1
INNER JOIN T2
on T1.Bus_Stream = T2.Bus_Stream
and T1.Crit_value = case when T1.Bus_Critiera = 0 then T2.GroupID
when T1.Bus_Critiera = 1 then T2.TypeID
when T1.Bus_Critiera = 2 then T2.SubGroupID
end
Did you try something like this?
SELECT
t1.*, t2.*
FROM Table1 t1
INNER JOIN Table2 t2 ON
t1.Bus_Stream = t2.Bus_Stream AND
CASE
WHEN t1.Bus_Criteria = 0
THEN t2.GroupID = t1.Crit_Value
WHEN t1.Bus_Criteria = 1
THEN t2.TypeID = t1.Crit_Value
ELSE
t2.SubGroupID = t1.Crit_Value
END
I am having one query given below in that Employee, ShiftAllocation, ShiftMaster (two for two shift: Shift1 and shift2) table
SELECT
Em.EmployeeId, Em.EmployeeName,
Sa.ShiftAllocationDate, Sa.ShiftId2, Sa.ShiftId, Sm.ShiftName,
Sm2.ShiftName AS ShiftName2, Sa.ShiftAllocationId
FROM
ShiftAllocation AS Sa
INNER JOIN
EmployeeMaster AS Em ON Sa.EmployeeId = Em.EmployeeId
LEFT OUTER JOIN
ShiftMaster AS Sm2 ON Sa.ShiftId2 = Sm2.ShiftId
LEFT OUTER JOIN
ShiftMaster AS Sm ON Sa.ShiftId = Sm.ShiftId
I am getting this output:
ShiftAlld EmployeeId EmployeeName ShiftAllDate shiftId2 ShifId ShiftName ShiftName2
1 19 XYZ 2011-08-01 NULL 1 General NULL
2 19 XYZ 2011-08-02 NULL 1 General NULL
3 19 XYZ 2011-08-02 NULL -1 NULL NULL
4 19 XYZ 2011-08-02 NULL 1 General NULL
5 19 XYZ 2011-08-02 NULL -2 NULL NULL
6 19 XYZ 2011-08-02 NULL 1 General NULL
I want
shiftId -1 value should assign ShiftName as Week Off
ShiftId -2 value should assign ShiftName as Holiday
ShiftId2 NULL value should assign ShiftName2 as Not Assign
I want this output:
ShiftAlld EmployeeId EmployeeName ShiftAllDate shiftId2 ShifId ShiftName ShiftName2
1 19 XYZ 2011-08-01 NULL 1 General NotAssign
2 19 XYZ 2011-08-02 NULL 1 General NotAssign
3 19 XYZ 2011-08-02 NULL -1 WeekOff NotAssign
4 19 XYZ 2011-08-02 NULL 1 General NotAssign
5 19 XYZ 2011-08-02 NULL -2 Holiday NotAssign
6 19 XYZ 2011-08-02 NULL 1 General NotAssign
You can use a case something like this (untested so there may be any number of typos in there).
select Em.EmployeeId,
Em.EmployeeName,
Sa.ShiftAllocationDate,
Sa.ShiftId2,
Sa.ShiftId,
case when sa.ShiftId = -1 then 'Week Off'
when sa.ShiftId = -2 then 'Holiday'
else sm.ShiftName
end as ShiftName,
case when sm2.ShiftId is null then 'Not assigned'
else Sm2.ShiftName
end as ShiftName2,
Sa.ShiftAllocationId
from ShiftAllocation as Sa
inner join EmployeeMaster as Em
on Sa.EmployeeId = Em.EmployeeId
left outer join ShiftMaster as Sm2
on Sa.ShiftId2 = Sm2.ShiftId
left outer join ShiftMaster as Sm
on Sa.ShiftId = Sm.ShiftId
Although I am not sure if it would be the best way to do it; you can try using CASE in your sql to arrive at a solution.
Edit : This http://www.dba-oracle.com/t_case_sql_clause.htm should help you if you want to try.