How do I run a SQL query against 2 views that are linked by an ID but has different column names? - sql

I currently have 2 views that house some data.
View1: includes patientsPID and their billing/invoice information (high-level)
View2: includes patientsCID and their respective line items for their billing invoice information (granularity of View1)
I am trying to run a query where I will be able to validate some data. E.g. -> I want to see patientsPID = 1 and see the total amount paid and join it to View2 to see in more details on the invoice.
expected results
Thank you.

You need to join View1 and View2:
select v1.patientspid, v1.invoiceheader, v2.invoiceline, v2.amount
from view1 v1 inner join view2 v2
on v1.patientspid = v2.patientscid
order by v1.patientspid
If you want to get the results for a patientspid use
where v1.patientspid = 1
and no order by

In this case both PatientsPID and PatientsCID act as your Key. The column names don't have to be the same as long as the data contained in them are linked (Same Data).
Select View1.PatientsPID, View1.AmountPaid, View2.[SomeColumnName]
From View1 inner join View2 on View1.PatientsPID = View2.PatientsCID
Where View1.PatientsPID = 1
Use Join in the From line and you have to set which columns are equal between the two tables. These columns have to contain the same data in order to be able to link. Whatever column names you want to select just place the table name in front of it as show above, this prevents errors in the event of an ambiguous column name

Related

Microsoft SQL Server generates two select queries and puts data in separate columns

