SQL Join Table A Column A to Table B Column A or B - sql

I have 2 tables - A Spend Table and a Sales Table
Spend Table Schema:
Spend_ID,
Spend_amount
Sales Table Schema:
Sales_ID_A,
Sales_ID_B,
Sales_amount
I want to do a left join of the spend table to the sales table. The join key from the spend table is the Spend_ID and i want to join when it matches the value in either Sales_ID_A or Sales_ID_B i.e. my match key on the sales table is in 2 columns. So in a way its like applying an 'or' condition to the join on the sales table Sales_ID_A or Sales_ID_B. If a match is found in Sales_ID_A, then no need to check Sales_ID_B. Only check Sales_ID_B if no match is found in Sales_ID_A. How do i achieve this with SQL?
Sample Data Illustration:
See screenshot

The columns called sales_id_a and sales_id_b are actually spend IDs and should better be called spend_id_a and spend_id_b.
You want to join on the first ID, but if that is null, you want to join on the second ID. Use COALESCE for this:
select *
from sales
left join spend on spend.spend_id = coalesce(sales.sales_id_a, sales.sales_id_b)

Related

Join SQL tables, but with additional info from joined table

Here is a basic illustration of the issue
I have two tables I want to join.
One table contains information about a product sale. (product_sales)
The other contains keys for the names of locations. (states_keys)
Both contain the same column 'state_key'.
The states_keys table has an additional column called 'state_names'.
I would like to join the table so that I can view the accurate state name that coordinates to each product sale.
So, I want to join where each table's state_key are = but display the additional column state_names from table states_keys.
SELECT product_sales.*, state_names
FROM product_sales
INNER JOIN states_keys
ON product_sales.state_key = states_keys.state_key
Try with something like this:
Select prod.*, state.state_names
from product_sales prod
inner join states_keys state on state.state_key = prod.state_key

Joins on multiple tables to create a view [duplicate]

This question already has answers here:
SQL JOIN and different types of JOINs
(6 answers)
Closed 5 years ago.
I want to create a view by joining three tables.
The schema is a bit complicated, and so for the sake of simplicity, I will mention only the tables and columns required for the problem.
There is a table sales with two columns:
SaleID(pkey),
Buyer,
Amount.
The second table is purchases with two columns:
PurchaseID(pkey),
Seller,
Amount.
I have a third table stockhistory which keeps track of the flow of materials.
The schema of that table is:
Date,
PurchaseID(fkey to column PurchaseID, Purchases Table),
SalesID(fkey to column SalesID, Sales Table),
Amount(calculated amount inserted here).
Now, each of the stockhistory records corresponds to either a record of Purchases table or Sales table, but not both or none.
I have a constraint for that purpose:
([salesid] IS NULL AND [purchaseid] IS NOT NULL OR [salesid] IS NOT NULL AND
[purchaseid] IS NULL)
Now, in the view StockReport, I am trying to pull all records from stockhistory table, and want to display the name of buyer or seller as is the case.
I have tried to write a SQL of the lines of:
SELECT StockHistory.date
, StockHistory.purchaseid
, StockHistory.salesid
, Purchases.seller
, Sales.buyer
WHERE StockHistory.purchaseid = Purchases.purchaseid
OR StockHistory.salesid = Sales.salesid
How can I do the same with LEFT JOIN?
You can use following query
SELECT
SH.date,
SH.purchaseid,
SH.salesid,
P.seller,
S.buyer
FROM stockhistory SH
LEFT JOIN Purchases P on P.PurchaseID=SH.PurchaseID
LEFT JOIN Sales S on S.salesid=SH.salesid

Joining two tables to update results in third table using like

I am trying to join two tables and update the results in the third table.
So table A is the results table and it has the columns customer number and score.
Table B has customer number and ind_code and table C has ind_code and ind_score.
So the output of the query should be such that the ind_code in table B and C should join together based on the first two digits and ind_score should be updated in Table A in the score column. Table A and Table B should be joined on the basis of customer number.
Could anyone please help. I tried multiple queries but nothing seems to work. i am using oracle sql developer
Generally, the JOIN operation mustn't cut field information but if your structure (for me not correct) is that ...
If I understand better:
UPDATE TableA
SET score =
(SELECT MAX(C.ind_score)
FROM TableC C
JOIN TableB B
ON C.ind_code = SUBSTRING(B.ind_code, 1, 2)
WHERE B.customernumber = TableA.customernumber)
I use on subquery MAX aggregate function, because I don't know if your cut of ind_code of TableB can be not unique (i.e. you have ind_code 5555 and 5554)

