Oracle SQL - Select from two tables - sql

I have two tables which are exactly the same layout, but have different data (one is current, one is history).
How do I pull information from both tables?
PSUDO SQL:
SELECT
T.TRANS_QUAN,
P.PONO, D.ID
FROM
TRANSLOG T, (select * from PO, PO_HIST) P, (SELECT * FROM PO_DETAIL, PO_DETAIL_HIST) D
WHERE
D.PO_ID = P.ID
AND T.SOURCE_ID = D.ID
When I try to actually run that I get "column ambiguously defined"

You can UNION clause.
Try:
SELECT
T.TRANS_QUAN,
P.PONO, D.ID
FROM
TRANSLOG T,
(
SELECT * FROM PO
UNION
SELECT * FROM PO_HIST
) P,
(
SELECT * FROM PO_DETAIL
UNION
SELECT * FROM PO_DETAIL_HIST
) D
WHERE
D.PO_ID = P.ID
AND T.SOURCE_ID = D.ID

(select * from PO, PO_HIST) P
This subquery might make a cross join of tables that share a common column name.
Maybe you want:
Select t.trang_quan
, p.pono
, d.id
from translog t
inner join po_detail d
on d.id = t.source_id
cross join po_detail_hist
inner join po p
on p.id = d.po_id
cross join po_hist p2
Are you sure you want cross joins?

Related

SQL many to many select people with multiple vacancies

I am working with sql server through SSMS right now. How can i choose all people with multiple(>2)vacancies?
I am trying something like that, but i dont understand how to make part with "more than 2 vacancies"?
SELECT dbo.applicants.FirstName, dbo.vacancy.Name
FROM dbo.applicants INNER JOIN
dbo.VacancyApplicant ON dbo.applicants.id = dbo.VacancyApplicant.ApplicantId INNER JOIN
dbo.vacancy ON dbo.VacancyApplicant.VacancyId = dbo.vacancy.id WHERE dbo.vacancy.Name='third vacancy'
SELECT dbo.applicants.FirstName, dbo.vacancy.Name
FROM dbo.applicants A INNER JOIN
dbo.VacancyApplicant V ON A.id = V.ApplicantId
WHERE EXIST(
SELECT 1
FROM dbo.applicants INNER JOIN
dbo.VacancyApplicant ON dbo.applicants.id =
dbo.VacancyApplicant.ApplicantId INNER JOIN
dbo.vacancy ON dbo.VacancyApplicant.VacancyId = dbo.vacancy.id
WHERE A.id=dbo.applicants.id
GROUP BY dbo.applicants.id,dbo.vacancy.id
HAVING COUNT(1)>2
)
Group By and Having are you basic answer. Below is a simple solution, might not be ideal, but can give you the idea.
I am finding target "applicants" ids in subquery, that uses GROUP BY and HAVING then outer query joins to that to output FirstName and LastName of applicant
SELECT dbo.applicants.FirstName, dbo.applicants.LastName FROM
dbo.applicants a INNER JOIN
(
SELECT dbo.applicants.id
FROM dbo.applicants INNER JOIN
dbo.VacancyApplicant ON dbo.applicants.id = dbo.VacancyApplicant.ApplicantId INNER JOIN
dbo.vacancy ON dbo.VacancyApplicant.VacancyId = dbo.vacancy.id AND dbo.vacancy.Name='third vacancy'
GROUP BY dbo.applications.id
HAVING COUNT(dbo.vacancy.id) > 2
) targetIds ON a.id = targetIds.id
"more than 2 vacancies"?
Your question only mentions vacancies but your query is filtering for a particular name. I assume you really want more than two of that name.
If I understand correctly, you want aggregation:
SELECT a.FirstName, a.Name
FROM dbo.applicants a INNER JOIN
dbo.VacancyApplicant va
ON a.id = va.ApplicantId INNER JOIN
dbo.vacancy v
ON va.VacancyId = v.id
WHERE v.Name = 'third vacancy'
GROUP BY a.FirstName, v.Name
HAVING COUNT(*) > 2;
Note the use of table aliases. They make the query easier to write and to read.
WITH TempCTE AS (
SELECT DISTINCT ap.FirstName
,vc.Name
,COUNT (va.VacancyId) OVER (PARTITION BY ap.id) AS NoOfVacancies
FROM dbo.applicants ap
JOIN dbo.VacancyApplicant va
ON ap.id = va.ApplicantId
JOIN dbo.vacancy vc
ON va.VacancyId = vc.id
)
SELECT FirstName,[Name], NoOfVacancies FROM TempCTE
WHERE NoOfVacancies > 2

SQL select specific rows from subquery and insert into row_to_json

