get Value that does not exist in another table and vice versa - sql

I have two table named lu_timepoint which holds default timepoints and another operational table called tbl_data.
The tbl_data contains details about a candidate and a timepoint when he has to come for lab test. The timepoint will range from -30 mins to 24 hrs
The lu_timepoint table is the lookup table for the default timepoints.
I need to write a query that will check whether the timepoint in tbl_data exist in the lu_timepoint table and if its not there i need have the value as false in a column called checked.
Likewise if the timepoint in the lu_timepoint table does not exist in the tbl_data table i need have the value as false in the column checked. else true in a checked column.
I tried with Left Join however i'm getting more rows count due to incorrect join statement.
below is the code i used to get all the candidate id whose timepoint is not equal to the other table
select distinct PT, PCTPT
from tbl_data s
left join lu_Timepoint t
on s.STUDY = t.Study
where s.PCTPT = t.Timepoint
Data is attached in the below link...
Table Data

If you want to get the records that doesn't exists in the joined tabled and vice versa, you can use FULL OUTER JOIN that display the distinct values from each table.
Specifying the database you are using and providing the tables structures and some of your data will help to build the final query.

I have found out the solution for this. I did a left join with the lu_timepoint table and tbl_data and got the values that does not exist in both the tables.
Below is the query i used.
select Candidate, CPEVENT, Test_Number, DosedTime, DoseTime, ExpectedTime, s.Timepoint as tmpt, t.Timepoint as tmpt1, CASE WHEN t.Timepoint IS NULL THEN 'Not Collected' WHEN s.timepoint IS NULL THEN 'Not Collected' ELSE 'Collected' END as Timepoint_Collection, case when t.timepoint is null THEN s.timepoint WHEN s.timepoint IS NULL THEN t.Timepoint WHEN s.timepoint = t.TIMEPOINT THEN s.timepoint END as Timepoint from vw_data s FULL OUTER JOIN lu_pk_Timepoint t on s.PCTPT = t.Timepoint AND s.STUDY=t.Study

Related

Assigning a value from one table to other table

There are two tables Table A and Table B. These contains the same columns cost and item. The Table B contains the list of items and their corresponding costs whereas the Table A contains only the list of items.
Now we need to check the items of Table A, if they are present in the Table B then the corresponging item cost should be assigned to the item's cost in Table A.
Can someone help me out by writing a query for this.
Consider the tables as shown:
Table A:
item cost
-------------
pen null
book null
watch null
Table B:
item cost
-------------
watch 1000
book 50
Expected output
Table A:
item cost
pen 0
book 50
watch 1000
Just add a foreign key (primary key of table A) in the Table B as you can say table A ID then add a join(right join may be) in the query to get or assign the prices respective items.
join be like
SELECT item, cost
FROM tablename a
RIGHT JOIN tablename b ON a.item= b.item;
Edit:
Just edit this table name ,now run it.
I would structure the update like this:
with cost_data as (
select
item,
max (cost) filter (where item = 'watch') as watch,
max (cost) filter (where item = 'book') as book
from table_b
group by item
)
update table_a a
set
watch = c.watch,
book = c.book
from cost_data c
where
a.item = c.item and
(a.watch is distinct from c.watch or
a.book is distinct from c.book)
In essence, I am doing a common table expression to do a poor man's pivot table on the Table B to get the rows into columns. One caveat here -- if there are multiple costs listed for the same item, this may not do what you want, but then you would need to know how to handle that in almost any case.
Then I am doing an "update A from B" against the CTE.
The last part is not critical, per se, but it is helpful -- to limit the query to only execute on rows that need to change. It's best to limit DML if it doesn't need to occur (the best way to optimize something is to not do it).
There are plenty of ways you could do this, if you are taking table b to be the one containing the price then a left outer join would do the trick.
SELECT
table_a.item,
CASE
WHEN table_b.cost IS NULL
THEN 0
ELSE table_b.cost
END as cost
FROM table_a
LEFT OUTER JOIN table_b ON table_a.item = table_b.item
The result also appears to suggest that pen which is not in table b should have a price of 0 (this is bad practice) but for the sake of returning the desired result you will want a case statement to assign a value if it is null.
In order to update the table, as per the comment
update table_a set cost = some_alias.cost
from (
SELECT
table_a.item,
CASE
WHEN table_b.cost IS NULL
THEN 0
ELSE table_b.cost
END as cost
FROM table_a
LEFT OUTER JOIN table_b ON table_a.item = table_b.item
) some_alias
where table_a.item = some_alias.item

How to query for getting value from either Table A or B?

