SQL: pivot multiple tables - sql

I have two tables
TableA
ID Qualification
1 A
2 A
3 B
TableB
ID Qualification
1 C
2 A
3 A
Unfortunately, the names of the columns in table A and B are the same - resulting in an error 8156 - The column 'Qualification' was specified multiple times.
My select looks like follows
SELECT *
FROM (
SELECT A.ID, A.Qualification, B.Qualification
FROM TableA A LEFT OUTER JOIN TableB B
ON A.ID = B.ID
)s
PIVOT
(SUM(ID)
FOR Qualification IN ([A],[B],[C])) pvt
TIA!

Related

Left join but maintain values where NULL may result in Microsoft SQL

I have two tables:
Table A:
id names
1 a
2 b
3 c
and Table B:
id names
1 x
2 y
I'd like to perform a left join of Table B on Table A that results in the following table:
id names
1 x
2 y
3 c
How can I do this in Microsoft SQL?
You could use COALESCE:
SELECT a.id, COALESCE(b.name, a.name) AS name
FROM tab1 a
LEFT JOIN tab2 b
ON a.id = b.id
I think you just want coalesce():
select a.id, coalesce(b.name, a.name) as name
from a left join
b
on a.id = b.id;

Return all inactive items from Table B for each item in Table A

Not sure if I can explain this well in words..
I want to find all items in Table B that have ALL items inactive for each item in Table A. Let's say Table A just has column "item" and Table B has columns "item" and "active"
Table A Table B
A A | 1
A A | 1
A B | 1
B B | 0
B C | 0
B C | 0
C D | 0
C E | 1
D
E
F
In that example, it should return C and D.
I managed to join tables A and B together with a group by clause but not sure where to go from there. Tried looking around and only found answers where the other table's value doesn't exist so you can use "NOT IN" but that doesn't seem to work here.
Any help would be appreciated!
You can join the tables and use the HAVING clause to make the comparison like this:
SELECT ta.Item
FROM TableA tA
LEFT JOIN TableB tB
ON tA.Item=tB.Item
GROUP BY tA.Item
HAVING SUM(tB.Inactive)=COUNT(tb.Inactive)
This would give you a distinct list of Items in TableA
The above query assumes 1 is Inactive and 0 is Active. If your data is opposite (which it looks like it is), you could instead say:
SELECT ta.Item
FROM TableA tA
LEFT JOIN TableB tB
ON tA.Item=tB.Item
GROUP BY tA.Item
HAVING SUM(tB.Inactive)=0
This would also return Item F as it doesn't have a value in table b to SUM. Just flip the LEFT JOIN to an INNER JOIN if you don't want Item F to return.
If you need to return back all instances in TableA, you could use a subquery and join to that:
SELECT ta.Item
FROM TableA tA
LEFT JOIN (SELECT ITEM, SUM(ACTIVE) Sum0 FROM TableB GROUP BY ITEM)tB
ON tA.Item=tB.Item
WHERE tB.Sum0 = 0
/*or tB.Sum0 is null would give you Item F*/
Use NOT EXISTS:
select distinct a.item
from table_A a
where not exists (select 1 from table_B b where b.item = a.item and b.status = 1);
I believe you would just need to join the tables together on table name and filter to only value of 0 on the active column.
SELECT B.*
FROM TableA A INNER JOIN TableB B ON A.item = B.item
WHERE B.active = 0
Does that get you what you need?

select sql query to merge results

