Values from a table that are not in another one - sql

I have two tables, A and B.
A
ID age
1 24
2 25
45 22
B
ID school
34 school1
1 school2
I want to select IDs that are in B but not in A.
I wrote
Select distinct bb.school
From B as bb
Left outer join A as aa
On bb.ID=aa.ID
inner join C as cc
On bb.school=cc.school
This code returns exactly the same number of rows that I would have with an inner join instead of left outer join.
Am I doing something wrong?

Try using not in;
Select * From A Where ID Not In ( Select ID From B )

Related

how to execute query for each row result of another query

I have 2 tables , one stores IDs and another logs for each ID , i would like to get sum of log for each ID and ID number from these 2 tables
A B
------- -------------
ID ID_C LOG
1 1 15
2 1 30
3 4 44
4 2 14
5 3 88
3 10
2 10
for getting sum query is
SELECT SUM(LOG) FROM B WHERE ID_C ='2' ;
notice ID and ID_C are same but name is different in tables
and for getting all ids available query is
SELECT ID FROM A ;
I would like to get the following table result
result
--------------------
ID SUM
1 45
4 44
2 24
3 98
I tried
SELECT SUM(LOG) FROM B WHERE ID_C in (SELECT ID FROM A ) ;
but it result in sum of all IDs
It looks like you just need a join aggregation here:
SELECT a.ID, SUM(b.LOG) AS SUM
FROM A a
INNER JOIN B b
ON b.ID_C = a.ID
GROUP BY a.ID
ORDER BY a.ID;
Note that the inner join will also remove ID values from the A table which no entries whatsoever in the B table, which seems to be the behavior you want.
you should use inner join and GROUP BY:
SELECT A.ID as ID, SUM(LOG) AS SumLOG
FROM A inner join B ON A.ID = B.ID_C
GROUP BY A.ID
if you needed can use where for ID filter.

Transitive joins in postgresql

What is the best way to achieve a transitive join in postgresql? Currently, I want to do a full outer join for tables, a, b, and c. My query currently looks like this:
SELECT *
FROM a
FULL OUTER JOIN b
ON a."ID" = b."ID"
FULL OUTER JOIN c
ON a."ID" = c."ID"
I'm running into an issue where some records that match in table B and table C are showing up in different rows in the query output, and I realized that it must be because I have not explicitly joined tables B and C. What is the best way to write a "transitive" query where a=b, a=c, and b=c?
Here is an example of my current output. Right now, when a matching ID exists for just tables B and C, I get 2 different rows:
A ID
B ID
C ID
32
32
null
35
35
35
36
null
36
null
42
null
null
null
42
Here is my desired output:
A ID
B ID
C ID
32
32
null
35
35
35
36
null
36
null
42
42
Use using:
SELECT *
FROM a FULL OUTER JOIN
b
USING ("ID") FULL OUTER JOIN
c
USING ("ID");
If in your real example, the columns have different names:
SELECT *
FROM a FULL OUTER JOIN
b
ON b.id = a.id FULL OUTER JOIN
c
ON c.id = COALESCE(b.id, a.id);

Selecting item from columns in two different tables

I have two tables tabeleA and tableB..
In table A, I have column(Name)
In table B, I have column(Amount)
Table A:
cat_id cat_name
1 Man
2 Women
3 General
Table B:
cat_id cat_price
1 12
1 18
1 34
1 23
2 21
3 31
1 21
3 56
Now in these two tables I have name and price which are linked by cat_id..
Now I want to display Name and price for that particular name and the price should be the total for particular categories......
Something like this:
TableNew:
cat_name cat_price
Man 104
Woman 21
General 87
please help..
thanks...
SELECT
tA.cat_name, SUM(tB.cat_price) AS price
FROM TableA tA
INNER JOIN TableB tB
ON tA.cat_id=tB.cat_id
GROUP BY tA.cat_id
select a.cat_name,
sum(b.cat_price) price
from tablea a
inner join tableb b
on a.cat_id = b.cat_id
group by a.cat_name
INNER JOIN.
GROUP BY Sql Server version in absence of Wiki Sql article.
select T1.cat_name, T2.total
from TableA T1
NATURAL JOIN (SELECT cat_id, sum(cat_price) as total
FROM TableB GROUP BY cat_id) T2
You can use an INNER JOIN for this:
SELECT
table_a.cat_name,
SUM(table_b.cat_price) AS price
FROM
table_a
INNER JOIN
table_b
ON
table_b.cat_id = table_a.cat_id
GROUP BY
table_a.cat_name;
Hope this helps.

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