Sum with Loop expression - sql

I want to make a calculation over several lines and as a result there should be one result
Table g
| id |Oppervlakte|
| 1 | 10 |
| 2 |12 |
| 3 | 7 |
| 4 | 8 |
table d
| id | gid | Oppervlakte |
| 1 | 1 | 2 |
| 1 | 2 | 3 |
| 1 | 2 | 2 |
| 1 | 2 | 2 |
| 1 | 3 | 1 |
And the result
| id |test |
| 1 | 216 |
my code now is
Select r.id,
sum((g.oppervlakte-sum(d.oppervlakte)*8) as 'test'
from r
join g on g.rid=r.id
join d on d.gid=g.id
join c on c.id = g.Id
where c.cType=0
Group by r.id, g.oppervlakte

You probably just want to aggregate twice, once in a sub-query...
SELECT
r.id,
SUM((g.oppervlakte - d.oppervlakte) * 8) as 'test'
FROM
r
INNER JOIN
g
ON g.rid = r.id
INNER JOIN
(
SELECT
d.gid,
SUM(d.oppervlakte) AS oppervlakte
FROM
d
GROUP BY
d.gid
)
d
ON d.gid = g.id
INNER JOIN
c
ON c.id = g.id
WHERE
c.cType = 0
GROUP BY
r.id

Related

Join across many same tables

Theese are my tables:
users
| id | name |
|----|------|
| 1 | Bob |
| 2 | Adam |
products
| id | Name |
|----|----------|
| 1 | Keyboard |
| 2 | Mouse |
orders
| user_id | product_id |
|---------|------------|
| 1 | 1 |
| 1 | 2 |
| 2 | 1 |
I want to query all Bob orders. I can use that:
select
user_id,
product_id
from
orders o
inner join users u on u.id = o.user_id
inner join products p on p.id = o.product_id
where
o.user_id = 1
Now, for performance reasons, multiple orders tables has been added:
orders
| user_id | product_id |
|---------|------------|
| 1 | 1 |
| 1 | 2 |
| 2 | 1 |
orders_2
| user_id | product_id |
|---------|------------|
| 1 | 4 |
| 6 | 2 |
| 1 | 7 |
orders_3
| user_id | product_id |
|---------|------------|
| 1 | 8 |
| 2 | 2 |
| 4 | 1 |
How can I get all Bob's orders now? Every order_x has the same design as order. Is it possible to join them all in 1 query?
You can filter and union all orders together and then join with product.
select
user_id,
product_id
from
(
select * from orders o1 where o1.user_id = 1
union all
select * from orders_2 o2 where o2.user_id = 1
union all
select * from orders_3 o3 where o3.user_id = 1
) AS o
inner join users u on u.id = o.user_id
inner join products p on p.id = o.product_id

Cte within Cte in SQL

I have been encountered with a situation where I need to apply a where, group by condition on the result of CTE in the CTE.
Table 1 as follows
+---+---+---+---+
| x | y | z | w |
+---+---+---+---+
| 1 | 2 | 3 | 1 |
| 2 | 3 | 4 | 2 |
| 3 | 2 | 5 | 3 |
| 1 | 2 | 6 | 2 |
+---+---+---+---+
Table 2 as follows
+---+---+-----+---+
| a | b | c | d |
+---+---+-----+---+
| 1 | m | 100 | 1 |
| 2 | n | 23 | 2 |
| 4 | o | 34 | 4 |
| 1 | m | 23 | 2 |
+---+---+-----+---+
Assuming I have the data of following sql query in a table called TAB
with cte as (
select x,y,z from table1),
cte1 as (select a,b,c from table2)
select cte.x,cte1.y,cte1.z,cte2.b,cte2.c from cte left join cte1 on cte.x=cte.a and cte1.w=cte2.d
Result of above CTE would be as follows
+---+---+---+---+---+-----+
| x | y | z | w | b | c |
+---+---+---+---+---+-----+
| 1 | 2 | 3 | 1 | m | 100 |
| 2 | 3 | 4 | 2 | n | 23 |
| 1 | 2 | 6 | 2 | m | 23 |
+---+---+---+---+---+-----+
I would like to query the following from the table TAB
select * from TAB where (X||b) in (select (X||b) from TAB group by (X||Y) having sum(c)=123)
I'm trying to formulate the SQL query as follows but it's not as i expected:
select * from (
with cte as (
select x,y,z from table1),
cte1 as (select a,b,c from table2)
select cte.x,cte1.y,cte1.z,cte2.b,cte2.c from cte left join cte1 on cte.x=cte.a) as TAB
where ((X||b) in (select (X||b) from TAB group by (X||Y) having sum(c)=123))
The final result must be as follows
+---+---+---+---+---+-----+
| x | y | z | w | b | c |
+---+---+---+---+---+-----+
| 1 | 2 | 3 | 1 | m | 100 |
| 1 | 2 | 6 | 2 | m | 23 |
+---+---+---+---+---+-----+
I don't think DB2 allows CTEs in subqueries or to be nested. Why not just write this using another CTE?
with cte as (
select x,y,z from
table1
),
cte1 as (
select a,b,c
from table2
),
tab as (
select cte.x,cte1.y,cte1.z,cte1.w,cte2.b,cte2.c
from cte left join
cte1
on cte.x=cte.a and cte1.w=cte2.d
)
select *
from TAB
where (X||b) in (select (X||b) from TAB group by (X||Y) having sum(c)=123);

How to select records from a table which do not have foreign key in another table

I've got 5 tables in my database
I want to select the V_CODE in V which records do not share any S foreign key with F when F_CODE = 'A'.
I tried something like
select distinct V_CODE
from V
inner join V_S VS on V.V_ID = VS.V_FK
inner join S on VS.S_FK = S.S_ID
where S._ID not in (
select FS.S_FK
from F
inner join F_S on F.F_ID = F_S.F_FK
where F.F_CODE = 'A'
);
but this does not return exactly what I want.
Can someone give a help? Thanks in advance.
Table F
| F_ID | F_CODE |
| 1 | A |
| 2 | B |
| 3 | C |
Table F_S
| F_FK | S_FK |
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
Table S
| S_ID | S_CODE |
| 1 | S1 |
| 2 | S2 |
| 3 | S3 |
Table V_S
| V_FK | S_FK |
| 1 | 1 |
| 1 | 2 |
| 2 | 3 |
| 3 | 1 |
| 3 | 3 |
Table V
| V_ID | V_CODE |
| 1 | V1 |
| 2 | V2 |
| 3 | V3 |
In this case I'd want to return only V2 because it's the only record in table V not sharing a record in Table S when F_CODE = 'A'
If I understand correctly, you want v_codes that have no f_code = 'A' when you follow the relationships among the tables.
To me, this suggests not exists:
select v.*
from v
where not exists (select 1
from v_s join
f_s
on v_s.s_fk = f_s.s_fk join
f
on f_s.f_fk = f.f_id
where f.f_code = 'A' and vs.v_fk = v.v_id
);

SQL Query to identify records applicable for a distinct set of data

I have the following query that returns the result as shown below the query. However, I need only a subset of this data. I am interested in fetching DocumentIDs that are associated to RegionID value of 2 ONLY and not associated to any other region.
SELECT D.DocumentID, R.RegionID, COUNT(*) AS NUMOFPLANTSBYREGION
FROM Document D INNER JOIN ShopAreaDoc SAD ON D.DocumentID = SAD.DocumentID
INNER JOIN PlantShopAreaDoc PSAD ON SAD.ShopAreaDocID = PSAD.ShopAreaDocID
INNER JOIN Plant P ON PSAD.PlantID = P.PlantID
INNER JOIN Region R ON P.RegionID = R.RegionID
GROUP BY D.DocumentID, R.RegionID
ORDER BY D.DocumentID
Query Results:
+------------+----------+---------------------+
| DocumentID | RegionID | NUMOFPLANTSBYREGION |
+------------+----------+---------------------+
| 2126 | 2 | 8 |
| 2127 | 2 | 8 |
| 2128 | 2 | 8 |
| 2129 | 2 | 8 |
| 2130 | 2 | 8 |
| 2134 | 4 | 13 |
| 2135 | 3 | 8 |
| 2136 | 6 | 9 |
| 2137 | 2 | 8 |
| 2138 | 3 | 8 |
| 2138 | 1 | 20 |
| 2138 | 6 | 9 |
| 2138 | 4 | 14 |
| 2138 | 2 | 8 |
| 2139 | 1 | 17 |
| 2140 | 1 | 17 |
+------------+----------+---------------------+
The Result Set I am interested in as follows:
Other records are either not applicable to Region ID of 2 or applicable to more regions in addition to 2 and so should be excluded.
+------------+----------+----------------------+
| DocumentID | RegionID | NUMOFPLANTSBYREGION |
+------------+----------+----------------------+
| 2126 | 2 | 8 |
| 2127 | 2 | 8 |
| 2128 | 2 | 8 |
| 2129 | 2 | 8 |
| 2130 | 2 | 8 |
| 2137 | 2 | 8 |
+------------+----------+----------------------+
using a common table expression and not exists():
;with cte as (
SELECT D.DocumentID, R.RegionID, COUNT(*) AS NUMOFPLANTSBYREGION
FROM Document D INNER JOIN ShopAreaDoc SAD ON D.DocumentID = SAD.DocumentID
INNER JOIN PlantShopAreaDoc PSAD ON SAD.ShopAreaDocID = PSAD.ShopAreaDocID
INNER JOIN Plant P ON PSAD.PlantID = P.PlantID
INNER JOIN Region R ON P.RegionID = R.RegionID
GROUP BY D.DocumentID, R.RegionID
)
select *
from cte
where not exists (
select 1
from cte i
where i.DocumentID = cte.DocumentID
and i.RegionID <> 2
)
rextester demo: http://rextester.com/DUIE27467
returns:
+------------+----------+----------------------+
| DocumentID | RegionID | NUMOFPLANTSBYREGION |
+------------+----------+----------------------+
| 2126 | 2 | 8 |
| 2127 | 2 | 8 |
| 2128 | 2 | 8 |
| 2129 | 2 | 8 |
| 2130 | 2 | 8 |
| 2137 | 2 | 8 |
+------------+----------+----------------------+
SELECT D.DocumentID, R.RegionID, COUNT(*) AS NUMOFPLANTSBYREGION
FROM Document D
INNER JOIN ShopAreaDoc SAD ON D.DocumentID = SAD.DocumentID
INNER JOIN PlantShopAreaDoc PSAD ON SAD.ShopAreaDocID = PSAD.ShopAreaDocID
INNER JOIN Plant P ON PSAD.PlantID = P.PlantID
INNER JOIN Region R ON P.RegionID = R.RegionID
WHERE R.RegionId = 2
AND NOT EXISTS (SELECT * FROM Region R2 WHERE R2.RegionId <> 2 AND R2.DocumentId = D.documentid)
GROUP BY D.DocumentID, R.RegionID
ORDER BY D.DocumentID
You may use this approach, implementing the MINUS statement (which does not exists in MySQL by the way):
SELECT DocumentID FROM docs WHERE RegionID=2 AND DocumentID NOT IN (SELECT DocumentID FROM docs WHERE RegionID<>2)
I also tried it on http://sqlfiddle.com/#!9/66f0e8/57 and it seems to work.

SQL select from 3 table

I have 3 tables:
ssu:
id (primary key)
ssu_number
agreement:
agreement_id
agreement_number
agreement_status_fk
agreement_type_fk
agreement_ssu:
ssu_id
agreement_fk
I need to select ssu_number which occur at least 2 times as ssu_id in table agreement_ssu, which have agreement_status_fk = 1 and agreement_type_fk = 1.
Here is my select but i think it will be not work (i cant test it now):
select
*
from
asd.ssu p
join tdd.agreement_ssu ap on p.id = ap.ssu
join tdd.agreement ae on ae.id = ap.AGREEMENT_FK
join
(
select
ssu_id
from
tdd.agreement_ssu
group by
ssu_ID
having
count( ssu_id ) > 1 )
y on y.ssu_id = p.ID
where
ae.AGREEMENT_TYPE_FK = 1
and
ae.agreement_status_fk = 1;
Example
ssu
| id | ssu_number|
| 1 | 2000 |
| 2 | 2001 |
| 3 | 2002 |
| 4 | 2003 |
agreement
| agreement_id | agreement_number | agreement_status_fk | agreement_type_fk |
| 1 | da5as6d | 1 | 1 |
| 2 | d57as6 | 1 | 2 |
| 3 | dsjks6d | 2 | 2 |
| 4 | d4s7sad | 1 | 1 |
| 5 | d43790d | 1 | 1 |
| 6 | d437s6d | 1 | 1 |
| 7 | d4aq36d | 1 | 2 |
agreement_ssu
| ssu_id | agreement_fk |
| 1 | 1 |
| 1 | 2 |
| 2 | 6 |
| 2 | 4 |
| 2 | 7 |
| 3 | 3 |
| 4 | 5 |
And from select i should get only ssu_number: 2001 (occurs 2 times in agreement_ssu and both have agreement_status_fk = 1 and agreement_type_fk = 1)
| ssu_number |
| 2001 |
I have not setup the exact scenario, and not checked this code, but I think something along these lines is what you want:
SELECT
ssu.ssu_number
FROM
ssu
INNER JOIN
(
SELECT
assu.ssu_id
FROM
agreement_ssu assu
INNER JOIN
agreement a on a.agreement_id = assu.agreement_fk
GROUP BY
assu.ssu_id
WHERE
a.agreement_status_fk = 1
AND a.agreement_type_fk = 1
HAVING
COUNT(assu.ssu_id) > 1
) IT ON ssu.id = IT.ssu_id
Regards...
This should do it,
SELECT SSU.SSU_NUMBER
FROM SSU
JOIN AGREEMENT_SSU
ON SSU.ID = AGREEMENT_SSU.SSU_ID
JOIN AGREEMENT
ON AGREEMENT.ID = AGREEMENT_SSU.AGREEMENT_FK
WHERE AGREEMENT.AGREEMENT_STATUS_FK = 1
AND AGREEMENT.AGREEMENT_TYPE_FK = 1
GROUP BY SSU.SSU_NUMBER
HAVING COUNT(*) > 1;