Firebird SQL join tables - sql

Currently I have tables like these:
Table Customer
ID Name
01 Angel
02 Charlie
Table Input1
Name Value
Charlie 5
Angel 7
Charlie 10
Angel 3
Table Input2
Name Value
Charlie 10
Angel 5
Charlie 15
Angel 25
How to get result like this
Name Input1 Input2
Angel 10 30
Charlie 15 25

Try this:
SELECT
c.Name,
i1."Value" value1,
i2."Value" value2
FROM
Customer c LEFT JOIN
(SELECT Name, SUM("Value") "Value" from input1 group by Name) i1
ON c.Name = i1.Name LEFT JOIN
(SELECT Name, SUM("Value") "Value" from input2 group by Name) i2
ON c.Name = i2.Name
DEMO
http://sqlfiddle.com/#!9/204220/2

Related

I have 2 tables and I need to use SQL to return non matching data/columns

I have 2 tables with same number of columns. tablea has 5 rows and tableb has 4 rows with 2 matching rows and 3 non matching rows. I need to return all 3 non matching columns/data
The query below only returns the non matching column in table and not all the non matching columns. I'am trying to return non matching rows 3,4,5 . see table below
select *
from tablea
where not exists (select * from tableb
where tableb.id = tablea.id)
Table a:
id contact name address city postalcode country
———————————————
1 ab aa 123 hd 12 usa
2 as bb 321 hh 23 mex
3 av cc 571 hn 123 mex
4 as ww 457 bd 57 uk
5 chat xx 23 dh 123 fin
Table b:
id contact name address city postalcode country
————————————————
1 ab aa 123 hd 12 usa
2 as bb 321 hh 23 mex
3 ad ah 3200 res 321 mex
4 ash bb 457 hsj 1223 uk
I am not 100% sure on what rows you want exactly, as your text is kinda contradictionary, but if you want the 3 not matching rows from tableb this is what you need to do:
SELECT * FROM tableb WHERE customerid NOT IN (SELECT customerid FROM tablea)
If you want the ones not matching from tablea, you just need to change tablea with tableb and vice versa.
If you want all not matching, combine both options:
SELECT * FROM tablea, tableb WHERE tablea.customerid NOT IN (SELECT customerid from tableb) AND tableb.customerid NOT IN (SELECT customerid from tablea)

Return something based on the number of time it appears in SQL

id cars price
1 bmw
1 corvette
1 mercedes
2 bmw
3 bmw
3 toyota
4 bmw
4 honda
5 lotus
I found this table from another post and just wanted to use it for my question.
Suppose the ids represent owners and they own multiple cars and some owners have the same car.
I want to write a query such that given a number n and an owner(id)
I can return the cars that the owner has and there are a total of n of these cars in the table.
For example if
I'm given id 1 and n = 4 then it will return
bmw
if I'm given id 1 and n = 1 then it will return
corvette
mercedes
I figured out that
select cars from table group by cars having count(cars) = 4
Gives me all the cars that appear 4 times in the table but I want to narrow it down to a car that is owned by a certain car owner.
Thanks for helping
Method 3 :
select * from
(
select f1.*, rownumber() over(partition by f1.car) rang
from yourtable f1
) f2
where f2.rang=4 and f1.id=1
Method 1 :
with totalcar
(
select car, count(*) nb
from yourtable
group by car
)
select * from yourtable f1 inner join totalcar f2 on f1.car=f2.car
where f1.id=1 and f2.nb=4
Method 2 :
select * from yourtable f1
inner join lateral
(
select f2.car
from yourtable f2
where f1.car=f2.car
group by f2.car
having count(*)=4
) f3 on 1=1
where f1.id=1

how to get Unique data from one table and the other

