Combine SQL statements as columns, not as rows - sql

First Query:
SELECT OPENING.COMP_CODE, COMPANY.COMP_NAME, OPENING.QUAL_CODE, QUALIFICATION.QUAL_DESCRIPTION
FROM OPENING
LEFT JOIN COMPANY ON OPENING.COMP_CODE = COMPANY.COMP_CODE
LEFT JOIN QUALIFICATION ON OPENING.QUAL_CODE = QUALIFICATION.QUAL_CODE
Second Query:
SELECT EDUCATION.CAND_NUM, CANDIDATE.CAND_LNAME, EDUCATION.QUAL_CODE, QUALIFICATION.QUAL_DESCRIPTION
FROM EDUCATION
LEFT JOIN CANDIDATE ON EDUCATION.CAND_NUM = CANDIDATE.CAND_NUM
LEFT JOIN QUALIFICATION ON EDUCATION.QUAL_CODE = QUALIFICATION.QUAL_CODE
I tried using <Query1> UNION ALL <Query2> but it combines the results as rows. I want to combine the results as columns (side by side)

If you need to bring all the result in one row, UNION ALL / UNION wont work. Use cross apply instead. Such as,
SELECT A.* ,B.*
FROM
(
SELECT
OPENING.COMP_CODE, COMPANY.COMP_NAME, OPENING.QUAL_CODE, QUALIFICATION.QUAL_DESCRIPTION
FROM OPENING
LEFT JOIN COMPANY ON OPENING.COMP_CODE = COMPANY.COMP_CODE
LEFT JOIN QUALIFICATION ON OPENING.QUAL_CODE = QUALIFICATION.QUAL_CODE
) AS A
CROSS APPLY
(
SELECT EDUCATION.CAND_NUM, CANDIDATE.CAND_LNAME, EDUCATION.QUAL_CODE, QUALIFICATION.QUAL_DESCRIPTION
FROM EDUCATION
LEFT JOIN CANDIDATE ON EDUCATION.CAND_NUM = CANDIDATE.CAND_NUM
LEFT JOIN QUALIFICATION ON EDUCATION.QUAL_CODE = QUALIFICATION.QUAL_CODE
) AS B

Related

SQL- basic but still finding it complicated

I am working on SQL query which should return the list of Managers and the staff who reports to them.
Unfortunately there is no separate table for Employee or Staff but a single 'resource' table called ahsresources.
The managers are identified with a relation called 'C0'.
Even after trying various Joins, I am unable to extract the list. The idea is that a manager will run the report to see his reportees, as well as those staff who report to his own reportees
Example -
Now, if lets say HDY is running the query, then its should return him the below result
Below is the query I have created, but for the matter of understanding the issue, you can use the above example.
select a.description as manager1,a.rel_value as MGID,a.resource_id as Reportee1_MGR2,r.name,a.date_to as date, r.date_to,a1.resource_id as MG3ID,r1.name as Rep3Name,
a2.resource_id as MG4ID,r2.name as Rep4Name
from ahsrelvalue a
LEFT OUTER JOIN ahsresources r
ON r.resource_id = a.resource_id and r.client = a.client and a.date_to='12/31/2099'
LEFT OUTER JOIN ahsrelvalue a1
ON a1.rel_Value = a.resource_id and a1.client = a.client and a1.date_to = '12/31/2099'
LEFT OUTER JOIN ahsrelvalue a2
ON a2.rel_Value = a1.resource_id and a2.client = a1.client and a2.date_to = '12/31/2099'
LEFT OUTER JOIN ahsresources r1
ON r1.resource_id = a1.resource_id and r1.client = a1.client and a1.date_to='12/31/2099'
LEFT OUTER JOIN ahsresources r2
ON r2.resource_id = a2.resource_id and r2.client = a2.client and a2.date_to='12/31/2099'
where a.rel_Value = '$?resid' and a.rel_attr_id='C0' and r.date_to = '12/31/2099' and r1.date_to ='12/31/2099'
and r.status !='C' and r1.status!='C' and r2.status!='C'
In SQL Server, you can use a recursive query to traverse this hierarchical dataset:
with cte as (
select t.* from mytable where managerID = 6
union all
select t.*
from cte c
inner join mytable t on t.managerID = c.staffID
)
select * from cte

