Postgresql SQL Select items from table1 based on a condition from table2 - sql

I am trying to select items from table1 which has a child table2 there is a third table3 involved.
Select j.ccmasterid,
(Select sum(i.ccmatpullqty) From table2 i
Where i.ccmasterid = j.ccmasterid) pulled
from table1 j
INNER JOIN table3 s on j.ccstatus = s.sysstatusid and s.ccopenjob=false
where j.ccmasterid LIKE 'W%' and pulled = 0
This generates an error:
ERROR: column "pulled" does not exist
LINE 6: where j.ccmasterid LIKE 'W%' and pulled = 0
If I take the "and pulled = 0" out the the query, it works as one would expect producing a list of records from table1 with the sum of the values in table2 as pulled.
ccmasterid pulled
W106063 0
W100553 9
W100685 1
WHAT I can't figure out is how to select based on pulled being 0.

Change this query into a subquery, and move WHERE condition to the outer query:
SELECT * FROM (
Select j.ccmasterid,
(Select sum(i.ccmatpullqty) From table2 i
Where i.ccmasterid = j.ccmasterid) pulled
from table1 j
INNER JOIN table3 s on j.ccstatus = s.sysstatusid and s.ccopenjob=false
where j.ccmasterid LIKE 'W%'
) x
WHERE pulled = 0

Avoid the correlated subquery which runs for every row in outer query and not once if joining to an aggregate query with GROUP BY clause:
SELECT j.ccmasterid
FROM table1 j
INNER JOIN table3 s
ON j.ccstatus = s.sysstatusid AND s.ccopenjob = false
INNER JOIN
(SELECT i.ccmasterid, SUM(i.ccmatpullqty) AS pulled
FROM table2 i
GROUP BY i.ccmasterid
) AS agg
ON agg.ccmasterid = j.ccmasterid
WHERE j.ccmasterid LIKE 'W%' AND agg.pulled = 0
Even use CTE
WITH agg AS
(SELECT i.ccmasterid, SUM(i.ccmatpullqty) AS pulled
FROM table2 i
GROUP BY i.ccmasterid)
SELECT j.ccmasterid
FROM table1 j
INNER JOIN table3 s
ON j.ccstatus = s.sysstatusid AND s.ccopenjob = false
INNER JOIN agg
ON agg.ccmasterid = j.ccmasterid
WHERE j.ccmasterid LIKE 'W%' AND agg.pulled = 0

Related

Select count in parent table

