Facing in joining tables - sql

There are five tables
Items (ItemNo,productName)
ProductBatch (productBatchId,ItemNo,batchName,purchaseRate)
DamageStock (AdjustmentId,date,description)
DamageStockItem (damageStockDetailsId,AdjustmentId,productBatchId)
StockPosting (serialNumber,productBatchId,outwardQuantity,voucherType).
My aim is that to retrieve all information from above tables for each damage stock item through this query:
select
P1.ItemNo, B1.productBatchId, S1.serialNumber,
P1.productName, S1.outwardQuantity, DS.damageStockDetailsId
FROM
Items AS P1
INNER JOIN
ProductBatch AS B1 ON P1.ItemNo = B1.ItemNo
INNER JOIN
StockPosting AS S1 ON B1.productBatchId = S1.productBatchId
INNER JOIN
DamageStockItem as DS on DS.productBatchId = B1.productBatchId
INNER JOIN
DamageStock AS MASTER1 ON MASTER1 .AdjustmentId = DS.ItemAdjustmentId
WHERE
S1.voucherType = 'Damage Stock'
AND DS.ItemAdjustmentId = '10001'
but it shows duplicate values for damageStockDetailsId which is the primary key of DamageStockItem table and I don't know that there is any problem in the relationships between these tables or no and also I solved this problem when I made a relation between StockPosting table and DamageStock , I put the primary key of StockPosting table in DamageStockItem as foreign key and it did not show any duplicate value. I want to know that this relationship is correct or no. I need your ideas regarding this issue.

You can have several damageStockDetailsId per AdjustmentId in your table DamageStockItem (or DamageStockDetails, whatever it is called).
As those are connected to an AdjustmentId you should output that too, to see where the (seemingly same) damageStockDetailsIds belong to.

Related

how do use inner join to join two usernames from a second table, once as a sender and then as a receiver; then add records from a third table in SQL?

I have three tables in sql.
transcation_table: id(pk), date_time, sender_wallet(fk), amount_sent, sender_updated_balance, receiver_wallet(fk), amount_received, receiver_updated_balance
wallet_table: id(pk), userid(fk), wallet, currency, balance
user_table: id(pk), uname
all 'id' fields are primary keys
wallet_table.userid is foreign key of user_table.id
transaction_table.sender_wallet is foreign key of wallet_table.id
transaction_table.receiver_wallet is foreign key of wallet_table.id
I am trying to ask the database to give me a new table where any of the records in transaction_table contain a sender_wallet and receiver_wallet for a particular user.
The new returned table should be like:
date_time, sender_uname, amount_sent, sender_updated_balance, receiver_uname, amount_received, receiver_updated_balance
sender_uname and receiver_uname are new columns to be created for the purpose of making a distinction between the sender and receiver username in the newly returned table.
A returned result would be something like:
2023-02-03 09:57:38, marvin381, 40.00, 360.00, hamarni242, 40.00, 440.00
I made some poor attempts at trying to receive the intended result.
I am unable to see how I can pull the uname from the wallet_table effectively twice and join to the new table.
I also am not getting close to creating the new columns 'sender_uname' and 'receiver_uname'.
I have managed to get the inner join to work getting the data but with only one uname, but not the uname twice under 'sender' and 'receiver'.
which is not even working or coming close to the result.
select t.id,
t.date_time,
su.uname as sender_uname,
t.amount_sent,
t.sender_updated_balance,
ru.uname as receiver_uname,
t.amount_received,
t.receiver_updated_balance
from transcation_table t
inner join wallet_table sw on t.sender_wallet = sw.id
inner join wallet_table rw on t.receiver_wallet = rw.id
inner join user_table su on su.id = sw.userid
inner join user_table ru on ru.id = rw.userid
where su.id = x or ru.id = x;
That x would be a parameter (or a constant) written depending on your database which you didn't specify in tags.
PS: You could also join wallet_table and user table once with a CTE but I didn't want to go that route without knowing your database.
Here is a DBFiddle sample

Can you join two select statements when the composite primary keys are not in both statements