I have a view for which I have created several subqueries, I'm trying to return one of the subqueries as json using -
row_to_json(err.*) as overall_totals
The subquery -
left join
(
SELECT q.id, SUM(q.total) AS total,
jsonb_agg(jsonb_build_object('count', q.total, 'type', q.name)) AS totals
FROM (
SELECT r.id AS id, e.name, COUNT(de.value_id) AS total
FROM table_c de
JOIN tests.error e
ON e.id = de.value_id
JOIN table_a p
ON de.process_id = p.id
Join table_b r on p.root = r.id
GROUP BY e.name, r.id ) q
GROUP BY q.id
) err on err.id = rs.id
This works fine and returns as json, however, I only want to return total and totals of the "err" sub-query and not q.id. I need the q.id in the sub-query so that I can join the query onto the rest of the view but I don't want it to be stored in overall_totals. How can I get around this? Is it possible to select certain values into row_to_json?
If you are fine with returning jsonb instead of json, then you can use the - operator:
to_jsonb(err.*) - 'id' as overall_totals
You can add more subquery, something like this
SELECT row_to_json(err2.*) as overall_totals
FROM
(
SELECT err.total, err.totals
FROM XXX_TABLE RS
left join
(
SELECT q.id, SUM(q.total) AS total, jsonb_agg(jsonb_build_object('count', q.total, 'type', q.name)) AS totals
FROM
(
SELECT r.id AS id, e.name, COUNT(de.value_id) AS total
FROM table_c de
JOIN tests.error e
ON e.id = de.value_id
JOIN table_a p
ON de.process_id = p.id
Join table_b r on p.root = r.id
GROUP BY e.name, r.id
) q
GROUP BY q.id
) err on err.id = rs.id
) err2

Select qry to using 2 databases

I have the below query:
SELECT
--a.DateEntered,
--a.InventoryId,
a.SKU, a.QtyOnHand,
b.Dateentered AS VDateEntered,
b.GoLive, b.DateOnSite, b.CostPrice,
--a.CurrentPrice,
m.name AS Status,
hrf.category, hrf.department, hrf.BrandedOB, hrf.Division,
hrf.Fascia,
(a.QtyOnHand * b.CostPrice) AS Cost_Value,
NULL AS Item_Quantity, NULL AS Item,
NULL AS Season, hrf.Company,
(a.QtyOnHand * b.CurrentPrice) AS Sellilng_Value,
b.merchandisingseason, b.CostPrice AS Costprice_RP,
b.CurrentPrice, b.InventoryID,
-- a.AverageUnitCost,
-- a.AverageUnitCost AS RP_Stk_AverageUnitCost,
-- a.CurrentPrice AS RP_Stk_Current_Price,
-- a.Statusid,
-- a.Quantity_Sign,
(a.QtyOnHand * b.CostPrice) AS Cost_Value_RP,
(a.QtyOnHand * b.AverageUnitCost) AS AWC_Value
-- a.StockReconciliationId,
-- a.AverageUnitCost,
FROM
[dbo].[FC03QTY] a
JOIN
dbo.inventory b ON a.SKU = b.SKU
LEFT JOIN
(------Hierarchy-------
SELECT
ih.InventoryId, hry.category, hry.department,
hry.BrandedOB, hry.Division, hry.Fascia, hry.Company
FROM
(SELECT
ihn.HierarchyNodeId, ihn.InventoryId
FROM bm.InventoryHierarchyNode IHN
GROUP BY ihn.HierarchyNodeId, ihn.InventoryId) IH
JOIN
(SELECT
g.categoryid, g.category, h.department, i.BrandedOB,
j.Division, K.Fascia, L.company
FROM
Category g (NOLOCK)
JOIN
Department H ON g.departmentid = h.departmentID
JOIN
BrandedOB I (NOLOCK) ON h.BrandedOBID = i.BrandedOBID
JOIN
Division j (NOLOCK) ON i.divisionid = j.divisionid
JOIN
Fascia k (NOLOCK) ON j.fasciaid = k.fasciaID
JOIN
company l (NOLOCK) ON k.companyid = l.companyid
GROUP BY
g.categoryid, g.category, h.department,
i.BrandedOB, j.Division, K.Fascia, L.company) HRY ON ih.HierarchyNodeId = hry.CategoryId
GROUP BY
ih.InventoryId, hry.category, hry.department,
hry.BrandedOB, hry.Division, hry.Fascia, hry.Company) HRF ON b.inventoryid = hrf.inventoryid
JOIN
inventorystatus m (NOLOCK) ON b.statusid = m.statusid
It is using 2 tables -
[dbo].[FC03QTY] a
and
dbo.inventory b
that are joined at the SKU level.
[dbo].[FC03QTY] is on the scratch database and dbo.inventory is on the reports database.
How can I get my query to use these tables if they are on 2 different db?
Any advice greatly received.
In sql server the syntaxis for tables is [database name].[schema name].[table name]
So you need something like this:
SELECT A.*, B.*
FROM
Database1.dbo.Table1 as A,
Database2.dbo.Table2 as B

