How does this query populate data? - postgresql

It is my understanding that when this query runs it would not populate any data any number of times it runs because of the where clause
where c.company_id = lot.company_id
and p.product_id = lot.product_id
and l.packlevel_id = lot.packlevel_id
It looks to me that at the very beginning when the table fact_table_lot is empty the where clause would return with empty data because it would not find anything in an empty table and it would happen everytime. Is my understanding wrong?
insert into fact_table_lot(company_id, product_id, packlevel_id, l_num, sn_count, comm_loct, comm_start, commdate_end, man_date, exp_date, user_id, created_datetime)
select c.company_id, p.product_id, l.packlevel_id, l_num, sn_count, comm_loct, comm_start, commdate_end, man_date, exp_date, user_id, sysdate
from staging_serials s
left outer join fact_table_lot lot on s.lotnumber = lot.l_num
join company c on c.lsc_company_id = s.companyid
join product p on s.compositeprodcode = p.compositeprodcode
join level l on l.unit_of_measure = p.packaginguom
where c.company_id = lot.company_id
and p.product_id = lot.product_id
and l.packlevel_id = lot.packlevel_id
and lot.created_datetime is null

In your query staging_serials s left outer join fact_table_lot lot on s.lotnumber= lot.l_num this will give the result set containing all records from staging_serials and since fact table is empty null values for those column from fact table. If you want no records to be returned use a inner join instead of left join.

Related

Return closest timestamp from Table B based on timestamp from Table A with matching Product IDs

Goal: Create a query to pull the closest cycle count event (Table C) for a product ID based on the inventory adjustments results sourced from another table (Table A).
All records from Table A will be used, but is not guaranteed to have a match in Table C.
The ID column will be present in both tables, but is not unique in either, so that pair of IDs and Timestamps together are needed for each table.
Current simplified SQL
SELECT
A.WHENOCCURRED,
A.LPID,
A.ITEM,
A.ADJQTY,
C.WHENOCCURRED,
C.LPID,
C.LOCATION,
C.ITEM,
C.QUANTITY,
C.ENTQUANTITY
FROM
A
LEFT JOIN
C
ON A.LPID = C.LPID
WHERE
A.facility = 'FACID'
AND A.WHENOCCURRED > '23-DEC-22'
AND A.ADJREASONABBREV = 'CYCLE COUNTS'
ORDER BY A.WHENOCCURRED DESC
;
This is currently pulling the first hit on C.WHENOCCURRED on the LPID matches. Want to see if there is a simpler JOIN solution before going in a direction that creates 2 temp tables based on WHENOCCURRED.
I have a functioning INDEX(MATCH(MIN()) solution in Excel but that requires exporting a couple system reports first and is extremely slow with X,XXX row tables.
If you are using Oracle 12 or later, you can use a LATERAL join and FETCH FIRST ROW ONLY:
SELECT A.WHENOCCURRED,
A.LPID,
A.ITEM,
A.ADJQTY,
C.WHENOCCURRED,
C.LPID,
C.LOCATION,
C.ITEM,
C.QUANTITY,
C.ENTQUANTITY
FROM A
LEFT OUTER JOIN LATERAL (
SELECT *
FROM C
WHERE A.LPID = C.LPID
AND A.whenoccurred <= c.whenoccurred
ORDER BY c.whenoccurred
FETCH FIRST ROW ONLY
) C
ON (1 = 1) -- The join condition is inside the lateral join
WHERE A.facility = 'FACID'
AND A.WHENOCCURRED > DATE '2022-12-23'
AND A.ADJREASONABBREV = 'CYCLE COUNTS'
ORDER BY A.WHENOCCURRED DESC;

SQL case when in join

I have a query with 2 tables that I want to join, but do to a software bug I can't always join them the same way. The TICKC table is supposed to have a foreignkey populated which would allow a join to the LABLOG table, however it's not always populated, and when it isn't populated I need to join it a different way. So I want to know how to write the join so that it joins on the foreign key if it's present, and if it isn't present then it should join on a different condition. This backup condition always exists, but the primary doesn't always exist.
LEFT OUTER JOIN TICKC
ON tickc.DELFLAG=0 and TICKC.LABLOGNO = LABLOG.CPK_LABLOG *This is the ideal join, but if TICKC.LABLOGNO is blank then it should join like this instead:*
tickc.NEXTCODE = LABLOG.SCRIPTEXT AND CONVERT(VARCHAR(10),TICKC.CREATEDON, 20) = CONVERT(VARCHAR(10),LABLOG.CREATEDON, 20)
Any help is appreciated, thank you
You could do something like this:
LEFT OUTER JOIN TICKC
ON (
tickc.DELFLAG = 0
AND TICKC.LABLOGNO = LABLOG.CPK_LABLOG
)
OR (
TICKC.LABLOGNO IS NULL
AND tickc.NEXTCODE = LABLOG.SCRIPTEXT
AND CONVERT(VARCHAR(10),TICKC.CREATEDON, 20) = CONVERT(VARCHAR(10),LABLOG.CREATEDON, 20)
)

T-SQL: Joining on two separate fields based on specific criteria in a query

I have a query in which I am trying to get additional fields from another table through a join field that I manually create. The issue is when the field I create is null, then I want to use another field to join on. I am not sure how to do that without getting duplicate results. I tried a UNION query, but that just displays everything where the values are null when the manually created field value is null. Here is the query:
SELECT
BU = m.BU,
BUFBA = m.BUFBA,
a.CostCenter,
Delegate = m.Delegate,
a.DistrictLookup,
PCOwner = m.PCOwner,
a.PGr,
a.POrg,
PrimaryContact = m.PrimaryContact,
WarehouseManager = m.WarehouseManager,
Zone = m.Zone,
ZoneFBA = m.ZoneFBA
FROM
(SELECT
e.CostCenter,
e.District,
DistrictLookup =
CASE
WHEN e.PGr IN ('N01','BQE','BQA') THEN 'GSS'
WHEN e.PGr = 'BQB' THEN 'BG'
WHEN e.PGr = 'BQF' THEN 'FP'
ELSE e.District
END,
e.PGr,
e.POrg
FROM dbo.E1P e (NOLOCK)
WHERE
e.CoCd = '4433'
) a
LEFT JOIN dbo.Mapping m (NOLOCK) ON m.District = a.DistrictLookup
When the DistrictLookup field is NULL, I need a different join to occur so that the additional fields populate. That join would be:
LEFT JOIN dbo.Mapping m (NOLOCK) ON m.CostCenter = a.CostCenter
How can I write in this second join and not get duplicate results? This is a separate join on different fields and I think it differs from the other methods of doing a conditional join. If it, can someone please explain how to implement that logic into my query?
I believe this is what you are after...
LEFT JOIN dbo.Mapping m (NOLOCK)
ON (a.DistrictLookup IS NOT NULL AND m.District = a.DistrictLookup)
OR (a.DistrictLookup IS NULL AND m.CostCenter = a.CostCenter)

How to use Not Equals in Postgresql Joins

I'm doing this:
select * from schema2."Student" a INNER JOIN
schema1."StudentMapping" b on ( a."StudentID" = b."StudentID")
where a."IsRemoved" = false AND b."IsRemoved" = false
to get only those records from Student table that are present in StudentMapping table, here IsRemoved column I'm using for soft deletion(i.e, whenever any record is to be deleted from any of those tables then only I'm setting it to true, so for IsRemoved = false records are present in the tables) and the query is working fine. Now what I wanted is to get all those records from Student table that are not present in StudentMapping table so I tried this:
select * from schema2."Student" a INNER JOIN
schema1."StudentMapping" b on ( a."StudentId" != b."StudentId")
where a."IsRemoved" = false AND
b."IsRemoved" = false
but this is giving lot of records, more than I expected, what is wrong with this query or is there another way in Postgresql to get all matching recording from one table that are not present in another table.
Do a LEFT OUTER JOIN and then in the where clause, specify to only show recods where the join resulted in a NULL:
select * from schema1."Student" a LEFT OUTER JOIN
schema1."StudentMapping" b on ( a."StudentID" = b."StudentID")
where a."IsRemoved" = false
and b.StudentID IS NULL