SQL Selecting rows with not the same condition for all

I have to create SQL query that select persons datas. Every person has several grades and I have to select first by time for everyone. I don't know how do it because conditional is different for every person. Below is my current code which doesn't works.
SELECT s.sol_last_name,
g.grade_name,
MIN(sg.sol_grade_date_from)
FROM [dbo].[dim_s####] AS s
LEFT JOIN [dbo].[fact_s####_grade] AS sg ON s.sol_key = sg.sol_grade_sollers_key
LEFT JOIN [dbo].[dim_grade] AS g ON g.grade_key = sg.sol_grade_grade_key
GROUP BY s.sol_last_name,
g.grade_name
HAVING MIN(sg.sol_grade_date_from) = sg.sol_grade_date_from
You can put the earliest date in a subquery, and then inner join there:
SELECT s.sol_last_name,
g.grade_name,
sg.sol_grade_date_from
FROM [dbo].[dim_s####] AS s
INNER JOIN (
select sol_grade_grade_key
,min(sol_grade_date_from) as sol_grade_date_
from from [dbo].[dim_grade]
GROUP BY sol_grade_grade_key) AS g
ON g.grade_key = sg.sol_grade_grade_key
LEFT JOIN [dbo].[fact_s####_grade] AS sg
ON s.sol_key = sg.sol_grade_sollers_key
Use a Common Table Expression (cte) to save some typing. Then do a NOT EXISTS to return a row only if same sol_last_name has no older grade.
WITH CTE (sol_last_name, grade_name, grade_date_from) AS
(
SELECT s.sol_last_name,
g.grade_name,
sg.sol_grade_date_from
FROM [dbo].[dim_s####] AS s
LEFT JOIN [dbo].[fact_s####_grade] AS sg ON s.sol_key = sg.sol_grade_sollers_key
LEFT JOIN [dbo].[dim_grade] AS g ON g.grade_key = sg.sol_grade_grade_key
)
select sol_last_name, grade_name, grade_date_from
from cte as t1
where not exists (select 1 from cte t2
where t2.sol_last_name = t1.sol_last_name
and t2.grade_date_from < t2.grade_date_from)

Nested SQL - Distinct Load Left Join in one statement

I wanted to left join two queries:
First:
SELECT TIG_TOL.sName AS Maschine,
TIG_TOL.lTolRef,
Max(TIG_JOB.tActBegin) AS MaxvontActBegin
FROM TIG_JOB LEFT JOIN TIG_TOL ON TIG_JOB.lMacRef = TIG_TOL.lTolRef
WHERE (((TIG_JOB.sState)="Run" Or (TIG_JOB.sState)="Ready"))
GROUP BY TIG_TOL.sName, TIG_TOL.lTolRef;
Second:
SELECT TIG_JOB.sName AS Auftrag,
TIG_JOB.lJobRef,
TIG_TOL.sName AS Artikel,
TIG_TOL.sDescript AS Artikel_Bezeichnung
FROM (TIG_JOB LEFT JOIN TIG_TOL_BOK ON TIG_JOB.lJobRef = TIG_TOL_BOK.lJobRef)
LEFT JOIN TIG_TOL ON (TIG_TOL_BOK.lTolRef = TIG_TOL.lTolRef)
AND (TIG_TOL_BOK.lTolTypRef = TIG_TOL.lTolTypRef)
WHERE (((TIG_TOL.lTolTypRef)=10));
Over a left join
on First.MaxvontActBegin = Second.TIG_JOB.tActBegin
AND First.TIG_TOL.lTolRef = Second.TIG_JOB.lMacRef
Is that possible? In Access Im doing it over two queries, where the second is using the first..
I (blindly) added TIG_JOB.tActBegin and TIG_JOB.lMacRef to the 2nd SELECT (hoping they exist) in order to JOIN the two results.
I used SELECT * only because you did not specify the column selection.
SELECT *
FROM
(
SELECT TIG_TOL.sName AS Maschine,
TIG_TOL.lTolRef,
Max(TIG_JOB.tActBegin) AS MaxvontActBegin
FROM TIG_JOB LEFT JOIN TIG_TOL ON TIG_JOB.lMacRef = TIG_TOL.lTolRef
WHERE (((TIG_JOB.sState)="Run" Or (TIG_JOB.sState)="Ready"))
GROUP BY TIG_TOL.sName, TIG_TOL.lTolRef
) AS FirstTable
LEFT JOIN
(
SELECT TIG_JOB.sName AS Auftrag,
TIG_JOB.lJobRef,
TIG_TOL.sName AS Artikel,
TIG_TOL.sDescript AS Artikel_Bezeichnung,
TIG_JOB.tActBegin,
TIG_JOB.lMacRef
FROM (TIG_JOB LEFT JOIN TIG_TOL_BOK ON TIG_JOB.lJobRef = TIG_TOL_BOK.lJobRef)
LEFT JOIN TIG_TOL ON (TIG_TOL_BOK.lTolRef = TIG_TOL.lTolRef)
AND (TIG_TOL_BOK.lTolTypRef = TIG_TOL.lTolTypRef)
WHERE (((TIG_TOL.lTolTypRef)=10))
) AS SecondTable
ON FirstTable.MaxvontActBegin = SecondTable.tActBegin
AND FirstTable.lTolRef = SecondTable.lMacRef`

Recursive query with outer joins?

I'm attempting the following query,
DECLARE #EntityType varchar(25)
SET #EntityType = 'Accessory';
WITH Entities (
E_ID, E_Type,
P_ID, P_Name, P_DataType, P_Required, P_OnlyOne,
PV_ID, PV_Value, PV_EntityID, PV_ValueEntityID,
PV_UnitValueID, PV_UnitID, PV_UnitName, PV_UnitDesc, PV_MeasureID, PV_MeasureName, PV_UnitValue,
PV_SelectionID, PV_DropDownID, PV_DropDownName, PV_DropDownOptionID, PV_DropDownOptionName, PV_DropDownOptionDesc,
RecursiveLevel
)
AS
(
-- Original Query
SELECT dbo.Entity.ID AS E_ID, dbo.EntityType.Name AS E_Type,
dbo.Property.ID AS P_ID, dbo.Property.Name AS P_Name, DataType.Name AS P_DataType, Required AS P_Required, OnlyOne AS P_OnlyOne,
dbo.PropertyValue.ID AS PV_ID, dbo.PropertyValue.Value AS PV_Value, dbo.PropertyValue.EntityID AS PV_EntityID, dbo.PropertyValue.ValueEntityID AS PV_ValueEntityID,
dbo.UnitValue.ID AS PV_UnitValueID, dbo.UnitOfMeasure.ID AS PV_UnitID, dbo.UnitOfMeasure.Name AS PV_UnitName, dbo.UnitOfMeasure.Description AS PV_UnitDesc, dbo.Measure.ID AS PV_MeasureID, dbo.Measure.Name AS PV_MeasureName, dbo.UnitValue.UnitValue AS PV_UnitValue,
dbo.DropDownSelection.ID AS PV_SelectionID, dbo.DropDown.ID AS PV_DropDownID, dbo.DropDown.Name AS PV_DropDownName, dbo.DropDownOption.ID AS PV_DropDownOptionID, dbo.DropDownOption.Name AS PV_DropDownOptionName, dbo.DropDownOption.Description AS PV_DropDownOptionDesc,
0 AS RecursiveLevel
FROM dbo.Entity
INNER JOIN dbo.EntityType ON dbo.EntityType.ID = dbo.Entity.TypeID
INNER JOIN dbo.Property ON dbo.Property.EntityTypeID = dbo.Entity.TypeID
INNER JOIN dbo.PropertyValue ON dbo.Property.ID = dbo.PropertyValue.PropertyID AND dbo.PropertyValue.EntityID = dbo.Entity.ID
INNER JOIN dbo.DataType ON dbo.DataType.ID = dbo.Property.DataTypeID
LEFT JOIN dbo.UnitValue ON dbo.UnitValue.ID = dbo.PropertyValue.UnitValueID
LEFT JOIN dbo.UnitOfMeasure ON dbo.UnitOfMeasure.ID = dbo.UnitValue.UnitOfMeasureID
LEFT JOIN dbo.Measure ON dbo.Measure.ID = dbo.UnitOfMeasure.MeasureID
LEFT JOIN dbo.DropDownSelection ON dbo.DropDownSelection.ID = dbo.PropertyValue.DropDownSelectedID
LEFT JOIN dbo.DropDownOption ON dbo.DropDownOption.ID = dbo.DropDownSelection.SelectedOptionID
LEFT JOIN dbo.DropDown ON dbo.DropDown.ID = dbo.DropDownSelection.DropDownID
WHERE dbo.EntityType.Name = #EntityType
UNION ALL
-- Recursive Query?
SELECT E2.E_ID AS E_ID, dbo.EntityType.Name AS E_Type,
dbo.Property.ID AS P_ID, dbo.Property.Name AS P_Name, DataType.Name AS P_DataType, Required AS P_Required, OnlyOne AS P_OnlyOne,
dbo.PropertyValue.ID AS PV_ID, dbo.PropertyValue.Value AS PV_Value, dbo.PropertyValue.EntityID AS PV_EntityID, dbo.PropertyValue.ValueEntityID AS PV_ValueEntityID,
dbo.UnitValue.ID AS PV_UnitValueID, dbo.UnitOfMeasure.ID AS PV_UnitID, dbo.UnitOfMeasure.Name AS PV_UnitName, dbo.UnitOfMeasure.Description AS PV_UnitDesc, dbo.Measure.ID AS PV_MeasureID, dbo.Measure.Name AS PV_MeasureName, dbo.UnitValue.UnitValue AS PV_UnitValue,
dbo.DropDownSelection.ID AS PV_SelectionID, dbo.DropDown.ID AS PV_DropDownID, dbo.DropDown.Name AS PV_DropDownName, dbo.DropDownOption.ID AS PV_DropDownOptionID, dbo.DropDownOption.Name AS PV_DropDownOptionName, dbo.DropDownOption.Description AS PV_DropDownOptionDesc,
(RecursiveLevel + 1)
FROM Entities AS E2
INNER JOIN dbo.Entity ON dbo.Entity.ID = E2.PV_ValueEntityID
INNER JOIN dbo.EntityType ON dbo.EntityType.ID = dbo.Entity.TypeID
INNER JOIN dbo.Property ON dbo.Property.EntityTypeID = dbo.Entity.TypeID
INNER JOIN dbo.PropertyValue ON dbo.Property.ID = dbo.PropertyValue.PropertyID AND dbo.PropertyValue.EntityID = E2.E_ID
INNER JOIN dbo.DataType ON dbo.DataType.ID = dbo.Property.DataTypeID
INNER JOIN dbo.UnitValue ON dbo.UnitValue.ID = dbo.PropertyValue.UnitValueID
INNER JOIN dbo.UnitOfMeasure ON dbo.UnitOfMeasure.ID = dbo.UnitValue.UnitOfMeasureID
INNER JOIN dbo.Measure ON dbo.Measure.ID = dbo.UnitOfMeasure.MeasureID
INNER JOIN dbo.DropDownSelection ON dbo.DropDownSelection.ID = dbo.PropertyValue.DropDownSelectedID
INNER JOIN dbo.DropDownOption ON dbo.DropDownOption.ID = dbo.DropDownSelection.SelectedOptionID
INNER JOIN dbo.DropDown ON dbo.DropDown.ID = dbo.DropDownSelection.DropDownID
)
SELECT E_ID, E_Type,
P_ID, P_Name, P_DataType, P_Required, P_OnlyOne,
PV_ID, PV_Value, PV_EntityID, PV_ValueEntityID,
PV_UnitValueID, PV_UnitID, PV_UnitName, PV_UnitDesc, PV_MeasureID, PV_MeasureName, PV_UnitValue,
PV_SelectionID, PV_DropDownID, PV_DropDownName, PV_DropDownOptionID, PV_DropDownOptionName, PV_DropDownOptionDesc,
RecursiveLevel
FROM Entities
INNER JOIN [dbo].[Entity] AS dE
ON dE.ID = PV_EntityID
The problem is the second query, the "recursive one" is getting the data I expect since I can't do the LEFT JOINs like in the first query. (At least to my understanding).
If I remove the fetching of the data that requires the LEFT (Outer) JOINs then the recursion works perfectly. My problem is I need both. Is there a way I can accomplish this?
Per http://msdn.microsoft.com/en-us/library/ms175972.aspx you can not have a left/right/outer join in a recursive CTE.
For a recursive CTE you can't use a subquery either so I sugest following this example.
They use two CTE's. The first is not recursive and does the left join to get the data it needs. The second CTE is recursive and inner joins on the first CTE. Since CTE1 is not recursive it can left join and supply default values for the missing rows and is guarenteed to work in the inner join.
However, you can also duplicate a left join with a union and subselect though it isn't really useful normally but it is interesting.
In that case, you would keep your first statement how it is. It will match all rows that join successfully.
Then UNION that query with another query that removes the join, but has a
NOT EXISTS(SELECT 1 FROM MISSING_ROWS_TABLE WHERE MAIN_TABLE.JOIN_CONDITION = MISSING_ROWS_TABLE.JOIN_CONDITION)
This gets all the rows that failed the previous join condition in query 1. You can replace the colmuns you would get from MISSING_ROWS_TABLE with NULL. I had to do this once using a coding framework that didn't support outer joins. Since recursive CTE's don't allow subqueries you have to use the first solution.

How to write subquery inside the OUTER JOIN Statement

I want to join two table CUSTMR and DEPRMNT.
My needed is: LEFT OUTER JOIN OF two or more Tables with subquery inside the LEFT OUTER JOIN as shown below:
Table: CUSTMR , DEPRMNT
Query as:
SELECT
cs.CUSID
,dp.DEPID
FROM
CUSTMR cs
LEFT OUTER JOIN (
SELECT
dp.DEPID
,dp.DEPNAME
FROM
DEPRMNT dp
WHERE
dp.DEPADDRESS = 'TOKYO'
)
ON (
dp.DEPID = cs.CUSID
AND cs.CUSTNAME = dp.DEPNAME
)
WHERE
cs.CUSID != ''
Here the subquery is:
SELECT
dp.DEPID, dp.DEPNAME
FROM
DEPRMNT dp
WHERE
dp.DEPADDRESS = 'TOKYO'
Is it possible to write such subquery inside LEFT OUTER JOIN?
I am getting an error when running this query on my DB2 database.
You need the "correlation id" (the "AS SS" thingy) on the sub-select to reference the fields in the "ON" condition. The id's assigned inside the sub select are not usable in the join.
SELECT
cs.CUSID
,dp.DEPID
FROM
CUSTMR cs
LEFT OUTER JOIN (
SELECT
DEPID
,DEPNAME
FROM
DEPRMNT
WHERE
dp.DEPADDRESS = 'TOKYO'
) ss
ON (
ss.DEPID = cs.CUSID
AND ss.DEPNAME = cs.CUSTNAME
)
WHERE
cs.CUSID != ''
I think you don't have to use sub query in this scenario.You can directly left outer join the DEPRMNT table .
While using Left Outer Join ,don't use columns in the RHS table of the join in the where condition, you ll get wrong output