SQL: CUSTOMER that has bought a WORK from every ARTIST || 2 tables - sql

So I have 2 tables that both contain IDs
work:
workID, artistID
1 6
2 7
3 8
4 6
5 6
trans:
CustomerID, workID
10 1
11 2
12 3
10 4
10 5
So far I've only managed to put all the ID's together but the result I need is to show any customerID that has purchased a workID from every artistID:
SELECT
trans.customerID, trans.workID, work.artistID
FROM
trans
INNER JOIN work
ON trans.workID=work.workID
WHERE
trans.customerID IS NOT null
ORDER BY
trans.customerID;
Basically I have no idea what my next step should be, if anyone could point me in the right direction or explain a solution that would be great.
EDIT: added simplified data to tables

This should get you going:
SELECT t.customerId
FROM
( SELECT t.CustomerId, COUNT(DISTINCT artistId) as artists
FROM trans t INNER JOIN work w ON w.workid = t.workid) t
INNER JOIN
( SELECT COUNT(DISTINCT artistId) artists FROM work) a ON t.artists = a.artists

Related

SQL get table1 names with a count of table2 and table3

I have three tables, table1 is connected to table2 and table3, but table2 and table3 are not connected. I need an output count of table2 and table3 for each table1 row. I have to use joins and a group by table1.name
SELECT Tb_Product.Name, count(TB_Offers.Prod_ID) 'Number of Offers', count(Tb_Requests.Prod_ID) 'Number of Requests'
FROM Tb_Product LEFT OUTER JOIN
Tb_Requests ON Tb_Product.Prod_ID = Tb_Requests.Prod_ID LEFT OUTER JOIN
TB_Offers ON Tb_Product.Prod_ID = TB_Offers.Prod_ID
GROUP BY Tb_Product.Name
I need to combine these queries:
SELECT Tb_Product.[Name], count(TB_Offers.Prod_ID) 'Number of Offers'
FROM Tb_Product LEFT OUTER JOIN
TB_Offers ON Tb_Product.Prod_ID = TB_Offers.Prod_ID
GROUP BY Tb_Product.[Name]
SELECT Tb_Product.[Name], count(Tb_Requests.Prod_ID) 'Number of Requests'
FROM Tb_Product LEFT OUTER JOIN
Tb_Requests ON Tb_Product.Prod_ID = Tb_Requests.Prod_ID
GROUP BY Tb_Product.[Name]
Results:
Name Number of Offers
Airplane 6
Auto 5
Bike 3
Camera 0
Computer 12
Milk 4
Oil 4
Orange 6
Telephone 0
Truck 6
TV 4
Name Number of Requests
Airplane 1
Auto 5
Bike 0
Camera 2
Computer 6
Milk 4
Oil 5
Orange 6
Telephone 0
Truck 1
TV 5
My results for offers and requests are the same value. I am not sure what I am doing wrong with the joins. Do I need to somehow join product to request and separately join product to offers? This needs to be done in one query.
This is for a class. Explanation would also be appreciated.
The simplest way to do this is to count the distinct values of each column:
SELECT
Tb_Product.Name,
count(distinct TB_Offers.Prod_ID) 'Number of Offers',
count(distinct Tb_Requests.Prod_ID) 'Number of Requests'
FROM
Tb_Product
LEFT OUTER JOIN
Tb_Requests ON Tb_Product.Prod_ID = Tb_Requests.Prod_ID
LEFT OUTER JOIN
TB_Offers ON Tb_Product.Prod_ID = TB_Offers.Prod_ID
GROUP BY
Tb_Product.Name
This is necessary because of the way joins work consecutively to produce a rowset that is a combination of all the input relations. COUNT() normally performs a count of non-null values in a column.
You can also do something like this, which aggregates the counts from the child tables independently and then joins them to the base table:
SELECT
p.Name,
o.cnt as Offer_Count,
r.cnt as Request_Count
FROM
TB_Product p
LEFT OUTER JOIN
(SELECT Prod_ID, COUNT(1) cnt FROM TB_Offers GROUP BY Prod_ID) o
LEFT OUTER JOIN
(SELECT Prod_ID, COUNT(1) cnt FROM TB_Requests GROUP BY Prod_ID) r
More explanation...
Let's say you have two products:
Prod_ID
Name
1
Widget
2
Gizmo
And two offers, one for each product:
Offer_ID
Prod_ID
100
1
200
2
And two requests for each product:
Request_ID
Prod_ID
1001
1
1002
1
2001
2
2002
2
Now you join Product relation to Offer relation on Prod_ID, you get a result like this:
Prod_ID
Name
Offer_ID
Prod_ID
1
Widget
100
1
2
Gizmo
200
2
Now when you join that relation to Requests on Prod_ID, you get something like this:
Prod_ID
Name
Offer_ID
Prod_ID
Request_ID
Prod_ID
1
Widget
100
1
1001
1
1
Widget
100
1
1002
1
2
Gizmo
200
2
2001
2
2
Gizmo
200
2
2002
2
Now when you count any of these columns you get 4 because each column has 4 values.

