I am completely New to SQL queries and need help in combining some select statements together to form one single query.
I will start one query at a time:
select sum(DOCI)
from (
select POL.SP_NUM, sum(Q.AMT + POL.AMT) DOCI
from S_ASSET POL
, S_QUOTE_ITEM Q
where POL.X_QUOTE_ID = Q.ROW_ID
and POL.SP_NUM in ('000','111','222')
group by POL.SP_NUM
UNION ALL
select POL.SP_NUM, sum(QXM.AMT) DOCI
from S_ASSET POL
, S_QUOTE_ITEM Q
, S_QUOTE_ITEM_XM QXM
where POL.X_QUOTE_ID = Q.ROW_ID
and Q.ROW_ID = QXM.PAR_ROW_ID
and POL.SP_NUM in ('000','111','222')
group by POL.SP_NUM
)
Tables:
S_ASSET
X_QUOTE_ID POL AMT
A 000 1
B 111 1
C 222 1
S_QUOTE_ITEM
ROW_ID AMT
A 10
B 10
C 1
S_QUOTE_ITEM_XM
PAR_ROW_ID AMT
A 10
B 0
Expected O/P:
POL AMT(sum)
A 21
B 11
C 2
Please help
SELECT sp_num, SUM(doci)
FROM ( ...subquery... )
GROUP BY sp_num;
The table name pol only exists inside the subquery. The outer query is selecting from the result of the subquery, not from any named table.
Related
I am unable to generate a looping kind of behaviour in a SQL query.
I am having two tables:
Table A
Id Brand Prod_Id Alt_Prod_Id
1 A 2 5
2 B 3 9
3 C 5 9
Table B
Id Prod_Id Rate
1 2 5
2 3 9
2 5 7
2 9 9
Rate in Table B needs to be looked up for each brands Prod_ID & Alt_Prod_Id & select the least value between 2 found value
The expected result / output is:
Brand Min_Prod_Val
A 5
B 9
C 7
Can this be done in a query?
Thanks!
You could join tableb twice (once for prod_id, another for alt_prod_id), and then select the smallest rate:
select
a.brand,
least(b1.rate, b2.rate) min_prod_val
from tablea a
inner join tableb b1 on b1.prod_id = a.prod_id
inner join tableb b2 on b2.prod_id = a.alt_prod_id
It is unclear which database you are using. If that's SQL Server: it does not support least(), so you need a case expression:
case when b1.rate < b2.rate then b1.rate else b2.rate end min_prod_val
You can use a single join and GROUP BY the brand:
SELECT a.Brand,
MIN( b.rate ) AS min_prod_val
FROM TableA A
INNER JOIN TableB b
ON ( b.prod_id IN ( a.prod_id, a.alt_prod_id ) )
GROUP BY a.Brand
Or you can use a correlated sub-query:
SELECT a.Brand,
(
SELECT MIN( rate )
FROM TableB b
WHERE b.prod_id IN ( a.prod_id, a.alt_prod_id )
) AS min_prod_val
FROM TableA A
db<>fiddle
I would like a result of
ID received total
2 25 25
from ItemReceived table
ID item received
2 1 5
2 2 2
2 1 10
2 2 8
and ItemsToReceive table
ID item quantity
2 1 15
2 2 10
Is there a way to get this result?
I used this code:
SELECT sum(ItemsToReceive.quantity), SUM( ItemReceived.received)
FROM ItemsToReceive
INNER JOIN ItemReceived ON ItemReceived.ID = ItemsToReceive.ID
GROUP BY poitems.poid
I got a wrong result making received to 50...
Can anyone help me?
Try this
select t1.Id,t1.quantity, t2.received from
(
SELECT ID,sum(quantity) quantity from ItemsToReceive group by id
) as t1 inner join
(
SELECT ID,SUM(received) as received from ItemReceived group by id
) as t2 on t1.id=t2.id
This might help
;WITH quantity AS (
SELECT sum(ItemsToReceive.quantity) As TotQuant
,ItemsToReceive.id AS id
FROM ItemsToReceive
GROUP BY ItemsToReceive.id
), Prod As (
SELECT SUM( ItemReceived.received) As TotRec
,ItemReceived.ID As Id
FROM ItemReceived
GROUP BY ItemReceived.ID
)
SELECT
q.Id
,p.TotRec As Received
,q.TotQuant As Quantity
FROM quantity q
INNER JOIN Prod p on p.Id = q.id
select ID , sum(received) , sum(quantity) from ItemReceived left join ItemsToReceive on (ItemReceived.ID = ItemsToReceive.ID and ItemReceived.item = ItemsToReceive.item) group by ID
i wish to apply a Group By condition to my SQL below so that the O/P will display POL# with GP.
select t.POl#, (DEB.CUSTD - CRED.CUSTC) AS GP
from (
(
select POL.SP_NUM POL#
, sum(D.AMT) AS CUSTD
from S_INVOICE D
, S_ASSET POL
where POL.ROW_ID = D.FN_ACCNT_ID
and POL.SP_NUM in ('000','111','222')
and D.DEBIT_TYPE = 'Customer'
group by POL.SP_NUM
) DEB
CROSS JOIN
(
select pol.SP_NUM POL#
, sum(C.AMT) AS CUSTC
from S_SRC_PAYMENT C
, S_ASSET POL
where POL.ROW_ID = C.ASSET_ID
and POL.SP_NUM in ('000','111','222')
and C.CG_DEDN_TYPE_CD = 'Customer'
group by POL.SP_NUM
) CRED
) t
group by t.POL#
When i execute the same I am getting "ORA-00933: SQL command not properly ended" error, where the cursor points to 't'
Kindly assist.
Expected O/P:
POL# GP
000 800
111 120
222 50
Appending Sample Data with explanation for better understanding of requirement:
Table 1:
S_ASSET
ROW_ID POL#
1 000
2 111
3 222
4 333
5 444
Table 2:
S_INVOICE (Debit Table)
FN_ACCNT_ID POL# DEBIT_TYPE AMT
1 000 Customer 10
1 000 Customer 10
1 000 Insurer 5
2 111 Customer 10
3 222 Customer 10
3 222 Insurer 5
5 444 Insurer 10
Table 3:
S_SRC_PAYMENT (Credit Table)
ASSET_ID POL# CG_DEDN_TYPE_CD AMT
1 000 Insurer 10
1 000 Insurer 10
1 000 Customer 5
2 111 Insurer 10
3 222 Insurer 5
3 222 Insurer 5
3 222 Customer 5
5 444 Customer 10
As per this query I will consider "Customer" records per POL# and SUM the AMT. (Every Debit for the Customer will Credit Insurer(s) per POL# & vice-versa)
Expected O/P (Sum of Debits - Sum of Credits) for a Customer per POL#
POL # AMT (GP)
000 15
111 10
222 5
333 0
444 -10
You obviously only want to get the deb and cred per s_asset and then aggregate so as to get the sums. You can do this without a join and subquery the sums directly instead:
select
sp_num as pol#,
sum(<get deb sum for the pol.row_id here>) - sum(<get cred sum for the pol.row_id here>)
from s_asset pol
where sp_num in ('000','111','222')
group by sp_num;
The complete query:
select
sp_num as pol#,
coalesce(sum(
(
select sum(deb.amt)
from s_invoice deb
where deb.fn_accnt_id = pol.row_id
and deb.debit_type = 'Customer'
)
), 0) -
coalesce(sum(
(
select sum(cred.amt)
from s_src_payment cred
where cred.asset_id = pol.row_id
and cred.cg_dedn_type_cd = 'Customer'
), 0)
) as gp
from s_asset pol
where sp_num in ('000','111','222')
group by sp_num;
The same with joins instead:
select
pol.sp_num as pol#,
coalesce(sum(deb.total), 0) - coalesce(sum(cred.total), 0) as gp
from s_asset pol
left join
(
select fn_accnt_id as pol_row_id, sum(deb.amt) as total
from s_invoice
where debit_type = 'Customer'
group by fn_accnt_id
) deb on deb.pol_row_id = pol.row_id
left join
(
select asset_id as pol_row_id, sum(amt) as total
from s_src_payment
where cg_dedn_type_cd = 'Customer'
group by asset_id
) cred on cred.pol_row_id = pol.row_id
group by pol.sp_num;
This syntax
from ( (select ...) CROSS JOIN (select ...) )
is invalid. A JOIN belongs to a FROM. So either of these would be correct:
from ( SELECT * FROM (select ...) CROSS JOIN (select ...) )
or
from (select ...) CROSS JOIN (select ...)
However, are you sure you want a CROSS JOIN at all? Both subqueries give you POL numbers plus data, bat rather than joining them on POL#, you cross join the results, so you get all POL# combinations instead.
I have a table_1:
id custno
1 1
2 2
3 3
and a table_2:
id custno qty descr
1 1 10 a
2 1 7 b
3 2 4 c
4 3 7 d
5 1 5 e
6 1 5 f
When I run this query to show the minimum order quantities from every customer:
SELECT DISTINCT table_1.custno,table_2.qty,table_2.descr
FROM table_1
LEFT OUTER JOIN table_2
ON table_1.custno = table_2.custno AND qty = (SELECT MIN(qty) FROM table_2
WHERE table_2.custno = table_1.custno )
Then I get this result:
custno qty descr
1 5 e
1 5 f
2 4 c
3 7 d
Customer 1 appears twice each time with the same minimum qty (& a different description) but I only want to see customer 1 appear once. I don't care if that is the record with 'e' as a description or 'f' as a description.
First of all... I'm not sure why you need to include table_1 in the queries to begin with:
select custno, min(qty) as min_qty
from table_2
group by custno;
But just in case there is other information that you need that wasn't included in the question:
select table_1.custno, ifnull(min(qty),0) as min_qty
from table_1
left outer join table_2
on table_1.custno = table_2.custno
group by table_1.custno;
"Generic" SQL way:
SELECT table_1.custno,table_2.qty,table_2.descr
FROM table_1, table_2
WHERE table_2.id = (SELECT TOP 1 id
FROM table_2
WHERE custno = table_1.custno
ORDER BY qty )
SQL 2008 way (probably faster):
SELECT custno, qty, descr
FROM
(SELECT
custno,
qty,
descr,
ROW_NUMBER() OVER (PARTITION BY custno ORDER BY qty) RowNum
FROM table_2
) A
WHERE RowNum = 1
If you use SQL-Server you could use ROW_NUMBER and a CTE:
WITH CTE AS
(
SELECT table_1.custno,table_2.qty,table_2.descr,
RN = ROW_NUMBER() OVER ( PARTITION BY table_1.custno
Order By table_2.qty ASC)
FROM table_1
LEFT OUTER JOIN table_2
ON table_1.custno = table_2.custno
)
SELECT custno, qty,descr
FROM CTE
WHERE RN = 1
Demolink
The question is:
Two tables (t1, t2)
Table t1:
SELLER | NON_SELLER
A B
A C
A D
B A
B C
B D
C A
C B
C D
D A
D B
D C
Table t2:
SELLER | COUPON | BAL
A 9 100
B 9 200
C 9 300
D 9 400
A 9.5 100
B 9.5 20
A 10 80
Using SELECT Statement to get this result:
SELLER| COUPON | SUM(BAL)
A 9 900
B 9 800
C 9 700
D 9 600
A 9.5 20
B 9.5 100
C 9.5 120
D 9.5 120
A 10 0 # !!!
B 10 80
C 10 80
D 10 80
For seller A SUM(BAL) means sum( B.BAL,C.BAL,D.BAL), for B, SUM(BAL)=SUM(A.BAL,C.BAL,D.BAL)...
Please find a way with good performance and don't use temporary table.
My solution:
Running this query will get the result but without the row "A 10 0":
select t1.seller, t2.coupon, sum(bal)
from t1, t2
where t1.non_seller = t2.seller
group by t1.seller, t2.coupon
order by t2.coupon
Please help ~~~~~~
If I understand you correctly, you're looking for data on all sellers and all coupons. So let's start with a cross join that generates a list of coupons and sellers:
select sellers.seller
, coupons.coupon
from (
select distinct seller
from Table2
) as sellers
cross join
(
select distinct coupon
from Table2
) as coupons
For each seller-coupon combination, you're looking for the sum they can buy from other sellers. This can be accomplished by a left join:
select sellers.seller
, coupons.coupon
, case when sum(t2.bal) is null then 0 else sum(t2.bal) end
from (
select distinct seller
from Table2
) as sellers
cross join
(
select distinct coupon
from Table2
) as coupons
left join
Table2 t2
on t2.seller <> sellers.seller
and t2.coupon = coupons.coupon
group by
sellers.seller
, coupons.coupon
The only function of the case statement is to replace a null sum with a 0.
The output matches the one in your answer. Note that this solution doesn't use Table1: the list of other sellers is produced by the t2.seller <> sellers.seller condition in the left join.
I get another way to this:
select t1.seller, t2.coupon, sum(bal)
from t1, t2
where t1.non_seller = t2.seller
group by t1.seller, t2.coupon
union
(select seller,coupon,0 from t2 group by coupon having count(seller) == 1);
And I don't know if it is better or worst than compare with #Andomar :
select sellers.seller
, coupons.coupon
, case when sum(t2.bal) is null then 0 else sum(t2.bal) end
from (
select distinct seller
from Table2
) as sellers
cross join
(
select distinct coupon
from Table2
) as coupons
left join
Table2 t2
on t2.seller <> sellers.seller
and t2.coupon = coupons.coupon
group by
sellers.seller
, coupons.coupon