This is Datagridview which I need to display on the screen like these.
(Datagrid view is binding with the "main table" (RECEIVE_PLAN))
Concept Design database:
if you want to import something into warehouse, you must plan for receiving in a day.
Receiving Plan is made from "Purchase Order" directly
Or sometime your warehouse has a receiving schedule before ordering.
Database has three tables, including Table A and Table B and Main Table.
They have a relation like these.
Note: the main table has two options for getting value for display to the screen
get "PO_LIST_NO" and "PO_NO" from A table(PURCHASE ORDER table) directly.
get "PO_LIST_NO" and "PO_NO" from B table(RECEIVE SCHEDULE table) then get value from A table.
Important Conditions
In main table (RECEIVE PLAN) must have a value in either "PO_ID" or "RS_ID"
If main table (RECEIVE PLAN) has a value at PO_ID column, RS_ID column must be NULL.
On the other hand, If main table (RECEIVE PLAN) has a value at
RS_ID column, PO_ID column must be NULL
Main Table (RECEIVE PLAN) must not NULL both PO_ID and RS_ID
Main Table (RECEIVE PLAN) must not has a value at both PO_ID and RS_ID
RECEIVE PLAN's example like below.
(PO_TRAN_ID) is PO_ID
(RS_TRAN_ID) is RS_ID in this case.
QUESTION :How to query for getting value from either Table A or B?
How to join between a main table,A and B table for display like these.
This datagridview Properties.
BindingSource : main table (RECEIVE_PLAN)
"PO LIST NO" column : getting from A table (PURCHASE_ORDER)
"PO NO" column : getting from A table (PURCHASE_ORDER)
"PLAN QTY" column : getting from main table (RECEIVE PLAN)
Something like this?
SELECT A_TABLE.PO_LIST_NO, A_TABLE.PO_NO, SUM(MAIN_TABLE.PLAN_QTY) FROM A_TABLE
INNER JOIN B_TABLE ON A_TABLE.PO_ID = B_TABLE.PO_ID
INNER JOIN MAIN_TABLE ON MAIN_TABLE.PO_ID = B_TABLE.PO_ID OR MAIN_TABLE.RS_ID = B_TABLE.RS_ID
WHERE (MAIN_TABLE.RS_ID IS NOT NULL OR MAIN_TABLE.PO_ID IS NOT NULL) AND NOT (MAIN_TABLE.RS_ID IS NOT NULL AND MAIN_TABLE.PO_ID IS NOT NULL)
GROUP BY A_TABLE.PO_LIST_NO, A_TABLE.PO_NO
I can solved it by using this query.
( SELECT MAIN_TABLE.*, A_TABLE.PO_LIST_NO, A_TABLE.PO_NO
FROM MAIN_TABLE
LEFT OUTER JOIN A_TABLE
ON MAIN_TABLE.PO_ID = A_TABLE.TRAN_ID
WHERE (MAIN_TABLE.RS_ID IS NULL)
)
UNION
( SELECT MAIN_TABLE.* , A_TABLE.PO_LIST_NO , A_TABLE.PO_NO
FROM MAIN_TABLE
LEFT OUTER JOIN B_TABLE
ON MAIN_TABLE.RS_ID = B_TABLE .TRAN_ID
LEFT OUTER JOIN A_TABLE
ON B_TABLE .PO_ID = A_TABLE.TRAN_ID
WHERE (MAIN_TABLE.PO_ID IS NULL)
)

merging two rows in Oracle

The reason for me in merging two rows is because the table I'm referring to stores transactions in both Debit and Credit. therefore, whenever a transaction occurs, there will always be two new records inserted into the table, one for Debit and one for Credit. What I need to do is merge those two related transactions, for example:
into something that looks like this:
forgot one thing. how the Debit and Credit amount is determined is by this code:
CASE WHEN DTD.PART_TRAN_TYPE = 'D'
THEN (DTD.TRAN_AMT)
ELSE null
END DR_Amount,
CASE WHEN DTD.PART_TRAN_TYPE = 'C'
THEN (DTD.TRAN_AMT)
ELSE null
END CR_Amount,
the amounts just come from one table.
What you want here is an SQL JOIN query.
Assuming the table name is 'trans', Something like:
SELECT table1.TRANSACTION_ID, table1.ACCT_CURRENCY,
table1.DR_AMOUNT, table2.CR_AMOUNT
FROM trans table1
INNER JOIN trans table2 on table1.TRANSACTION_ID = table2.TRANSACTION_ID
This uses an INNER JOIN to join the table 'trans' with itself. We do this by giving the table an alias ('FROM trans table1' lets us refer to an instance of trans with 'table1').
The 'on' statement tells Oracle to take every record from table1 and join it to a record from table2 that has the same 'TRANSACTION_ID' field value.
In your case you will have a record with either Credit value or Debit value.
Consider a Table Name as TRANS_INFO with sample record
Query :
SELECT * FROM TRANS_INFO CR_TABLE
INNER JOIN TRANS_INFO DR_TABLE ON CR_TABLE.TRANS_ID = DR_TABLE.TRANS_ID
AND (CR_TABLE.CR_AMOUNT <> '') AND (DR_TABLE.DR_AMOUNT <> '')
OutPut: As a Merged row based on TRANS_ID