SQL help i need to find the inventory remaining in my office

In sql help i have 3 tables, table one is asset table which is as follow
id
asset_code
asset_name
asset_group
asset_quantity
1
A001
demo asset
4
5
2
A002
demo asset 2
6
3
and another table is asset_allocation
id
asset_id
allocated_quantity
allocated_location
1
1
2
IT office
2
1
1
main hall
the last table is asset_liquidated which will present assets that are no longer going to be used
id
asset_id
liquidated_quantity
1
1
2
2
1
1
lets say i have 5 computers and i have allocated 3 computers and 1 is no longer going to be used so i should be remaining with 1 computer so now how do i make sql auto generate this math for me
You need to use aggregation and the join your tables -
SELECT id, asset_code, asset_name, asset_group, asset_quantity,
asset_quantity - COALESCE(AA.allocated_quantity, 0) - COALESCE(AL.liquidated_quantity, 0) available_quantity
FROM asset A
LEFT JOIN (SELECT asset_id, SUM(allocated_quantity) allocated_quantity
FROM asset_allocation
GROUP BY asset_id) AA ON A.id = AA.asset_id
LEFT JOIN (SELECT asset_id, SUM(liquidated_quantity) liquidated_quantity
FROM asset_liquidated
GROUP BY asset_id) AL ON A.id = AL.asset_id
This query will give you -1 as available_quantity for asset_id 1 as you have only 5 available, 3 of them are allotted and 3 are liquidated as per your sample data.
Please see if this helps
SELECT
asset_quantity AS Total_Assets
,ISNULL(allocated_quantity, 0) allocated_quantity
,ISNULL(liquidated_quantity, 0) liquidated_quantity
FROM asset
LEFT OUTER JOIN (
SELECT
asset_id, SUM(allocated_quantity) AS allocated_quantity
FROM asset_allocation
GROUP BY asset_id
) asset_allocation2
ON asset_allocation2.asset_id = asset.id
LEFT OUTER JOIN (
SELECT
asset_id, SUM(liquidated_quantity) AS liquidated_quantity
FROM asset_liquidated
GROUP BY asset_id
) asset_liquidated 2
ON asset_liquidated 2.asset_id = asset.id

combine two group by queries to one to get count of both table's record in sql server

I have two queries to get Tutor and Parent Counts by Locations, are below:
Select a.LocationId, COUNT(*) from TutorAddress ta
inner join Address a on a.Id=ta.AddressId group by a.LocationId
Out Put is:
LocationId Count
1 4
14 13
second query is:
Select a.LocationId, COUNT(*) from ParentAddress pa
inner join Address a on a.Id=pa.AddressId group by a.LocationId
Out Put is:
LocationId Count
1 6
14 3
12 8
I want to merge these two queries and get the result single output as below:
LocationId tutorCount ParentCount
1 4 6
14 13 3
12 0 8
is it possible, i m not able to get how i can achieve this. please help.
You can combine both query using a left join
select a.locationid,
count(pa.AddressId) as parentcount, COUNT(ta.AddressId) tutorcount
from Address a
left join ParentAddress pa on a.Id=pa.AddressId
left join TutorAddress ta on a.Id=ta.AddressId
group by a.locationid