I have two tables (table one is parent and table two is children) in ms access that are related together with ID
Table one :
table two :
and I need a select sql code to run this query:
I could write the sql command without count of TeamName :
Select Table1.TackName,Sum(Table2.PaintingValue) as SumofPaintingValue
from (Table1 INNER JOIN
Table2
on (Table1.ID = Table2.fgk)
GROUP BY Table1.TackName
Try this
Select TrackName, Sum(PaintingValue) as SumOfPaintingValue, Dcount( "TrackName","Table1","TrackName='" & a.TrackName & "'") as CountOfTeamName from Table1 as a INNER JOIN Table2 as b ON a.ID = b.fgk
group by TrackName
OR
Create two saved query
qryA
Select TrackName, count(TrackName) as CountOfTeamName from Table1 as a group by TrackName
qryB
Select TrackName, Sum(PaintingValue) as SumOfPaintingValue from Table1 as a INNER JOIN Table2 as b ON a.ID = b.fgk group by TrackName
Then use below for result
Select qryA.TrackName, SumOfPaintingValue, CountOfTeamName from qryA INNER JOIN qryB on qryA.TrackName = qryB.TrackName
I can't test this at the moment, but I think a correlated query should do the trick:
Select
Table1.TackName,
Sum(Table2.PaintingValue) as SumofPaintingValue,
(select count(TeamName) from table1 t1 where t1.TrackName=table1.TrackName
group by TeamName) as CountOfTeams
from Table1 INNER JOIN Table2 on (Table1.ID = Table2.fgk)
GROUP BY Table1.TackName

How to convert the following set of queries' output to a view in SQL Server?

I have the below code in SQL Server and I want the same output but as a view. How do I write a view to give this output? I want the result from the first query basically along with the count of distinct people id for each occupancy id but I can't use group by in that query.
Thanks in advance!
SELECT DISTINCT
pp.PeopleID,
od.OccupancyID,
pp.Gender
INTO
t1
FROM
dimPeople AS pp
LEFT JOIN
OccupanciesPeople AS op ON op.PeopleID = pp.PeopleID
AND op.CompanyID = pp.CompanyID
LEFT JOIN
OccupancyDetail AS od ON op.OccupancyID = od.OccupancyID
AND op.CompanyID = od.CompanyID
WHERE
od.OccupancyEndDate IS NULL
AND op.DateLeftOccupancy IS NULL
AND pp.DateOfDeath IS NULL
SELECT
OccupancyID, COUNT(DISTINCT peopleID) AS PeopleCount
INTO
t2
FROM
t1
GROUP BY
OccupancyID
SELECT
t1.*,
t2.PeopleCount, t2.[HouseHold Person]
FROM
t1
JOIN
t2 ON t1.occupancyID = t2.OccupancyID
DROP TABLE t1
DROP TABLE t2
If those queries work the way you want (spoiler: they don't - you don't define t2.[HouseHold Person] when you create t2), you could replace the 2 "into" tables with Common Table Expressions and get your results.
CREATE VIEW dbo.MyView AS
WITH t1 AS (
SELECT DISTINCT
pp.PeopleID,
od.OccupancyID,
pp.Gender
FROM
dimPeople AS pp
LEFT JOIN
OccupanciesPeople AS op ON op.PeopleID = pp.PeopleID
AND op.CompanyID = pp.CompanyID
LEFT JOIN
OccupancyDetail AS od ON op.OccupancyID = od.OccupancyID
AND op.CompanyID = od.CompanyID
WHERE
od.OccupancyEndDate IS NULL
AND op.DateLeftOccupancy IS NULL
AND pp.DateOfDeath IS NULL
), t2 as (
SELECT
OccupancyID, COUNT(DISTINCT peopleID) AS PeopleCount
FROM
t1
GROUP BY
OccupancyID
)
SELECT
t1.PeopleID,
t1.OccupancyID,
t1.Gender,
t2.PeopleCount
FROM
t1
JOIN
t2 ON t1.occupancyID = t2.OccupancyID;

SQL Find Record in Table A not in Table B

I have Tbl1
and Tbl2
I would like to return the record that is in A but not in B, in this case I would like to return the bottom 2 records.
I have tried the following but this yields 0 records. What am I missing?
SELECT tbl2.field1, tbl2.field2, tbl2.field3
FROM tbl2
RIGHT JOIN tbl1
ON tbl2.field1 = tbl1.field1
WHERE tbl1.field1 IS NULL
EDIT:
I have tried LEFT join and I have also tried the following:
SELECT *
FROM tbl2
LEFT JOIN tbl1 ON tbl1.field1 = tbl2.field1
WHERE tbl1.field1 IS NULL
which gives the following result:
Edited solution: You can use the not exists method the check the second table.
SELECT *
FROM tbl2
WHERE NOT EXISTS (SELECT *
FROM tbl1
WHERE tbl1.field1 = tbl2.field1
AND tbl1.field2 = tbl2.field2
AND tbl1.field3 = tbl2.field3);
The both tables have the same fields, because of that, we have to check all fields (like mentoined by #Andre).
You need all columns you want to compare in the JOIN condition.
SELECT *
FROM tbl2
LEFT JOIN tbl1
ON (tbl1.field1 = tbl2.field1) AND (tbl1.field2 = tbl2.field2) AND (tbl1.field3 = tbl2.field3)
WHERE tbl1.field1 IS NULL

I cannot get this LEFT JOIN to work (I don't understand joins)

These queries both get results:
SELECT * FROM Table1 WHERE Criteria = '5'
SELECT * FROM Table1 WHERE Criteria = '3'
This query gets results:
SELECT *
FROM Table1 p, Table2 m
WHERE p.UID = m.ID
AND Criteria = '5'
This query does not:
SELECT *
FROM Table1 p, Table2 m
WHERE p.UID = m.ID
AND Criteria = '3'
I am trying to convert these to a proper join which returns results even if there are no records in the right table.
I have tried the following
SELECT *
FROM Table1 p LEFT JOIN Table2 m ON p.UID = m.ID
WHERE p.Criteria = '3'
AND m.OtherCriteria = 'Moron'
--0 results
My limited understanding was that LEFT join is what I needed. I want data from the left table even if there is no data in the right table that matches. Since this didn't work I also tried right join, left outer join, right outer join and full join. None returned results.
What am I missing?
This is too long for a comment. Your query:
SELECT *
FROM Table1 p LEFT JOIN
Table2 m
ON p.UID = m.ID AND p.Criteria = '3';
Should be returning a row for all rows in table1. If there is no match, then the values will be NULL for table2. This is easily demonstrated: Here is a MySQL example on SQL Fiddle. Because this is standard behavior, it should work on almost any database.
Note that this query is quite different from this one:
SELECT *
FROM Table1 p LEFT JOIN
Table2 m
ON p.UID = m.ID
WHERE p.Criteria = '3';
This query returns no rows, because no rows match the WHERE clause. The filtering happens (conceptually) after the LEFT JOIN.
I changed the code in the SQL Fiddle slightly, so that query is:
select *
from (select 5 as criteria, 1 as id union all
select 6, 1 union all
select 7, 2
) table1 left join
(select 1 as id, 'x' as x
) table2
on table1.id = table2.id and criteria = 3;
As a note: you should always use explicit join syntax. Simple rule: Never use commas in the FROM clause.
If your database is returning no rows, then it is behaving in a non-standard manner or your interface has decided to filter the rows for some reason.

Returning narrowed down SELECT based on associated table

I have a join query I use to pull data from another table:
SELECT [THEME].[NAME],
[THEMETYPE].[TYPE]
FROM [THEME]
LEFT OUTER JOIN [THEMETYPE]
ON [THEME].[THEMETYPEID] = [THEMETYPE].[PK_THEMETYPE]
WHERE COALESCE([THEME].[THEMETYPEID], 'null') LIKE '%'
ORDER BY CASE
WHEN [THEMETYPE].[TYPE] IS NULL THEN 1
ELSE 0
END,
[THEMETYPE].[TYPE]
I need to add the ability to narrow it down if a 3rd tables values match up:
Where producttheme.productid = variable-paramater-here
AND producttheme.themeid = theme.pk_theme
Here is a pic of the table:
So if the 1 is chosen above, it will return all [Theme].[Name] and the associated [ThemeType].[Type] where The ThemeId is associated with ProductId = 1
Edit: to be more clear ThemeId is the Primary key in the Theme table where Theme.Name exists.
This would give you some idea, please adjust the column names accordingly:
SELECT [Theme].[Name], [ThemeType].[Type]
FROM [Theme]
Left Outer Join [ThemeType]
ON [Theme].[ThemeTypeId] = [ThemeType].[PK_ThemeType]
join ProductTheme PT
on PT.ProductID=ThemeType.ProductID
WHERE ProductTheme.ProductID = VARIABLE-PARAMATER-HERE AND ProductTheme.ThemeId = Theme.PK_Theme
ORDER BY [ThemeType].[Type]
Depending on whether or not you need the WHERE condition before you add the 3rd table, you can try one of these 2 options:
SELECT *
FROM TABLE1 T1
LEFT OUTER JOIN TABLE2 T2
ON T1.FIELDA = T2.FIELDA
INNER JOIN TABLE3 T3
ON T1.FIELDA = T3.FIELDA
WHERE T1.FIELDB = 'aaa'
AND T3.FIELDC = 12
or:
SELECT *
FROM (SELECT T1.FIELDA,
T2.FIELDB
FROM TABLE1 T1
LEFT OUTER JOIN TABLE2 T2
ON T1.FIELDA = T2.FIELDA
WHERE T1.FIELDC = 'aaa')T3
INNER JOIN TABLE3 T4
ON T3.FIELDA = T3.FIELDA
AND T4.FIELDC = 12
I hope this gives you something to work with.
If you provide some sample data, I can set up a working example.