I need some advice.
I have an issue with joining two tables.
Example: Owner has a five-piece composite key
Position has a Six piece composite key
Owner Table has
As_Of_Date(Key), PORT_CD (Key), Deal_Or_Schedule (Key), Deal_Sched_No(Key),owner_port_cd (Key),Percent
Position table has
As_Of_Date (Key),PORT_CD (Key),Deal_Or_Schedule (Key), Deal_Sched_No (Key), Book_CD_Nme (Key),Positn_Num (Key)
As you can see 4 of the conditions match in Owner to join to table 2 but Onwer_port_cd cant be joined in as it's not in Position.
I need to get one table from the two tables so I can map income to its owner.
Right now my join results in a cartesian product as it's not taking in all qualifiers.
Try this:
SELECT *
FROM JUNE_INCOME JI
JOIN CHART_OF_ACCOUNTS CA
ON JUNE_INCOME.GL_ACCT_NO = CHART_OF_ACCOUNTS.GL_ACCT_NO
JOIN SECURITY_MASTER SM
ON JUNE_INCOME.INS_NO = SECURITY_MASTER.INS_NO
JOIN POSITION_ALLOCATION PA
ON JUNE_INCOME.TRADE_DT = POSITION_ALLOCATION.AS_OF_DATE
AND JUNE_INCOME.PORT_CD = POSITION_ALLOCATION.PORT_CD
AND JUNE_INCOME.BOOK_CD_NME = POSITION_ALLOCATION.BOOK_CD_NME
AND JUNE_INCOME.POSITN_NUM = POSITION_ALLOCATION.POSITN_NUM
JOIN POSITIONS PO
ON JUNE_INCOME.PORT_CD = POSITIONS.PORT_CD
AND JUNE_INCOME.BOOK_CD_NME = POSITIONS.BOOK_CD_NME
AND JUNE_INCOME.POSITN_NUM = POSITIONS.POSITN_NUM
JOIN OWNERSHIP OW
ON PA.AS_OF_DATE=OW.AS_OF_DATE
AND PA.PORT_CD=OW.PORT_CD
AND PA.DEAL_OR_SCHEDULE=OW.DEAL_OR_SCHEDULE
AND PA.DEAL_SCHED_NO=OW.DEAL_SCHED_NO
JOIN OWNERS
ON OWNERSHIP.OWNER_PORT_CD = OWNERS.OWNER_PORT_CD
Please make sure you add input and expected output in your question.
Additionally, make use of aliases to avoid writing full names everytime.

Self Join with on different tables

I wrote the following query:
SELECT R1.RELATIONSHIP_ID, R1.SUPPLIER_ACCOUNT_ID, R2.BUYER_ACCOUNT_ID
FROM RELATIONSHIP R1 JOIN RELATIONSHIP R2
ON (R1.RELATIONSHIP_ID = R2.RELATIONSHIP_ID)
ORDER BY SUPPLIER_ACCOUNT_ID;
For the tables:
1. RELATIONSHIP: Columns: RELATIONSHIP_ID, SUPPLIER_ACCOUNT_ID, BUYER_ACCOUNT_ID ...
2. ACCOUNT: ACCOUNT_ID, XX_ACCOUNT_ID ....
and gives the result correctly so far
However, what I want is more complicated. I need to replace the second and third columns with a column called XX_ACOUNT_ID to be shown twice. Each SUPPLIER_ACCOUNT_ID and BUYER_ACCOUNT_ID has a unique XX_ACCOUNT_ID and a unique ACCOUNT_ID. XX_ACCOUNT_ID belongs to the table ACCOUNTS in which there is ACCOUNT_ID (SUUPLIER_ACCOUNT_ID & BUYER_ACCONT_ID are referenced from this column) and XX_ACCOUNT_ID. I'm a bit confused that does it need nested self-join or multiple inner joins? or subqueries to solve this?
If R1.Supplier_Account_ID and R2.Buyer_Account_ID will always exist in the referenced tables, multiple inner joins should work. Try something like this:
SELECT R1.RELATIONSHIP_ID, AcctSupp.XX_ACOUNT_ID, AcctBuyer.XX_ACOUNT_ID
FROM RELATIONSHIP R1
JOIN RELATIONSHIP R2 ON (R1.RELATIONSHIP_ID = R2.RELATIONSHIP_ID)
JOIN Accounts AcctSupp ON R1.SUPPLIER_ACCOUNT_ID = AcctSupp.Account_ID
JOIN Accounts AcctBuyer ON R2.BUYER_ACCOUNT_ID = AcctBuyer.Account_ID
ORDER BY SUPPLIER_ACCOUNT_ID;
If there's any chance the values won't exist in the referenced tables, use left joins instead:
SELECT R1.RELATIONSHIP_ID, AcctSupp.XX_ACOUNT_ID, AcctBuyer.XX_ACOUNT_ID
FROM RELATIONSHIP R1
JOIN RELATIONSHIP R2 ON (R1.RELATIONSHIP_ID = R2.RELATIONSHIP_ID)
LEFT JOIN Accounts AcctSupp ON R1.SUPPLIER_ACCOUNT_ID = AcctSupp.Account_ID
LEFT JOIN Accounts AcctBuyer ON R2.BUYER_ACCOUNT_ID = AcctBuyer.Account_ID
ORDER BY SUPPLIER_ACCOUNT_ID;
Perhaps I misunderstood the question, but I don't see why you need a self join:
SELECT R.Relationship_Id,
Supplier.xx_account_id sup_id,
Buyer.xx._account_id buy_id
FROM Relationship AS R
JOIN Accounts AS Buyer
ON R.Buyer_account_Id = Buyer.Account_Id
JOIN Accounts AS Supplier
ON R.Supplier_account_Id = Supplier.Account_Id

Multiple foreign keys from one table linking to single primary key in second table