SQL INNER JOIN vs. WHERE ID IN(...) not the same results

I was surprised by the outcome of these two queries. I was expecting same from both. I have two tables that share a common field but there is not a relationship set up. The table (A) has a field EventID varchar(10) and table (B) has a field XXNumber varchar(15).
Values from table B column XXNumber are referenced in table A column EventID. Even though XXNumber can hold 15 chars, none of the 179K rows of data is longer than 10 chars.
So the requirement was:
"To avoid Duplicate table B and table A entries, if the XXNumber is contained in a table A >“Event ID” number, then it should not be counted."
To see how many common records I have I ran this query first - call it query alpha"
SELECT dbo.TableB.XXNumber FROM dbo.TableB WHERE dbo.TableB.XXNumber in
( select distinct dbo.TableA.EventId FROM dbo.TableA )
The result was 5322 rows.
The following query - call it query delta which looks like this:
SELECT DISTINCT dbo.TableB.XXNumber, dbo.TableB.EventId
FROM dbo.TableB INNER JOIN dbo.TableA ON dbo.TableB.XXNumber= dbo.TableB.EventId
haas returned 4308 rows.
Shouldn't the resulting number of rows be the same?
The WHERE ID IN () version will select all rows that match each distinct value in the list (regardless of whether you code DISTINCT indide the inner select or not - that's irrelevant). If a given value appears in the parent table more than once, you'll get multipke rows selected from the parent table for that single value found in the child table.
The INNER JOIN version will select each row from the parent table once for every successful join, so if there are 3 rows in the child table with the value, and 2 in the parent, then there will be 6 rows rows in the result for that value.
To make them "the same", add 'DISTINCT' to your main select.
To explain what you're seeing, we'd need to know more about your actual data.

SQL Server 2005 - How to take a record from one table and loop through another table looking for match

I have 2 tables. for this example I will use only one users records.
The first table has the user name and an evaluation date as such:
USER EVALDATE
--------------
bobr 6/7/2010
bobr 9/20/2010
bobr 9/21/2010
The above table needs to be joined against this user history table, which has the history of the ID's and the dates they were valid, to look for a match (the NULL date means current):
USER STARTDATE ENDDATE
----------------------------
bobr 2/20/2006 4/18/2010
bobr2 4/19/2010 9/7/2010
bobr 9/8/2010 null
What I'm trying to do in SQL Server 2005 is take the first record from the first table, loop it through the second table and when(if) the EVALDATE is within one of these date ranges and the IDs match, then flag that record from the first table as valid.
The current code takes the record from the first table and runs against all rows of the second table and kicks out a record for each invalid evaldate, so it kicks out a record when joined against the second table because the evaldate is not between the dates of the first record on the history table, even though the record is fine because the evaldate is between the start and end dates of the third record in the history table.
I hope this makes sense! In something like SAS I can create an array and loop through checking against each record in the history table. How do I do this in SQL? What I was trying to do was just update the first table with a flag if the records dates are invalid. Any ideas? Thanks!!!
Try this:
SELECT [USER]
,[EVALDATE]
,CASE WHEN ( SELECT COUNT(*)
FROM [UserStartEndDates] b
WHERE [a].[USER] = [b].[User]
AND [EVALDATE] BETWEEN [STARTDATE]
AND COALESE([ENDDATE],[EVALDATE])
) > 0 THEN 1
ELSE 0
END AS [IsValid]
FROM [Evaluations] a
You can try something like
Select *
FROM Users u INNER JOIN
UserHistory uh ON u.User = uh.User
AND u.EvalDate BETWEEN uh.StartDate
AND ISNULL(uh.EndDate, u.EvalDate)
EDIT
Try this for all values from User
Select u.*,
CASE
WHEN uh.User IS NULL
THEN 'Invalid'
ELSE 'Valid'
END Validity
FROM Users u LEFT JOIN
UserHistory uh ON u.User = uh.User
AND u.EvalDate BETWEEN uh.StartDate
AND ISNULL(uh.EndDate, u.EvalDate)
try something like:
select * from [table2] t2
join [table1] t1 on t1.user = t2.user
--or better yet the foreign key
where t1.user = t2.user and t1.evaldate
between t2.startdate and t2.enddate