How to get rows having sum equal to given in SQL - sql

**Table A :** **Table B:**
ITEMCODE Total QTY ITEMCODE Qty
A 100 A 25
B 50 A 75
C 75 B 10
D 85 B 20
B 30
D 80
D 5
Need to result view :
A 100 = A 25
A 75
How to get this result with SQL function with these two tables

If I understand correctly, you want the rows where the sum for the itemcode in b matches a. One method uses window functions:
select b.*
from (select b.*, sum(qty) over (partition by itemcode) as sumqty
from b
) b join
a
on a.itemcode = b.itemcode and a.qty = b.sumqty;

Related

How to identify non-existing keys with reference to a table that has all mandatory keys, SQL?

I have the table 'Table01' which contains the keys that should be mandatory:
id
1
2
3
4
And I also have the table 'Table02' which contains the records to be filtered:
id
customer
weight
1
a
100
2
a
300
3
a
200
4
a
45
1
b
20
2
b
100
3
b
17
1
c
80
4
c
90
2
d
30
3
d
30
4
d
50
So I want to identify which are the mandatory id's that the table 'Table02' does not have, and in turn identify which is the 'customer' of each id's that the table 'Table02' does not have.
The resulting table should look like this:
customer
id
b
4
c
2
c
3
d
1
What I have tried so far is a 'rigth join'.
proc sql;
create table table03 as
select
b.id
from table02 a
right join table01 b
on a.id=b.id
where a.id is null;
run;
But that query is not identifying all the id's that should be mandatory.
I hope someone can help me, thank you very much.
here is one way:
select cl.customerid , a.id
from
Table1 a
cross join
( select customerid
from table2
group by customerid
) cl
where not exists ( select 1 from table2 b
where b.customerid = cl.customerid
and b.id = a.id
)
You can use an EXCEPT between two sub-selects. The first creates a matrix of all possibilities, and the except table is a selection of the extant customers.
Example:
data ids;
do id = 1 to 4; output; end;
run;
data have;
input id customer $ weight;
datalines;
1 a 100
2 a 300
3 a 200
4 a 45
1 b 20
2 b 100
3 b 17
1 c 80
4 c 90
2 d 30
3 d 30
4 d 50
run;
proc sql;
create table want(label='Customers missing some ids') as
select matrix.*
from
(select distinct have.customer, ids.id from have, ids) as matrix
except
(select customer, id from have)
;
quit;
If you are doing it in SQL server. Something like #eshirvana above posted, but also you can use with cte:
;with cte as
(
SELECT t1.id, t2.Customer
FROM Table01 t1
cross join (select distinct customer from Table02)
)
SELECT a.customer, a.id FROM cte a
LEFT JOIN Table02 b
ON a.id=b.id AND a.customer=b.customer
where b.id is null

full-join issue in SQL server

I have two tables total_sales_store :
store. total_sales
23 198750953.849999
29 77141561.3099999
9 77789512.9899997
15 89133935.9200002
3 57586980.0699998
32 166819624.16
26 143416610.79
12 144287538.149999
35 131520910.08
6 223756634.64
43 90565869.4100002
21 108118179.92
27 253856294.88
38 55159990.42
7 81598450.1399996
and storesdata:
store. type
1 A
2 A
3 B
4 A
5 B
6 A
7 B
8 A
9 B
10 B
11 A
I want to full join the two table so that I have this desired table:
store. Type. totalsales
1 A 123124
2 B 141221
3 C 134141
4 A. 234234
5 B 2323
6 C 123214
...
So I used the following query:
SELECT A.Store,a.total_sales
FROM totalsales_store A
FULL JOIN
(
SELECT [Type], Store
FROM storesdata
) B
ON A.Store = B.Store
ORDER BY total_sales DESC
But what I got is this:
[enter image description here][3]
which neglects the Type column. What can I do to make this work? Thank you!
With a FULL JOIN you will get all results from both tables, even when they don't match each other, so you should account for the NULL store values across tables. Otherwise simply include the Type column in the select.
I didn't see a need for a sub-query.
SELECT
ISNULL(A.Store, B.Store) Store,
B.Type,
a.total_sales
FROM
totalsales_store A
FULL JOIN storesdata B ON
A.Store = B.Store
ORDER BY
a.total_sales DESC
I suspect you can get away with
SELECT
A.Store,
B.Type,
a.total_sales
FROM
totalsales_store A
JOIN storesdata B ON
A.Store = B.Store
ORDER BY
a.total_sales DESC

Multiple values in SQL Server