I have a table old_data and a table new_data. I want to write a select statement that gives me
Rows in old_data stay there
New rows in new_data get added to old_data
unique key is id so rows with id in new_data should update existing ones in old_data
I need to write a select statement that would give me old_data updated with new data and new data added to it.
Example:
Table a:
id count
1 2
2 19
3 4
Table b:
id count
2 22
5 7
I need a SELECT statement that gives me
id count
1 2
2 22
3 4
5 7
Based on your desired results:
SELECT
*
FROM
[TableB] AS B
UNION ALL
SELECT
*
FROM
[TableA] AS A
WHERE
A.id NOT IN (SELECT id FROM [TableB])
I think this would work pretty neatly with COALESCE:
SELECT a.id, COALESCE(b.count, a.count)
FROM a
FULL OUTER JOIN b
ON a.id = b.id
Note - if your RDBMS does not contain COALESCE, you can write out the function using CASE as follows:
SELECT a.id,
CASE WHEN b.count IS NULL THEN a.count
ELSE b.count END AS count
FROM ...
You can write a FULL OUTER JOIN as follows:
SELECT *
FROM a
LEFT JOIN b
ON a.id = b.id
UNION ALL
SELECT *
FROM b
LEFT a
ON b.id = a.id
You have to use UPSERT to update old data and add new data in Old_data table and select all rows from Old_data. Check following and let me know what you think about this query
UPDATE [old_data]
SET [count] = B.[count]
FROM [old_data] AS A
INNER JOIN [new_Data] AS B
ON A.[id] = B.[id]
INSERT INTO [old_data]
([id]
,[count])
SELECT A.[id]
,A.[count]
FROM [new_Data] AS A
LEFT JOIN [old_data] AS B
ON A.[id] = B.[id]
WHERE B.[id] IS NULL
SELECT *
FROM [old_data]

SQL: Join table a and b then join table c to get the results that are on a but not on c?

i have 3 tables. Table a pk = userid, table b and c fk = userid. On table b RoleID column is equal to Usermanager column from table c but w a new value.
So i joined table a and b with below query
select a.Username, a.Userid, b.Roleid
from NewTable a
join RoleTable b
on a.UserID=b.UserID
where b.RoleID = 2
This results in 502 records.
Table c query is
select *
from OldTable
where UserManager = 1
and Authorized = 1
and Status = 'A'
This results in 500 records.
So I'm trying to join the 2 queries to find the 2 records that are not on table c but are only on table a.
Thanks.
Try this:
select a.Username, a.Userid, b.Roleid
from NewTable a
join RoleTable b
on a.UserID=b.UserID
where
b.RoleID = 2
AND
NOT EXISTS
(select *
from OldTable AS c
where c.UserManager = 1
and
c.Authorized = 1
and
c.Status = 'A'
AND
a.userid = c.userid)
I used the two queries you mentioned you were using and just made the table c query into a WHERE NOT EXISTS subquery. It should provide those 2 results you are looking for.
Something like this should do the trick. You can work out the details for your database.
select fields
from tableA join tableB on something
where whatever
and tableA.someField in
(select someField
from tableA join tableB on something
where whatever
except
select someEquivalentField
from tableC)
The two where whatevers should be the same.
If I understand your question correctly... the following will join Table A and Table C and then find those that dont have corresponding values in Table C
Select * from Table A A
LEFT JOIN Table C C On A.UserId = C.UserId
Where C.UserId is NULL
This is the basic concept.. you need to work on it to get the syntax to fit your motives
You can do this with a Left Join
select subA.*
from (
select a.Username, a.Userid, b.Roleid
from NewTable a
join RoleTable b
on a.UserID=b.UserID
where b.RoleID = 2
) subA
left join (
select userID
from OldTable
where UserManager = 1
and Authorized = 1
and Status = 'A'
) subB
on subA.Userid = subB.UserID
Where subB.userid is null

SQL Server - Insert into a combination of two tables

I need to combinate two tables in SQL Server. But I need to have a row with each item of table A with each item of table B, resulting in a table C. I would be like this:
Table A
A
B
C
D
Table B
1
2
3
Table C
column x | cloumn Y
A 1
A 2
A 3
B 1
B 2
B 3
C 1
C 2
C 3
D 1
D 2
D 3
Thanks all!
You can simply do this:
SELECT
a.a + CAST(b AS VARCHAR(2)) AS a
FROM tablea a
CROSS JOIN tableb AS b;
See it in action:
SQL Fiddle Demo
Then you can use the INTO clause to insert them into a table already exists:
INSERT INTO tablec(c)
SELECT
a.a + CAST( b AS VARCHAR(2)) AS a
FROM tablea a
CROSS JOIN tableb AS b;
or create a new table from these values:
SELECT
a.a + CAST( b AS VARCHAR(2)) AS c
INTO Tablec
FROM tablea a
CROSS JOIN tableb AS b;
Updated SQL Fiddle Demo
Note that: I assumed the columns' names, since you didn't specify them in your question.
Looks like you're trying to get the following:
select a.col1, b.col1
into tableC
from tableA a
cross join tableB b