I have a database with three tables, a household table, an adults table and a users table. The Household table contains two foreign keys, iAdult1ID and iAdult2ID. The Users table has a iUserID primary key and the Adult table has a corresponding iUserID foreign key. One of the columns in the Users table is strUsername, an e-mail address.
I am trying to write a query that will allow me to search for an e-mail address for either adult that has a relation to the household. So I have two questions, assuming that all the values are not null, how can I do this?
And two, in reality, iAdult2ID can be null, is it still possible to write a query to do this?
Thanks for your help. Let me know if you need any more information.
Yes, you just left join to the same table twice:
select u1.strUsername, u2.strUsername
FROM Household h
LEFT JOIN Adult a1 on a1.ID = h.iAdult1ID
LEFT JOIN Users u1 on u1.ID = a1.iUserID
LEFT JOIN Adult a2 on a2.ID = h.iAdult2ID
LEFT JOIN Users u2 ON u2.ID = a2.iUserID
While the accepted answer is correct I thought it would be helpful to point out that the original problem is a consequence of how the data is modeled.
Ideally you should move the AdultIds out of the HouseHold table and into a new table called HouseholdAdults which contains both the HouseholdId and the iAdultId. Then you can have one or more adults per household.
Heres a screenshot to illustrate what I mean.
Currently you have restricted the relationship between adults and household to at least one and no more than two. What about houses with no adults or three? Also, you can't add a household record before adding an adult record? Where do you store information about an adults relationship to a household? For example, who is the owner, tenant, when they moved in, bought it etc. Basically anything relevant to the relationship.
These are all probably non-issues for you at the moment but still worth some thought I think.
This remodeling then resolves the issues you have with querying the data. With the new table in place to join the household table and the adult table you can easily query the relationship with the following.
SELECT Adult.iAdultId, Household.HouseHoldId, Users.strUserName FROM Adult
INNER JOIN HouseholdAdults ON Adult.iAdultId = HouseholdAdults.iAdultId
INNER JOIN Household ON HouseholdAdults.HouseholdId = Household.HouseHoldId
INNER JOIN Users ON Adult.iUserId = Users.iUserId
Heres some links explaining it further.
Many-to-Many relations
Database normalization

SQL Join 2 tables

I have two tables one named Person, which contains columns ID and Name and the second one, named Relation, which contains two columns, each of which contains an ID of a Person. It's about a relation between customer and serviceman. I'd like to Join these two tables so that I'll have names of people in every relation. Is it possible to write this query with some kind of joining?
EDIT::
I must do something wrong, but it's not working. I had tried a lot of forms of so looking queries, but I had been only getting one column or some errors. It's actually the school task, I have it already done (with different JOIN query). Firstly I had been trying to do this, but I'd failed: It seems to be very common situation, so I don't know why it's too complicated for me..
Here are my tables:
CREATE TABLE Oprava..(Repair) (
KodPodvozku INTEGER PRIMARY KEY REFERENCES Automobil(KodPodvozku),
IDzakaznika..(IDcustomer) INTEGER REFERENCES Osoba(ID),
IDzamestnance..(IDemployee) INTEGER REFERENCES Osoba(ID)
);
CREATE TABLE Osoba..(Person) (
ID INTEGER CONSTRAINT primaryKeyOsoba PRIMARY KEY ,
Jmeno..(Name) VARCHAR(256) NOT NULL,
OP INTEGER UNIQUE NOT NULL
);
It's in Czech, but the words in brackets after ".." are english equivalents.
PS: I am using Oracle SQL.
Assuming your tables are:
persons: (id, name)
relations: (customer_id, serviceman_id)
Using standard SQL:
SELECT p1.name AS customer_name,
p2.name AS serviceman_name
FROM persons p1
JOIN relations ON p1.id=relations.customer_id
JOIN persons p2 ON relations.serviceman_d=p2.id;
Further explanation
The join creates the following table:
p1.id|p1.name|relations.customer_id|relations.serviceman_id|p2.id|p2.name
Where p1.id=relations.customer_id, and p2.id=relations.serviceman_id. The SELECT clause chooses only the names from the JOIN.
Note that if all the ids from relations are also in persons, the result size would be exactly the size of the relations table. You might want to add a foreign key to verify that.
SELECT *
FROM Relation
INNER JOIN Person P1
ON P1.ID = Relation.FirstPersonID
INNER JOIN Person P2
ON P2.ID = Relation.SecondPersonID
SELECT p1.name AS customer, p2.name AS serciveman
FROM person p1, person p2, relation
WHERE p1.id=relation.customerid AND p2.id=relation.servicemanid
Person(ID, Name)
Relation(ID)
You don't mention the other columns that relation contains but this is what you need:
Select name
from Person as p
join Relation as r
on p.ID = r.ID
This is an INNER JOIN as are most of the other answers here. Please don't use this until you understand that if either record doesn't have a relationship in the other table it will be missing from the dataset (i.e. you can lose data)
Its very important to understand the different types of join so I would use this as an opportunity.