I have two tables, Table A & Table B
Table A:
G.R.N ITEM QUANTITY
--------------------------
1 ABC001 150
1 CBD001 150
1 SDB001 100
Table B:
DELIVERY ITEM QUANTITY
-------------------------------
34 ABC001 50
35 ABC001 40
36 ABC001 60
37 CBD001 50
38 CBD001 40
39 CBD001 10
Is it possible to get desired output like this:
G.R.N ITEM QUANTITY DELIVERY ITEM QUANTITY DIFFERENCE
1 ABC001 150 34,35,36 ABC001 150 0
1 CBD001 150 37,38,39 CBD001 100 50
1 SDB001 100 100
for recent version of sql-server (sql-server 2017)
You could try using left join, sum and group by
select A.GRN
, A.ITEM
, A.QUANTITY
, STRING_AGG(B.DELIVERY,',' ) DELIVERY
, B.ITEM
, SUM(B.QUANTITY )
, A.QUANTITY - SUM(B.QUANTITY ) QUANTITY_DIFFERENCE
from tableA A
left JOIN tableB B ON A.ITEM = B.ITEM
group by A.ITEM
You can join the tables using the item column. If you perform a left join, then items from the first table will be returned even if there is no matching item value in the second table.
The STRING_AGG aggregation function concatenates the values in the group together using the second argument as the delimiter - in this case a comma.
select
A.[G.R.N],
A.ITEM,
A.QUANTITY,
STRING_AGG(B.DELIVERY, ',') as DELIVERY,
SUM(B.QUANTITY) as DELIVERY_QUANTITY,
A.QUANTITY - SUM(B.QUANTITY) as QUANTITY_DIFFERENCE
from A
left join B on A.ITEM = B.ITEM
group by A.ITEM

How to find difference of two columns using in Left Outer Join in SQL Sever 2005?

I have two Tables
Let suppose A and B
Now suppose the structure of table A is Like that
id stock
37 1
40 1
37 1
40 1
37 1
37 1
And B is like that
id stock
37 1
37 1
40 1
Now i want to write a query that give me sum of specific id stock in (table A - Table B) and if that id does not exist in table B then only stock from A.
So i will expect result like that
id stock
40 1
37 2
I thought that left join will be possible option here and i write query like that
SELECT A.id,
SUM(CAST(isNull(A.Stock, 0) as int) - CAST(isNull(B.Stock, 0) as int) )'Stock'
from A
LEFT OUTER JOIN
B
ON A.id = B.id
group by A.id
But Problem is that the above query gives desired records but wrong quantity/Stocklevel as shown below:
id stock
37 0
40 1
How can I resolve Stock Level issue.
I guess you are looking for something like this.
select A.id, A.SumA - coalesce(B.SumB, 0) as stock
from (
select A.id, sum(A.stock) as SumA
from A
group by A.id
) as A
left outer join
(
select B.id, sum(B.stock) as SumB
from B
group by B.id
) as B
on A.id = B.id
Result:
id stock
----------- -----------
37 2
40 1
SE Data
SELECT A.id, A.Stock - isNull(B.stock, 0) as Stock from A
LEFT OUTER JOIN B
ON A.id = B.id
That would be it I think.
PS. you group by something that you did not include in your case scenario. Your expected result is also not understandable to me (it conflicts with your problem description)

Transposing rows to columns using self join

I have a table named category with values as below,
CategoryId | Value | Flag
1 25 a
2 26 a
3 27 a
1 28 m2 23 m
1 36 p2 33 p
Now I want to transpose the rows present in this table to columns based on the flag, something like
CategoryId | aValue | mValue | PValue
1 25 28 36
2 26 23 33
3 27 null null
I am trying to join based on the category id but I am just getting the matched records (inner join) in my resultset even if I use left outer join in my query.
My query:
SELECT
A.CategoryId,
A.Value AS actual,
B.Value AS projected,
C.Value AS Manual
FROM ((a AS A left JOIN b AS B ON A.categoryid=B.categoryid)
left JOIN c AS C ON A.categoryid=C.categoryid)
WHERE (((A.flag)="a") and ((B.flag)="p") and ((C.flag) ="m"))
I am getting the proper results if I have the data in 3 different tables.
I just want to check what would be the best way to transpose a rows to column when using self join...
Thanks,
Barani
Try this:
SELECT CategoryId,
MIN(SWITCH(YourTable.Flag = 'a',Value)) AS aValue,
MIN(SWITCH(YourTable.Flag = 'm',Value)) AS mValue,
MIN(SWITCH(YourTable.Flag = 'p',Value)) AS pValue
FROM YourTable
GROUP BY CategoryId