JOIN / LEFT JOIN conflict in SQL Server

I have a tricky query. I need to select all recent versions of 2 types of members of administrator groups. Here is the query:
SELECT refGroup.*
FROM tblSystemAdministratorGroups refGroup
JOIN tblGroup refMem ON refGroup.AttributeValue = refMem.ObjectUID
This query will return all the administrator groups. The next step will be getting the members of these groups. Since I have 2 types of memberships (Explicit, Computed), I will have to use a LEFT JOIN to make sure that I am not excluding any rows.
SELECT refGroup.*
FROM tblSystemAdministratorGroups refGroup
-- The JOIN bellow can be excluded but it is here just to clarify the architecture
JOIN tblGroup refMem ON refGroup.AttributeValue = refMem.ObjectUID
LEFT JOIN tblGroup_ComputedMember cm ON refMem.ObjectUID = cm.GroupObjectID
LEFT JOIN tblGroup_ExplicitMember em ON refMem.ObjectUID = em.GroupObjectID
The last piece in the puzzle is to get the latest version of each member. For that I will have to use JOIN to exclude older versions:
JOIN (
SELECT MAX([ID]) MaxId
FROM [OmadaReporting].[dbo].tblGroup_ComputedMember
GROUP BY ObjectID
) MostRecentCM ON MostRecentCM.MaxId = cm.Id
and
JOIN (
SELECT MAX([ID]) MaxId
FROM [OmadaReporting].[dbo].tblGroup_ExplicitMember
GROUP BY ObjectID
) MostRecentEM ON MostRecentEM.MaxId = em.Id
The full query will be:
SELECT refGroup.*
FROM tblSystemAdministratorGroups refGroup
JOIN tblGroup refMem ON refGroup.AttributeValue = refMem.ObjectUID
LEFT JOIN tblGroup_ComputedMember cm ON refMem.ObjectUID = cm.GroupObjectID
JOIN (
SELECT MAX([ID]) MaxId
FROM [OmadaReporting].[dbo].tblGroup_ComputedMember
GROUP BY ObjectID
) MostRecentCM ON MostRecentCM.MaxId = cm.Id
LEFT JOIN tblGroup_ExplicitMember em ON refMem.ObjectUID = em.GroupObjectID
JOIN (
SELECT MAX([ID]) MaxId
FROM [OmadaReporting].[dbo].tblGroup_ExplicitMember
GROUP BY ObjectID
) MostRecentEM ON MostRecentEM.MaxId = em.Id
The issue is clear: The 2 JOIN to exclude old versions are also applied to the select statement and clearly no rows are returned. What would be the best solution to escape such situation and to return the intended values?
SELECT refGroup.*
FROM tblSystemAdministratorGroups refGroup
JOIN tblGroup refMem ON refGroup.AttributeValue = refMem.ObjectUID
LEFT JOIN (
select GroupObjectID, ID, max(ID) over (partition by ObjectID) as maxID
from tblGroup_ComputedMember
) cm ON refMem.ObjectUID = cm.GroupObjectID and cm.ID = cm.maxID
LEFT JOIN (
select GroupObjectID, ID, max(ID) over (partition by ObjectID) as maxID
from tblGroup_ExplicitMember
) em ON refMem.ObjectUID = em.GroupObjectID and em.ID = em.maxID
where cm.ID = cm.MaxID
What about using LEFT join in your last two joins?
LEFT JOIN (
SELECT MAX([ID]) MaxId
FROM [OmadaReporting].[dbo].tblGroup_ComputedMember
GROUP BY ObjectID
) MostRecentCM ON MostRecentCM.MaxId = cm.Id
And then in Where clause filter values as:
WHERE MostRecentCM.MaxId IS NOT NULL
OR
MostRecentEM.MaxId IS NOT NULL

Sum record data into one

