join with lookup and group by - sql

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')

Related

SQL split one column into two columns based on values and use columns

Table: ProductionOrder
Id Ordernumber Lotsize
1 Order1 50
2 Order 2 75
3 WO-order1 1
4 WO-order2 1
Table: history
Id ProductionOrderID Completed
1 3 1
2 3 1
3 4 1
4 4 1
Table: ProductionOrderDetail
ID ProductionOrderID ProductionOrderDetailDefID Content
1 1 16 50
2 1 17 7-1-2018
3 2 16 75
4 2 17 7-6-2018
Start of my code:
Select p.ID, p.OrderNumber,
Case productionOrderDetailDefID
Where(Select pd1.productionOrderDetailDefID where ProductionOrderDetialDefID = 16) then min(pd1.content)
from ProductionOrder p
Left join History h1 on p.id = h1.productionOrderID
Left Join ProductionOrderDetail pd1 on p.ID = ProductionOrderID
The result in trying to get is
Id Ordernumber Lotsize Productionorder Completed
1 Order1 50 WO-order1 2
2 Order 2 75 WO-order2 2
Any help would be appreciated.
Try this
SELECT ordernumber,lotsize,Ordernumber,count(Ordernumberid)
FROM productionorder inner join history on productionorder.id = history.Ordernumberid
GROUP BY Ordernumber;
A bit of weird joins going on here. You should add this to a SQL fiddle so that we can see our work easier.
A link to SQL fiddle: http://sqlfiddle.com/
Here is my first attempt
SELECT
po.id
, po.ordernumber
, po.lotsize
, po2.productionorder
, SUM(h.completed)
FROM productionorder as po
INNER JOIN history as h
ON h.id = po.id
INNER JOIN prodcuctionorder as po2
ON po2.ordernumberid = h.ordernumberid
WHERE po.id NOT EXISTS IN ( SELECT ordernumberid FROM history )
GROUP BY
po.id
, po.ordernumber
, po.lotzise
, po2.productionorder
How far does that get you?

Query to get translation for each languages

Please help me to create query. I have table with languages like
Id Code
---------
1 EN
2 DE
3 RU
and table with translations
Id Code LanguageId Value
------------------------------------------
1 1 1 EnglishTranslation
2 1 3 RussianTranslation
3 2 1 EnglishTranslation
4 2 2 DeutschTranslation
5 3 1 EnglishTranslation
I'm trying to get this result
Id Code LanguageId Value
------------------------------------------
1 1 1 EnglishTranslation
1 1 2 NULL
2 1 3 RussianTranslation
3 2 1 EnglishTranslation
4 2 2 DeutschTranslation
4 2 3 NULL
5 3 1 EnglishTranslation
5 3 2 NULL
5 3 3 NULL
Need to get translations for all languages by Code from Translations table So far I try
select
T.id, T.Code, L.Id, T.Value
from Languages L
left join Translations T on T.LanguageId = L.Id
but I got not expected result. Could you please suggest
http://sqlfiddle.com/#!6/e9bed/1
You can use CROSS JOIN operator to construct a cartesian product of (LanguageId, Code) pairs, and left-join translation table to it:
SELECT
t.Id, y.Code, x.LanguageId, t.Value
FROM
((SELECT Id AS LanguageId FROM Languages) AS x
CROSS JOIN
(SELECT DISTINCT(Code) AS Code FROM Translations) AS y)
LEFT OUTER JOIN Translations t ON y.Code=t.Code AND x.LanguageId=t.LanguageId
ORDER BY t.Code, t.LanguageId
Note that this wouldn't produce a valid translation Id for rows missing from Translations, i.e. the result would look like this:
Id Code LanguageId Value
---------------------------------------------
1 1 1 EnglishTranslation
NULL 1 2 NULL
2 1 3 RussianTranslation
3 2 1 EnglishTranslation
4 2 2 DeutschTranslation
NULL 2 3 NULL
5 3 1 EnglishTranslation
NULL 3 2 NULL
NULL 3 3 NULL
Demo.
I resolved the issue and got the result that you expected.
Run the below query:
SELECT
(CASE
WHEN T.Id is null and lc.Code = 1 THEN 1
WHEN T.Id is null and lc.Code = 2 THEN 4
WHEN T.Id is null and lc.Code = 3 THEN 5
ELSE T.Id
END) as Id,
lc.Code, lc.Id as LanguageId, T.Value from
(SELECT x.Id, y.Code from (SELECT Id FROM Languages) x cross join (SELECT DISTINCT(Code) as Code FROM Translations) y) as lc
left outer join Translations T ON lc.Id = T.LanguageId and lc.Code = T.Code
order by Id, Code, LanguageId
You can also see the solution in the below link:
http://sqlfiddle.com/#!6/e9bed/30
Hopefully it will work as you like.