Select average rating from another datatable

I have 3 data tables.
In the entries data table I have entries with ID (entryId as primary key).
I have another table called EntryUsersRatings in there are multiple entries that have entryId field and a rating value (from 1 to 5).
(ratings are stored multiple times for one entryId).
Columns: ratingId (primary key), entryId, rating (integer value).
In the third data table I have translations of entries in the first table (with entryId, languageId and title - translation).
What I would like to do is select all entries from first data table with their titles (by language ID).
On a top of that I want average rating of each entry (which can be stored multiple times) that is stored in EntryUsersRatings.
I have tried this:
SELECT entries.entryId, EntryTranslations.title, AVG(EntryUsersRatings.rating) AS AverageRating
FROM entries
LEFT OUTER JOIN
EntryTranslations ON entries.entryId = EntryTranslations.entryId AND EntryTranslations.languageId = 1
LEFT OUTER JOIN
EntryUsersRatings ON entries.entryId = EntryUsersRatings.entryId
WHERE entries.isDraft=0
GROUP BY title, entries.entryId
isDraft is just something that means that entries are not stored with all information needed (just incomplete data - irrelevant for our case here).
Any help would be greatly appreciated.
EDIT: my solution gives me null values for rating.
Edit1: this query is working perfectly OK, I was looking into wrong database.
We also came to another solution, which gives us the same result (I hope someone will find this useful):
SELECT entries.entryId, COALESCE(x.EntryUsersRatings, 0) as averageRating
FROM entries
LEFT JOIN(
SELECT rr.entryId, AVG(rating) AS entryRating
FROM EntryUsersRatings rr
GROUP BY rr.entryId) x ON x.entryId = entries.entryId
#CyberHawk: as you are using left outer join with entries, your result will give all records from left table and matching record with your join condition from right table. but for unmatching records it will give you a null value .
check out following link for the deta:
http://msdn.microsoft.com/en-us/library/ms187518(v=sql.105).aspx

Joining 3 tables & inserting in a 4th table in SQL server

I am joining 3 tables - items , sales , & purchase.
And then, inserting the combined data into a 4th table FULL_DETAIL_OF_ITEMS.
ITEMS table has columns : ITEM_CD, ITEM_NM, COM_CD, SALE_RT, PURCH_RT, MRP
SALES table has columns : ITEM_CD, ITEM_NM, SALE_QTY
PURCHASE table has columns : ITEM_CD, ITEM_NM, PURCH_QTY
FULL_DETAIL_OF_ITEMS table has columns :
ITEM_CD, ITEM_NM, COM_CD, SALE_RT, PURCH_RT, MRP, SALE_QTY, PURCH_QTY
The query is:
insert into FULL_DETAIL_OF_ITEMS
SELECT
Items.Item_CD,
Items.Item_NM ,
ITEMS.COM_CD,
ITEMS.SALE_RT,
ITEMS.PURCH_RT,
ITEMS.MRP,
SALES.SALE_QTY,
PURCHASE.PURCH_QTY
FROM items
JOIN sales on ITEMS.ITEM_CD = sales.ITEM_CD
JOIN purchase on items.ITEM_CD = purchase.ITEM_CD
Items table is filled but sales & purchase tables are empty, so on executing the above query nothing happens? Why so?
At least it should insert rest of the columns from the items table into the 4th table.
It finds that in sales table - sale_qty , & in purchase table, purch_qty is empty, so it should fill null in these columns in the final table & fill rest of the columns as they are picked from item table which consists data so it should fill that.
But its not doing so?
According to the definition of JOIN, ITEM_CD in item table is not matching with the ITEM_CD column of the sales & purchase table as it is empty in both, so this is the reason.
But I want that rest of the data is inserted in the 4th table, then is there any way to do this?
You need to change those join statements to left join.
By default, a join is an "inner join", which means that only rows that exist on both sides of the join will be included. A "left join" includes all rows on the "left" side of the join.
Example:
from items
left join sales on ITEMS.ITEM_CD =sales.ITEM_CD
left join purchase on items.ITEM_CD =purchase.ITEM_CD
You can minimize your query using a select into statement which will, by default, creates a new table at run time.
select Items.Item_CD,Items.Item_NM,Items.COM_CD,Items.Mrp,Items.Purchase_RT,Items.Sale_RT,
purchase.Purchase_QTY,Sales.Sale_QTY
into full_details_of_items
from Items
inner join purchase
inner join Sales
on purchase.Item_CD=Sales.Item_CD
on items.Item_CD=purchase.Item_CD