I have this query which returns qty in each of my branch. now the branch has two WH_subType as you see in the attached diagram i have attached. I want to sum the 2 subtype and show its available qty. how can i do it.
my select query is like this
SELECT
dbo.WarehouseType.name AS Section,
dbo.WarehouseSubType.name AS WH_Type,
dbo.WarehouseSubType1.name AS WH_SubType,
dbo.Branch.name AS Branch,
(dbo.WarehouseProductQuantity.actualQuantity - dbo.WarehouseProductQuantity.reservedQuantity) AS AvailQty,
dbo.WarehouseProductQuantity.tafsilId AS Tafsil,
dbo.Tafsil.description AS Product_Name
FROM
dbo.WarehouseSubType
INNER JOIN
dbo.WarehouseType
ON
(
dbo.WarehouseSubType.warehouseTypeId = dbo.WarehouseType.id)
INNER JOIN
dbo.WarehouseSubType1
ON
(
dbo.WarehouseSubType.id = dbo.WarehouseSubType1.warehouseSubTypeId)
INNER JOIN
dbo.Warehouse
ON
(
dbo.WarehouseSubType1.id = dbo.Warehouse.warehouseSubType1Id)
INNER JOIN
dbo.Branch
ON
(
dbo.Warehouse.branchId = dbo.Branch.id)
INNER JOIN
dbo.WarehouseProductQuantity
ON
(
dbo.Warehouse.id = dbo.WarehouseProductQuantity.warehouseId)
INNER JOIN
dbo.TafsilLink
ON
(
dbo.WarehouseProductQuantity.tafsilId = dbo.TafsilLink.sourceId)
INNER JOIN
dbo.Tafsil
ON
(
dbo.TafsilLink.targetId = dbo.Tafsil.id)
INNER JOIN
dbo.FinishProduct
ON
(
dbo.Tafsil.id = dbo.FinishProduct.tafsilId)
INNER JOIN
dbo.Supplier
ON
(
dbo.FinishProduct.supplierId = dbo.Supplier.tafsilId)
WHERE
WarehouseSubType1.warehouseSubTypeId IN (1,4)
group by dbo.WarehouseProductQuantity.tafsilId
Have you tried a group by
SELECT SubType, SUM(qty) AS QtySum
GROUP BY SubType
Every grouped by column should be in your select. Note: for every column you group by it further sub divides the data
Update based on OP comment:
If you want other columns you need to do something like
SELECT s.WH_SubType,s.AvailQty, t.other_cols
from
(SELECT
dbo.WarehouseSubType1.name AS WH_SubType,
sum(dbo.WarehouseProductQuantity.actualQuantity - dbo.WarehouseProductQuantity.reservedQuantity) AS AvailQty
FROM
table
GROUP BY
dbo.WarehouseSubType1.name) s
left join table t on t.dbo.WarehouseSubType1.name = s.WH_SubType;
For reference see this question: How do I use "group by" with three columns of data?
UPDATE 2:
SELECT
dbo.WarehouseType.name AS Section,
dbo.WarehouseSubType.name AS WH_Type,
dbo.WarehouseSubType1.name AS WH_SubType,
dbo.Branch.name AS Branch,
SumTable.AvailQty,
SumTable.Tafsil,
dbo.Tafsil.description AS Product_Name
FROM
dbo.WarehouseSubType
INNER JOIN
dbo.WarehouseType
ON
(
dbo.WarehouseSubType.warehouseTypeId = dbo.WarehouseType.id)
INNER JOIN
dbo.WarehouseSubType1
ON
(
dbo.WarehouseSubType.id = dbo.WarehouseSubType1.warehouseSubTypeId)
INNER JOIN
dbo.Warehouse
ON
(
dbo.WarehouseSubType1.id = dbo.Warehouse.warehouseSubType1Id)
INNER JOIN
dbo.Branch
ON
(
dbo.Warehouse.branchId = dbo.Branch.id)
INNER JOIN
dbo.WarehouseProductQuantity
ON
(
dbo.Warehouse.id = dbo.WarehouseProductQuantity.warehouseId)
INNER JOIN
dbo.TafsilLink
ON
(
dbo.WarehouseProductQuantity.tafsilId = dbo.TafsilLink.sourceId)
INNER JOIN
dbo.Tafsil
ON
(
dbo.TafsilLink.targetId = dbo.Tafsil.id)
INNER JOIN
dbo.FinishProduct
ON
(
dbo.Tafsil.id = dbo.FinishProduct.tafsilId)
LEFT JOIN (SELECT
sum(dbo.WarehouseProductQuantity.actualQuantity - dbo.WarehouseProductQuantity.reservedQuantity) AS AvailQty,
dbo.WarehouseProductQuantity.tafsilId AS Tafsil
FROM
dbo.WarehouseProductQuantity
group by dbo.WarehouseProductQuantity.tafsilId) SumTable on dbo.Tafsil.id = SumTable.Tafsil
WHERE
WarehouseSubType1.warehouseSubTypeId IN (1,4)
You need to do something like
SELECT SUM(AvailQty), ... FROM ... WHERE ... GROUP BY WH_SubType
http://www.w3schools.com/sql/sql_func_sum.asp
http://www.w3schools.com/sql/sql_groupby.asp