If I want to display Order_Number data1 data2 data3 (most current by date changed OtherData1, OtherData2, OtherData3) date_changed the problem is I wasn't just one line, I was getting multiple lines for each order number.
What I would love to get is
1, a, f,q, cc,ccc,abc, 12/2/2014, bob
3, c, b,h, aa,aaa,abc, 12/2/2014, bob
Thanks!
I was working with
SELECT
t.Order_Number,
cr.data1, cr.data2, cr.data3,
t.OtherData1, t.OtherData2, t.OtherData3,
x.date_changed, cr.name
FROM
(SELECT
Order_Number,
Max(date_changed) as date_changed
FROM
table2
GROUP BY
Order_Number) x
JOIN
table2 t ON x.date_changed = t.date_changed
LEFT JOIN
table1 cr ON x.Order_Number = cr.Order_Number
WHERE cr.name = 'bob'
Here are example tables.
Table1:
Order_Number data1 data2 data3 name
1 a f q bob
2 b g g john
3 c b h bob
4 d s j john
Table2:
Order_Number date_changed OtherData1 OtherData2 OtherData3
1 11/30/2014 aa aaa abc
1 12/1/2014 bb bbb def
1 12/2/2014 cc ccc abc
3 12/1/2014 dd aaa def
2 11/30/2014 dd bbb abc
2 12/1/2014 ss ccc def
3 12/2/2014 aa aaa abc
4 11/26/2014 fc wer wsd
Your Join to config_log (Table2) needs to include the entire composite key if you want to retrieve unique rows.
JOIN
conf_log t ON x.date_changed = t.date_changed
And x.Order_Number = t.Order_number
I think you need to have 2 sub querys:
SELECT
Data.Order_Number,
Data.data1, Data.data2, Data.data3,
Data.OtherData1, Data.OtherData2, Data.OtherData3,
Data.date_changed, Data.name
FROM
(SELECT
Order_Number,
Max(date_changed) as date_changed
FROM
table2
GROUP BY
Order_Number) x
JOIN (SELECT
t.Order_Number,
cr.data1, cr.data2, cr.data3,
t.OtherData1, t.OtherData2, t.OtherData3,
t.date_changed, cr.name
FROM table2 t
JOIN table1 cr
ON t.Order_Number = cr.Order_Number) AS Data
ON x.date_changed = data.date_changed
AND x.Order_Number = data.Order_number
WHERE cr.name = 'bob'
The fact that you had cr.name in the where clause means the LEFT JOIN had the same affect as just JOIN.

cross joining two tables

I have a table that looks like this, lets call this table B.
id boardid schoolid subject cnt1 cnt2 cnt3 ....
=================================================================
1 20 21 f
2 20 21 r
3 20 21 w
4 20 21 m
5 20 30 r
6 20 30 w
7 20 30 m
Suppose the counts are just integers. Notice that there is no subject = f for schoolid = 30. Similarly, for most schools, some subject dosnt exist. You might have a schoolid that has just r, w or some that are just r, m, f..
So what I want to do is have 4 consistent rows for each school, and the row that dosnt exist I want dummy values. I thought about creating a secondary table
drop table #A
Select * into #A FROM
(
select [subject_s] = 'r', orderNo = 1
union all
select [subject_s] = 'w', orderNo = 2
union all
select [subject_s] = 'm', orderNo = 3
union all
select [subject_s] = 'f', orderNo = 4
) z
and doing some joins on them, but I've gotten NO where. I've tried inner join, left outer, cross join, everything. I've even tried to make cartesian product. I think my cartesian product messes up because I have orderno in there so it makes 16 rows per row in the main table. Actually typing this out, I realize if I remove the orderno, apply the cartesian product and then add orderno in later, it might work but I am interested to see what you guys can come up with. I am stumped.
End result
id boardid schoolid subject cnt1 cnt2 cnt3 ....
=================================================================
1 20 21 r
2 20 21 w
3 20 21 m
4 20 21 f
5 20 30 r
6 20 30 w
7 20 30 m
7 20 30 f
Try the following:
SELECT S.boardid, S.schoolid, A.[subject], B.cnt1, B.cnt2, B.cnt3
FROM (SELECT DISTINCT boardid, schoolid FROM YourTable) S
CROSS JOIN #A A
LEFT JOIN YourTable B
ON B.boardid = S.boardid AND B.schoolid = S.schoolid
AND A.[subject] = B.[subject]
Since I do not know which RDBMS you are using I tried the following with sqlite and a simpler table:
sqlite> create table schools (name varchar, subject varchar, teacher varchar);
sqlite> select * from schools;
School1|Maths|Mr Smith
School2|English|Jack
School3|English|Jimmy
School3|Maths|Jane
School4|Computer Science|Bob
sqlite> select
schoolnames.name,
subjects.subject,
ifnull(teachers.teacher, "Unknown")
from (select distinct name from schools) schoolnames
join (select distinct subject from schools) subjects
left join schools teachers
on schoolnames.name = teachers.name
and subjects.subject = teachers.subject;
School1|Maths|Mr Smith
School1|English|Unknown
School1|Computer Science|Unknown
School2|Maths|Unknown
School2|English|Jack
School2|Computer Science|Unknown
School3|Maths|Jane
School3|English|Jimmy
School3|Computer Science|Unknown
School4|Maths|Unknown
School4|English|Unknown
School4|Computer Science|Bob
I'd use:
SELECT
boardid, schoolid, dist_subject, id, cnt1, ...
FROM
(SELECT
boardid, schoolid, dist_subject
FROM
(SELECT
DISTINCT subject AS dist_subject
FROM b ) s full outer join
(SELECT
boardid, schoolid
FROM b
GROUP BY
boardid, schoolid ) g ) sg LEFT OUTER JOIN
b ON
sg.boardID = b.boardID AND
sg.schoolid = b.schoolID
sg.dist_subject = b.subject