SQL query to add points from two tables within a database

I'm about to have a cow here. I'm designing a hockey pool database, which at the moment consists of 3 tables as follows:
Table 1 Table 2 Table 3
TeamID TeamName GoalieID TeamID Points SkaterID TeamID Points
1 Marlies 1 1 10 1 4 20
2 Colts 2 3 5 2 1 25
3 Sting 3 2 6 3 3 7
4 Steelheads 4 4 7 4 2 12
The actual tables have a lot more players and teams, this is just an example.
I'm looking to create a query that will combine points totals for each player from Table2 and Table3, and display this information right next to the Team Name.
Team Name Total Points
Steelheads 27
Marlies 25
Colts 18
Sting 12
I have no problems summing points from a single table but unfortunately I'm having trouble wrapping my head around combining points that span across multiple tables. Could someone point me in the right direction please?
Do a UNION ALL in a derived table (p) to get all players at once, including goalies. LEFT JOIN with that result to get all teams with players' points. Finally do a GROUP BY and sum the points.
SELECT t1.TeamName, sum(p.Points) as TotalPoints
FROM Table1 t1
LEFT JOIN (select TeamID, Points from Table2
union all
select TeamID, Points from Table3) p
ON t1.TeamId = p.TeamId
GROUP BY t1.TeamName
(Have you considered to have all players in the same table?)
SELECT
Table1.TeamName,
sum(isNull(Table2.Points,0) + isNull(Table3.Points,0)) as TotalPoints
FROM
Table1
LEFT JOIN Table2
ON Table1.TeamId = Table2.TeamId
LEFT JOIN Table3
ON Table1.TeamId = Table3.TeamId
GROUP BY
Table1.TeamName

Group by with two columns

I am trying to write a query using group by in sub query ,I referred lot of blogs but could not get all the values.
I have three tables and below is the structure of those tables.
Pet_Seller_Master
ps_id ps_name city_id
2 abc 1
3 xyz 2
4 fer 4
5 bbb 1
City_Master
city_id city_name
1 Bangalore
2 COIMBATORE
4 MYSORE
Api_Entry
api_id ps_id otp
1 2 yes
2 3
3 2 yes
4 3 yes
5 4
6 5 yes
7 5 yes
8 5 yes
Query is to get number of sellers, no of pet sellers with zero otp, no of pet sellers with 1 otp, no of pet sellers with 2 otp,no of pet sellers with otp>2 for the particular city and within date range.
Through Below query I am able to get city , psp , and zero otp
select cm.city_name,
count(ps.ps_id) as PSP,
((select count(ps1.ps_id)
FROM ps_master ps1
WHERE ps1.city = cm.city_id)-
(SELECT count(distinct ps1.ps_id)
from ps_master ps1
INNER JOIN api_entry ae ON ps1.ps_id = ae.ps_id and otp!=''
WHERE ps1.city = cm.city_id and date(timestamp) >= curdate() - INTERVAL DAYOFWEEK(curdate())+6 DAY AND date(timestamp) < curdate())) as zero_psp
from ps_master ps INNER JOIN city_master cm ON ps.city = cm.city_id and cm.city_type = 'IN HOUSE PNS'
group by city_id
Please tell me the solution to solve this query.
Thanks in advance
It's not hard to do and you were on a right track. Here is what I would use:
select c.city_name, a.otp, p.ps_name, COUNT(*) nbr
from Api_Entry a
inner join Pet_Seller_Master p on p.ps_id=a.ps_id
inner join City_Master c on p.city_id=c.city_id
group by c.city_name, a.otp, p.ps_name
Now, if you want to get the number of sellers with zero otp, you just apply where clause:
where otp <> 'yes'
If you want to get the number of pet sellers with otp>2, then you just use subquery:
select *
from (
select c.city_name, a.otp, p.ps_name, COUNT(*) nbr
from #tempA a
inner join #tempP p on p.ps_id=a.ps_id
inner join #tempC c on p.city_id=c.city_id
group by c.city_name, a.otp, p.ps_name
) g
where nbr > 2