Joining several tables: table specified more than once error

I am attempting to call data after joining all of my tables in a postgreSQL query.
I am getting the following error:
Error in postgresqlExecStatement(conn, statement, ...) :
RS-DBI driver: (could not Retrieve the result : ERROR: table name "place" specified more than once
)
Failed to execute SQL chunk
After referring to similar posts and online resources, I have attempted setting aliases (which only create new errors about not referring to the other tables in the FROM clause), reordering the table names (the cleanest, reordered chunk is posted below), and experimenting with UPDATE/FROM/JOIN as an alternative to SELECT/FROM/JOIN. However, I think I ultimately need to be using the SELECT clause.
SELECT *
FROM place
INNER JOIN place ON place.key = form.key
INNER JOIN form ON form.id = items.formid
INNER JOIN items ON items.recid = rec.id
INNER JOIN rec ON rec.id = sub.recid
INNER JOIN sub ON sub.id = type.subid
INNER JOIN type ON type.name = det.typeid;
You have "place" in your query twice, which is allowed but you would have to alias the second use of the table "place". Also you reference something called "det", but it's not a table or alias anywhere in your query. If you want only one place that's fine, just remove the INNER JOIN place and move your place.key = form.key to the form join or to a where clause.
If you want to place tables in their because you are trying to join the table to itself the alias the second one, but you will want to make sure that you then have a clause to join those two tables on (could be part of an on or a where)
The issue ended up being the order of table names. The code below joined everything just fine:
SELECT *
FROM place
INNER JOIN form ON place.key = form.key
INNER JOIN items ON form.id = items.formid
INNER JOIN rec ON items.recid = rec.id
INNER JOIN sub ON rec.id = sub.recid
INNER JOIN type ON sub.id = type.subid
INNER JOIN det ON type.name = det.typeid;