Show null and not num values

My query
with with_user_earns as (
-- get father information (start)
select father.id, father.str_name, father.id_father, father.ind_father_side_type, 1 as int_user_level from tb_user father where id = #v_user_id
union all
-- get son information (stop condition)
select son.id, son.str_name, son.id_father, son.ind_father_side_type, WUE.int_user_level + 1
from tb_user as son inner join with_user_earns as WUE on son.id_father = WUE.id
where son.id_father is not null and WUE.int_user_level < #v_max_level
)
select aux.*
from (
-- show result
select with_user_earns.id id_son, with_user_earns.str_name str_son_name, with_user_earns.id_father, father.str_name str_father_name, with_user_earns.ind_father_side_type, with_user_earns.int_user_level, isnull(sum(o.int_score), 0) as int_score
from with_user_earns inner join tb_order o on o.id_user = with_user_earns.id
inner join tb_user as father on father.id = with_user_earns.id_father
where o.dt_insert between #v_cycle_begin and #v_cycle_end and o.ind_payment_status = 3
group by with_user_earns.id, with_user_earns.str_name, with_user_earns.id_father, with_user_earns.ind_father_side_type, with_user_earns.int_user_level, father.str_name
) as aux
order by aux.int_user_level, aux.id_son
The table with_user_earns contains a lot of users (mult nivel hierarchy).
Then I want to join with tb_order to get int_score 0 if the user sell nothing and if the user sell anything I want the sum of it.
I tried put left join, full outer join, ... But no one works perfect
What a need to do?
My result:
id_son int_score
1 100
2 11100
3 100
10 300
Expected result:
id_son int_score
1 100
2 11100
3 100
4 0
5 0
6 0
7 0
8 0
9 0
10 300

Oracle Outer join with 0 value return for non existing rows

I have 2 tables
Person
--------------------
id name dept_id
---------------------
1 x 1
2 y 1
3 z 2
Feedback
------------------------------------
person_id f_date positive negative
------------------------------------
1 2014-05-05 10 4
1 2014-05-15 5 3
2 2014-05-11 3 8
Now my query is
SELECT p.id,
nvl(sum(positive),0) AS pf,
nvl(sum(negative),0) AS nf
FROM person p
LEFT OUTER JOIN feedback f ON p.id = f.person_id
WHERE f_date BETWEEN to_date('2014-05-04', 'YYYY-MM-DD')
AND to_date('2014-05-16', 'YYYY-MM-DD')
GROUP BY p.id
ORDER BY p.id;
I expect to see
id pf nf
---------------
1 15 7
2 3 8
3 0 0
but I don't see the the data for 3. In fact the data i get is only if the rows exist in feedback table as if its an equi join.
Your WHERE clause is turning the outer join into an inner join. The solution is to move the condition to the ON clause:
SELECT p.id, nvl(sum(positive),0) as pf, nvl(sum(negative),0) as nf
FROM person p left outer JOIN
feedback f
on p.id = f.person_id and
f.f_date between to_date('2014-05-04', 'YYYY-MM-DD') AND to_date('2014-05-16', 'YYYY-MM-DD')
GROUP BY p.id
ORDER BY p.id;