SQL Select From Master - Detail Tables

I have two tables, named t_master and t_detail.
The data in the t_detail table corresponds to a record on the master table.
Data of t_master
ID Brand
1 Toyota
2 Honda
Data for the t_detail
DetID ParentID Model
1 1 Corolla 2009
2 1 Corolla 2010
3 1 Corolla 2011
4 2 Civic 2004
5 2 Civic 2006
Now, I want to make a query that should select all rows in the master table and at the same time, select the detail which has the latest ID (max), i.e.
ID Brand DetID ParentID Model
1 Toyota 3 1 Corolla 2011
2 Honda 5 2 Civic 2006
Appreciate your help. Thanks.
Use:
SELECT m.id,
m.brand,
x.detid,
x.parentid,
x.model
FROM T_MASTER m
JOIN T_DETAIL x ON x.parentid = m.id
JOIN (SELECT d.parentid,
MAX(d.detid) AS max_detid
FROM T_DETAIL d
GROUP BY d.parentid) y ON y.max_detid = x.detid
AND y.parentid = x.parentid
SELECT Make.ID, Make.Brand, Model.DetID, Model.Model
FROM t_master Make
INNER JOIN t_detail Model ON Make.ID = Model.ParentID
WHERE
DetID =
(
SELECT MAX(DetID) From t_detail WHERE ParentID = Make.ID
)
Please note that if you have more rows in Master Table and there are no rows in Detail Table that fits , but you still want to show ALL master table rows then you should initiate the below :
( Please note that you have to add 2 more rows to the master table)
for example :
ID Brand
1 Toyota
2 Honda
3 Porsche
4. Volvo
In order to get the following result :
ID BRAND DETID PARENTID MODEL
1 Toyota 3 1 Corolla 2011
2 Honda 5 2 Civic 2006
4 Volvo - - -
3 Porcshe - - -
Then do the following select (a bit different syntax for the ease of Oracle Users) :
SELECT m.id,
m.brand,
x.detid,
x.parentid,
x.model
FROM T_MASTER m,
T_DETAIL x,
(SELECT m.id,NVL(MAX(d.detid),1) AS max_detid
FROM T_DETAIL d, T_MASTER m
WHERE m.id = d.parentid (+)
GROUP BY m.id) y
WHERE m.id = x.parentid (+)
AND y.max_detid = NVL(x.detid,1)
AND y.id = m.id