I am looking for a query that separate the data with the condition WHERE in the same output but in separates columns.
Example: I have the table Product_2:
I have two separates queries (to separate the products by Produt_Tag):
SELECT
Product_Mark AS "PIT-10_Product_Mark",
Product_Model AS "PIT-10_Product_Model"
FROM Product_2
WHERE Product_Tag = 'PIT-10';
SELECT
Product_Mark AS "PIT-11_Product_Mark",
Product_Model AS "PIT-11_Product_Model"
FROM Product_2
WHERE Product_Tag = 'PIT-11';
And I get this output:
But I need the output to be like this:
Can someone tell me how I need to modify my query to have the four columns in the same table/ output?
Thank you
I forgot to tell that in the data I Have the “Porduct_Mark” that only appears one time. (in reality the data in “Product_Mark” is the name of the place where the instrument is located and one place can have one or two instruments “Product_Model”. At the end I’m looking for the result show in the image here below. I tried to use LEFT JOIN but that don’t work.
here is the new table "Product_2"
Result that I'm looking for:
Luis Ardila
I am assuming Product_PK is the primary key for the table and the repeated value 1002 shown in the question is a mistake. Considering this assumption, you can get the result set using self join as below.
SELECT pa.Product_Mark AS "PIT-10_Product_Mark", pa.Product_Model AS "PIT-10_Product_Model",
pb.Product_Mark AS "PIT-11_Product_Mark", pb.Product_Model AS "PIT-11_Product_Model"
FROM Product_2 pa
INNER JOIN Product_2 pb
ON pa.Product_Mark = pb.Product_Mark
WHERE pa.product_pk != pb.product_pk
and pa.Product_Tag = 'PIT-10'
and pb.Product_Tag = 'PIT-11';
verified same in https://dbfiddle.uk/NiOO8zc1

SQL - join three tables based on (different) latest dates in two of them

Using Oracle SQL Developer, I have three tables with some common data that I need to join.
Appreciate any help on this!
Please refer to https://i.stack.imgur.com/f37Jh.png for the input and desired output (table formatting doesn't work on all tables).
These tables are made up in order to anonymize them, and in reality contain other data with millions of entries, but you could think of them as representing:
Product = Main product categories in a grocery store.
Subproduct = Subcategory products to the above. Each time the table is updated, the main product category may loses or get some new suproducts assigned to it. E.g. you can see that from May to June the Pulled pork entered while the Fishsoup was thrown out.
Issues = Status of the products, for example an apple is bad if it has brown spots on it..
What I need to find is: for each P_NAME, find the latest updated set of subproducts (SP_ID and SP_NAME), and append that information with the latest updated issue status (STATUS_FLAG).
Please note that each main product category gets its set of subproducts updated at individual occasions i.e. 1234 and 5678 might be "latest updated" on different dates.
I have tried multiple queries but failed each time. I am using combos of SELECT, LEFT OUTER JOIN, JOIN, MAX and GROUP BY.
Latest attempt, which gives me the combo of the first two tables, but missing the third:
SELECT
PRODUCT.P_NAME,
SUBPRODUCT.SP_PRODUCT_ID, SUBPRODUCT.SP_NAME, SUBPRODUCT.SP_ID, SUPPRODUCT.SP_VALUE_DATE
FROM SUBPRODUCT
LEFT OUTER JOIN PRODUCT ON PRODUCT.P_ID = SUBPRODUCT.SP_PRODUCT_ID
JOIN(SELECT SP_PRODUCT_ID, MAX(SP_VALUE_DATE) AS latestdate FROM SUBPRODUCT GROUP BY SP_PRODUCT_ID) sub ON
sub.SP_PRODUCT_ID = SUBPRODUCT.SP_PRODUCT_ID AND sub.latestDate = SUBPRODUCT.SP_VALUE_DATE;
Trying to find a row with a max value is a common SQL pattern - you can do it with a join, like your example, but it's usually more clear to use a subquery or a window function.
Correlated subquery example
select
PRODUCT.P_NAME,
SUBPRODUCT.SP_PRODUCT_ID, SUBPRODUCT.SP_NAME, SUBPRODUCT.SP_ID, SUPPRODUCT.SP_VALUE_DATE,
ISSUES.STATUS_FLAG, ISSUES.STATUS_LAST_UPDATED
from PRODUCT
join SUBPRODUCT
on PRODUCT.P_ID = SUBPRODUCT.SP_PRODUCT_ID
and SUBPRODUCT.SP_VALUE_DATE = (select max(S2.SP_VALUE_DATE) as latestDate
from SUBPRODUCT S2
where S2.SP_PRODUCT_ID = SUBPRODUCT.SP_PRODUCT_ID)
join ISSUES
on ISSUES.ISSUE_ID = SUBPRODUCT.SP_ID
and ISSUES.STATUS_LAST_UPDATED = (select max(I2.STATUS_LAST_UPDATED) as latestDate
from ISSUES I2
where I2.ISSUE_ID = ISSUES.ISSUE_ID)
Window function / inline view example
select
PRODUCT.P_NAME,
S.SP_PRODUCT_ID, S.SP_NAME, S.SP_ID, S.SP_VALUE_DATE,
I.STATUS_FLAG, I.STATUS_LAST_UPDATED
from PRODUCT
join (select SUBPRODUCT.*,
max(SP_VALUE_DATE) over (partition by SP_PRODUCT_ID) as latestDate
from SUBPRODUCT) S
on PRODUCT.P_ID = S.SP_PRODUCT_ID
and S.SP_VALUE_DATE = S.latestDate
join (select ISSUES.*,
max(STATUS_LAST_UPDATED) over (partition by ISSUE_ID) as latestDate
from ISSUES) I
on I.ISSUE_ID = S.SP_ID
and I.STATUS_LAST_UPDATED = I.latestDate
This often performs a bit better, but window functions can be tricky to understand.

How to show elements from 2 tables ( existing in one , another or both)

I have 2 tables than i need to fuse together for data analysis.
Table One ( shows year consumption of items with values, from a contract)
Table One fields : product code, quantity, total value, contract number
Table Two (shows contract defined included products)
Table Two fields : included product code, included quantity, total included value, contract number
I need to join both of them so that shows per contract, all the related products, both consumed or included, so that shows either i only have consumed but not included, included but not consumed and included and consumed...
Something like this :
Contract|Product Code|Consumed qty|Included Qty|Consumed Total|Included Total
CTC001|X0001|55|45|550|450
CTC001|X0002|20|NULL|200|NULL
CTC001|X0003|NULL|10|NULL|100
CTC002|X0001|10|10|100|100
Using inner join only shows the ones on both tables
Using left or right joins shows all from one table and similar and null's from other table...
My goal was to show from both tables, has the example
Any help or tip ?
(this is my current query, field names not all equal as example, but you get the idea :
SELECT dbo.USR_View_ArtIncludContr.strCodArtigo, dbo.USR_View_TotaisConsumos.strCodArtigo AS Expr2, dbo.USR_View_TotaisConsumos.QTDTOTAL,
dbo.USR_View_ArtIncludContr.fltQuantLimiteInc, dbo.USR_View_TotaisConsumos.VALORTOTAL, dbo.USR_View_ArtIncludContr.Total, dbo.USR_View_TotaisConsumos.strCodSecContrato,
dbo.USR_View_TotaisConsumos.strCodTpContrato, dbo.USR_View_TotaisConsumos.strCodExercContrato, dbo.USR_View_TotaisConsumos.intNumeroContrato, dbo.USR_View_ArtIncludContr.strCodSeccao,
dbo.USR_View_ArtIncludContr.strCodTpContrato AS Expr1, dbo.USR_View_ArtIncludContr.strCodExercicio, dbo.USR_View_ArtIncludContr.intNumero
FROM dbo.USR_View_ArtIncludContr INNER JOIN
dbo.USR_View_TotaisConsumos ON dbo.USR_View_ArtIncludContr.strCodSeccao = dbo.USR_View_TotaisConsumos.strCodSecContrato AND
dbo.USR_View_ArtIncludContr.strCodTpContrato = dbo.USR_View_TotaisConsumos.strCodTpContrato AND
dbo.USR_View_ArtIncludContr.strCodExercicio = dbo.USR_View_TotaisConsumos.strCodExercContrato AND dbo.USR_View_ArtIncludContr.intNumero = dbo.USR_View_TotaisConsumos.intNumeroContrato AND
dbo.USR_View_ArtIncludContr.strCodArtigo = dbo.USR_View_TotaisConsumos.strCodArtigo
Sounds like you want a full join:
SELECT aic.strCodArtigo, tc.strCodArtigo AS Expr2, tc.QTDTOTAL,
aic.fltQuantLimiteInc, tc.VALORTOTAL, aic.Total, tc.strCodSecContrato,
tc.strCodTpContrato, tc.strCodExercContrato, tc.intNumeroContrato, aic.strCodSeccao,
aic.strCodTpContrato AS Expr1, aic.strCodExercicio, aic.intNumero
FROM dbo.USR_View_ArtIncludContr aic FULL JOIN
dbo.USR_View_TotaisConsumos tc
ON aic.strCodSeccao = tc.strCodSecContrato AND
aic.strCodTpContrato = tc.strCodTpContrato AND
aic.strCodExercicio = tc.strCodExercContrato AND
aic.intNumero = tc.intNumeroContrato AND
aic.strCodArtigo = tc.strCodArtigo
Notice that column aliases make the query much easier to write and to read.
Just figure out an workaround...
i could use CASE WHEN for the contract and for product code...
Something like this in select :
"CASE WHEN AIC.strCodArtigo IS NULL THEN TC.strCodArtigo WHEN TC.strCodArtigo IS NULL THEN AIC.strCodArtigo ELSE AIC.strCodArtigo END AS ARTIGO "
And use FULL OUTER JOIN
In case anyone has a better way, i appreciate any opinion

how to join multiple tables without showing repeated data?

I pop into a problem recently, and Im sure its because of how I Join them.
this is my code:
select LP_Pending_Info.Service_Order,
LP_Pending_Info.Pending_Days,
LP_Pending_Info.Service_Type,
LP_Pending_Info.ASC_Code,
LP_Pending_Info.Model,
LP_Pending_Info.IN_OUT_WTY,
LP_Part_Codes.PartCode,
LP_PS_Codes.PS,
LP_Confirmation_Codes.SO_NO,
LP_Pending_Info.Engineer_Code
from LP_Pending_Info
join LP_Part_Codes
on LP_Pending_Info.Service_order = LP_Part_Codes.Service_order
join LP_PS_Codes
on LP_Pending_Info.Service_Order = LP_PS_Codes.Service_Order
join LP_Confirmation_Codes
on LP_Pending_Info.Service_Order = LP_Confirmation_Codes.Service_Order
order by LP_Pending_Info.Service_order, LP_Part_Codes.PartCode;
For every service order I have 5 part code maximum.
If the service order have only one value it show the result correctly but when it have more than one Part code the problem begin.
for example: this service order"4182134076" has only 2 part code, first'GH81-13601A' and second 'GH96-09938A' so it should show the data 2 time but it repeat it for 8 time. what seems to be the problem?
If your records were exactly the same the distinct keyword would have solved it.
However in rows 2 and 3 which have the same Service_Order and Part_Code if you check the SO_NO you see it is different - that is why distinct won't work here - the rows are not identical.
I say you have some problem in one of the conditions in your joins. The different data is in the SO_NO column so check the raw data in the LP_Confirmation_Codes table for that Service_Order:
select * from LP_Confirmation_Codes where Service_Order = 4182134076
I assume you are missing an and with the value from the LP_Part_Codes or LP_PS_Codes (but can't be sure without seeing those tables and data myself).
By this sentence If the service order have only one value it show the result correctly but when it have more than one Part code the problem begin. - probably you are missing and and with the LP_Part_Codes table
Based on your output result, here are the following data that caused multiple output.
Service Order: 4182134076 has :
2 PartCode which are GH81-13601A and GH96-09938A
2 PS which are U and P
2 SO_NO which are 1.00024e+09 and 1.00022e+09
Therefore 2^3 returns 8 rows. I believe that you need to check where you should join your tables.
Use DINTINCT
select distinct LP_Pending_Info.Service_Order,LP_Pending_Info.Pending_Days,
LP_Pending_Info.Service_Type,LP_Pending_Info.ASC_Code,LP_Pending_Info.Model,
LP_Pending_Info.IN_OUT_WTY, LP_Part_Codes.PartCode,LP_PS_Codes.PS,
LP_Confirmation_Codes.SO_NO,LP_Pending_Info.Engineer_Code
from LP_Pending_Info
join LP_Part_Codes on LP_Pending_Info.Service_order = LP_Part_Codes.Service_order
join LP_PS_Codes on LP_Part_Codes.Service_Order = LP_PS_Codes.Service_Order
join LP_Confirmation_Codes on LP_PS_Codes.Service_Order = LP_Confirmation_Codes.Service_Order
order by LP_Pending_Info.Service_order, LP_Part_Codes.PartCode;
distinct will not return duplicates based on your select. So if a row is same, it will only return once.

outer query to list only if its rowcount equates to inner subquery

Need help on a query using sql server 2005
I am having two tables
code
chargecode
chargeid
orgid
entry
chargeid
itemNo
rate
I need to list all the chargeids in entry table if it contains multiple entries having different chargeids
which got listed in code table having the same charge code.
data :
code
100,1,100
100,2,100
100,3,100
101,11,100
101,12,100
entry
1,x1,1
1,x2,2
2,x3,2
11,x4,1
11,x5,1
using the above data , it query should list chargeids 1 and 2 and not 11.
I got the way to know how many rows in entry satisfies the criteria, but m failing to get the chargeids
select count (distinct chargeId)
from entry where chargeid in (select chargeid from code where chargecode = (SELECT A.chargecode
from code as A join code as B
ON A.chargecode = B.chargeCode and A.chargetype = B.chargetype and A.orgId = B.orgId AND A.CHARGEID = b.CHARGEid
group by A.chargecode,A.orgid
having count(A.chargecode) > 1)
)
First off: I apologise for my completely inaccurate original answer.
The solution to your problem is a self-join. Self-joins are used when you want to select more than one row from the same table. In our case we want to select two charge IDs that have the same charge code:
SELECT DISTINCT c1.chargeid, c2.chargeid FROM code c1
JOIN code c2 ON c1.chargeid != c2.chargeid AND c1.chargecode = c2.chargecode
JOIN entry e1 ON e1.chargeid = c1.chargeid
JOIN entry e2 ON e2.chargeid = c2.chargeid
WHERE c1.chargeid < c2.chargeid
Explanation of this:
First we pick any two charge IDs from 'code'. The DISTINCT avoids duplicates. We make sure they're two different IDs and that they map to the same chargecode.
Then we join on 'entry' (twice) to make sure they both appear in the entry table.
This approach gives (for your example) the pairs (1,2) and (2,1). So we also insist on an ordering; this cuts to result set down to just (1,2), as you described.