Avoid repeatation of rows for every instance when joined with a table

Hi i have 3 tables and i am trying to join them to get a desire table. I have tried group by and temp tables options to get the desired table but no help. I want to avoid duplicates for every instance of a value in one table from another table.
Table 1 Customer Table:
CstId CstDetails CstType
---------- --------------- ------------
1 address 1 1
2 address 2 1
3 address 3 1
4 address 4 2
5 address 5 2
Table 2 Customer Relationship:
CstId CstGroupId
---------- ----------------
1 4 (this is same as CustomerId)
2 5 (this is same as CustomerId)
3 4 (this is same as CustomerId)
Table 3 Customer Notes:
CstId NotesId NoteTxt
----------- --------- ---------
1 1 note11
1 2 note12
1 3 note13
3 1 note31
4 1 note41
4 2 note42
4 3 note43
4 4 note44
4 5 note45
Now i want the result to be in the below format
Table result:
(NoteId) (Notetxt) (NoteId) (Notetxt)
CstId CstDetails CstGroupId CstNoteId CstNote CstGroupNoteId CstGroupNote
1 address1 4 1 note11 1 note41
1 address1 4 2 note12 2 note42
1 address1 4 3 note13 3 note43
1 address1 4 null null 4 note44
1 address1 4 null null 5 note45
But i am getting CstGroupNote repeated for all the CstNote, which i am trying to avoid.
Is there a way i could achieve this result?
Below is the code i use:
select c.cstid, c.cstdetails, cn.cstnotesid, cn.cstnotetxt
insert into temp1
from customer c
left outer join customernotes cn
on c.cstid = cn.cstid
where c.customertypeid = 1
select cr.cstid, cr.cstgroupid, cn.cstgroupnoteid, cn.cstnotetxt
insert into temp2
from customerrelationship cr
left outer join customernotes cn
on cr.cstgroupid = cn.customerid
select t1.cstid, t1.cstdetails, t1.cstnotesid, t1.cstnotetxt, t2.cstgroupnoteid, t2.cstnotetext
from temp1 t1
left outer join t2
on t1.cstid = t2.cstid
Try:
select CstId,
max(CstDetails) CstDetails,
max(CstGroupId) CstGroupId,
max(CstNoteId) CstNoteId,
max(CstNote) CstNote,
max(CstGroupNoteId) CstGroupNoteId,
max(CstGroupNote) CstGroupNote
from
(select c.CstId,
c.CstDetails,
0 CstGroupId,
n.NotesId CmbNotesId,
n.NotesId CstNoteId,
n.NoteTxt CstNote,
0 CstGroupNoteId,
'' CstGroupNote
from customer c
left outer join customernotes n on c.cstid = n.cstid
where c.customertypeid = 1
union all
select c.CstId,
c.CstDetails,
r.CstGroupId,
n.NotesId CmbNotesId,
0 CstNoteId,
'' CstNote,
n.NotesId CstGroupNoteId,
n.NoteTxt CstGroupNote
from customer c
left outer join customerrelationship r on c.cstid = r.cstid
left outer join customernotes n on r.CstGroupId = n.cstid
where c.customertypeid = 1) u
group by CstId, CmbNotesId
Use a derived table and an outer join
The trick there is the
and cn.cstnotesid = cG.cstnotesid
to link those two on one row
select c.cstid, c.cstdetails, cn.cstnotesid, cn.cstnotetxt
,cG.CstGroupId, cG.cstnotesid, cG.cstnotetxt
from customer c
join customernotes cn
on cn.cstid = c.cstid
outer join (select c.cstid, c.CstGroupId, cn.cstnotesid, cn.cstnotetxt
from customer c
join customernotes cn
on cn.cstid = c.CstGroupId) as cG
on c.cstid = cG.cstid
and cn.cstnotesid = cG.cstnotesid
order by c.cstid, cn.cstnotesid, cG.cstnotesid