Get part of the result into columns instead of lines - sql

I have a query about internal and external trainings. Every training has 1 or more speakers. What I want is to have a column for every speaker.
I was checking on aggregate functions, but I couldn't find the one solving my problem.
select e.sid
, e.access_kz EXTERN1
, z.zuname VERTRETERPERSONAL1
from MDEV e
join MDEVCAL ec on (ec.klient_id = e.klient_id and ec.EV_sid = e.sid)
left outer join MDEVCALS ecs on (ecs.klient_id = e.klient_id and ecs.ev_sid = e.sid and ecs.evcal_sid = ec.sid)
left outer join MDZHD z on (z.klient_id = e.klient_id and z.sid = ecs.MDZHD_SID)
I use left outer joins because a training doesn't have to have a speaker but can have X different speakers
What I want to have is something like this:
SID | Extern1 | VERTRETERPERSONAL1 | VERTRETERPERSONAL2 | VERTRETERPERSONAL3 ...

I think the Following query will resolve your problem but with the static list of trainers.
SELECT
*
FROM
(
SELECT
E.SID,
E.ACCESS_KZ EXTERN1,
Z.ZUNAME VERTRETERPERSONAL
FROM
MDEV E
JOIN MDEVCAL EC ON ( EC.KLIENT_ID = E.KLIENT_ID
AND EC.EV_SID = E.SID )
LEFT OUTER JOIN MDEVCALS ECS ON ( ECS.KLIENT_ID = E.KLIENT_ID
AND ECS.EV_SID = E.SID
AND ECS.EVCAL_SID = EC.SID )
LEFT OUTER JOIN MDZHD Z ON ( Z.KLIENT_ID = E.KLIENT_ID
AND Z.SID = ECS.MDZHD_SID )
) PIVOT (
MAX ( VERTRETERPERSONAL )
FOR VERTRETERPERSONAL
IN ( '<VERTRETERPERSONAL_NAME1>' AS VERTRETERPERSONAL1, '<VERTRETERPERSONAL_NAME2>' AS VERTRETERPERSONAL2, .... )
);
Cheers!!

Related

I want to output table based on what the user input

User required to input an APP_ID but optional to put MILESTONE_ID and TASK_ID. If MILESTONE_ID only the input, it should be the milestone only not include the task.
Ex. APP_ID: 1 MILESTONE_ID:341 TASK_ID: (blank) = output should be app_id and milestone only.
When APP_ID: 1 MILESTONE_ID: (blank) TASK_ID: 441 = output should be app_id and task only.
Lastly when user input a APP_ID: 1, MILESTONE_ID:341, TASK_ID: 441 = output should be app_id, task and milestone.
My current query is below:
SELECT APPLICATION, MILESTONE_NAME, TASK_NAME, FIELD_NAME, FIELD_ALIAS
FROM TBL_APPLICATIONS A
INNER JOIN TBL_WORKFLOWS B ON B.APPLICATION_FK = A.APPLICATION_PK
INNER JOIN TBL_WORKFLOW_DEFINITION C ON C.WORKFLOW_FK = B.WORKFLOW_PK
INNER JOIN TBL_MILESTONE D ON D.MILESTONE_PK = C.START_MILESTONE_FK OR D.MILESTONE_PK = C.END_MILESTONE_FK
INNER JOIN TBL_TASK_FOR_MILESTONE E ON E.MILESTONE_FK = D.MILESTONE_PK
INNER JOIN TBL_TASK F ON F.TASK_PK = E.TASK_FK strong text
INNER JOIN TBL_REQ_FOR_TASK G ON G.TASK_FK = F.TASK_PK
INNER JOIN TBL_TASK_REQUIREMENTS H ON H.TASK_REQUIREMENT_PK = G.TASK_REQUIREMENT_FK
WHERE APPLICATION_PK = :APPLICATION_ID
OR MILESTONE_PK = :MILESTONE_ID
OR TASK_PK = :TASK_ID
Output looks like this.
Your requirements are slightly unclear. If you want to change the projection of the query or even remove the tables from the FROM clause, that cannot be done in pure SQL. Dynamically assembling queries requires PL/SQL or some other client language.
But if your requirement is simply to conditionally suppress the column value whether a parameter is populated, that can be done by testing each parameter, like this:
SELECT APPLICATION
, case when :MILESTONE_ID is not null then MILESTONE_NAME end as MILESTONE_NAME
, case when :TASK_ID is not null then TASK_NAME end as TASK_NAME
, FIELD_NAME
, FIELD_ALIAS
FROM TBL_APPLICATIONS A
INNER JOIN TBL_WORKFLOWS B ON B.APPLICATION_FK = A.APPLICATION_PK
INNER JOIN TBL_WORKFLOW_DEFINITION C ON C.WORKFLOW_FK = B.WORKFLOW_PK
INNER JOIN TBL_MILESTONE D ON D.MILESTONE_PK = C.START_MILESTONE_FK OR D.MILESTONE_PK = C.END_MILESTONE_FK
INNER JOIN TBL_TASK_FOR_MILESTONE E ON E.MILESTONE_FK = D.MILESTONE_PK
INNER JOIN TBL_TASK F ON F.TASK_PK = E.TASK_FK strong text
INNER JOIN TBL_REQ_FOR_TASK G ON G.TASK_FK = F.TASK_PK
INNER JOIN TBL_TASK_REQUIREMENTS H ON H.TASK_REQUIREMENT_PK = G.TASK_REQUIREMENT_FK
WHERE APPLICATION_PK = :APPLICATION_ID
and ( :MILESTONE_ID is not null or :TASK_ID is not null )
and ( :MILESTONE_ID is null or MILESTONE_PK = :MILESTONE_ID )
and ( :TASK_ID is null or TASK_PK = : )
Note that I have corrected the WHERE clause to include conditions that only filter on MILESTONE_ID or TASK_ID when they are populated.

Optimize the SQL Statement with MAX() and VALUES()

In the following case the target is to return the max value rating of a share:
SELECT DISTINCT sd.ShareId
, CASE
WHEN sd.GV01 IS NOT NULL OR sd.GV02 IS NOT NULL OR sd.GV03 IS NOT NULL THEN (
SELECT MAX(val)
FROM (VALUES (rmatMG.RankingId), (rmatSG.RankingId), (rmatFG.RankingId)) AS value(val)
WHERE val IS NOT NULL
)
END AS minRating
, sd.TradeValue
FROM dbo.MasterData sd
LEFT JOIN dbo.CfgRatingMatching rmMG ON sd.GV01 = rmMG.RatingIdOne
LEFT JOIN dbo.CfgRatingmatrix rmatMG ON rmMG.RatingIdCollMatrix = rmatMG.RankingId
LEFT JOIN dbo.CfgRatingMatching rmSG ON sd.GV02 = rmSG.RatingIdTwo
LEFT JOIN dbo.CfgRatingmatrix rmatSG ON rmSG.RatingIdCollMatrix = rmatSG.RankingId
LEFT JOIN dbo.CfgRatingMatching rmFG ON sd.GV03 = rmFG.RatingIdThree
LEFT JOIN dbo.CfgRatingmatrix rmatFG ON rmFG.RatingIdCollMatrix = rmatFG.RankingId
Do anyone have an idea how to optimize the code? I have a lot of data and the return of the list takes almost more than a minute. It takes too long.

Alias to a join query

( SELECT Vraboteni.v, Ulogi.p, Zarabotuva.honorar
FROM Vraboteni, Ulogi, Zarabotuva
WHERE Vraboteni.v = Ulogi.v
AND ima_uloga='sporedna'
AND Ulogi.p = Zarabotuva.p
) as F
JOIN
( SELECT Vraboteni.v, Ulogi.p, Zarabotuva.honorar
FROM Vraboteni, Ulogi, Zarabotuva
WHERE Vraboteni.v = Ulogi.v
AND ima_uloga='glavna'
AND Ulogi.p = Zarabotuva.p
) as S
ON (F.honorar > S.honorar)
Can anyone tell me what is wrong with the syntax that I am using above? I'm having the same issue over multiple queries and I'm not sure I quite understand how I am supposed to assign an alias when I use a join (having the same issue when trying to assign alliases to multiple nested joins)
The subselects you join should be considered as a normal table or view, so imagine they are, and your select statement looks like this:
SELECT1 as F
JOIN SELECT2 as S ON (F.honorar > S.honorar)
This statement is missing essential parts, like a SELECT and FROM clause.
So fix it, if you want to join two selects, you should encapsulate them in another select, so you get:
SELECT
S.*,
F.*
FROM
(SELECT ... ) AS F
JOIN (SELECT ...) AS S ON (F.honorar > S.honorar)
Alternatively, you could get rid of the two subselects, use normal joins for all your tables, and end up with a query like this:
SELECT
Vraboteni.v, Ulogi.p, Zarabotuva.honorar
FROM
Vraboteni AS v1
JOIN Ulogi AS u1 ON v1.v = u1.v
JOIN Zarabotuva AS z1 ON u1.p = z1.p
CROSS JOIN Vraboteni AS v2 -- Not sure if you would want/need a condition here
JOIN Ulogi AS u2 ON v2.v = u2.v
JOIN Zarabotuva AS z2 ON u2.p = z2.p
WHERE
v1.ima_uloga = 'sporedna' -- Not sure if this should be v1, u1 or z1
AND v2.ima_uloga = 'glavna'
AND z1.honorar > z2.honorar
this is what you need to do:
SELECT *
FROM
(SELECT Vraboteni.v
, Ulogi.p
, Zarabotuva.honorar
FROM Vraboteni
, Ulogi
, Zarabotuva
WHERE Vraboteni.v = Ulogi.v
AND ima_uloga = 'sporedna'
AND Ulogi.p = Zarabotuva.p) AS F
JOIN
(SELECT Vraboteni.v
, Ulogi.p
, Zarabotuva.honorar
FROM Vraboteni
, Ulogi
, Zarabotuva
WHERE Vraboteni.v = Ulogi.v
AND ima_uloga = 'glavna'
AND Ulogi.p = Zarabotuva.p) AS S ON F.honorar > S.honorar;

Sql query with 4 tables

I have 4 tables: Fonctionnaire, Echelon, PromotionEchelon, Mise.
Fonctionnaire: CodeFonctionnaire(PK), NomFonctionnaire, PrenomFonctionnaire
Echelon : NumEchelon(PK), CodeEchelon, Indice
PromotionEchelon:CodeFonctionnaire(FK),NumEchelon(FK),DateArrete
Mise:CodeMise(PK),Nature,NumArrete,DateArrete,DureeMise,CodeFonctionnaire(FK)
I want to select the list of all 'Fonctionnaire' and their 'DateArrete' from
'PromotionEchelon' and their 'CodeEchelon, Indice' from 'Echelon' and if
exist their 'Nature,NumArrete,DateArrete,DureeMise' from 'Mise'.
I used this query:
SELECT
Fonctionnaire.CodeFonctionnaire,
Fonctionnaire.NomFonctionnaire,
Fonctionnaire.PrenomFonctionnaire,
Echelon.CodeEchelon, Echelon.Indice,
PromotionEchelon.DateArrete,
Mise.Nature, Mise.NumArrete, Mise.DateArrete, Mise.DureeMise
FROM
Fonctionnaire, PromotionEchelon, Echelon, Mise
WHERE
Fonctionnaire.CodeFonctionnaire = PromotionEchelon.CodeFonctionnaire
AND PromotionEchelon.NumEchelon = Echelon.NumEchelon
AND Fonctionnaire.CodeFonctionnaire = Mise.CodeFonctionnaire
But it returns 0 records, i tried inner and outer join and i get errors.
So where is the error in my query?
You do not address the JOIN chain properly
Start with the following and see what you get
SELECT
Fonctionnaire.CodeFonctionnaire
, Fonctionnaire.NomFonctionnaire
, Fonctionnaire.PrenomFonctionnaire
, Echelon.CodeEchelon, Echelon.Indice
, PromotionEchelon.DateArrete
,Mise.Nature, Mise.NumArrete, Mise.DateArrete, Mise.DureeMise
FROM
Fonctionnaire f
LEFT JOIN PromotionEchelon p
ON p.CodeFonctionnaire = f.CodeFonctionnaire
LEFT JOIN Mise m
ON m.CodeFonctionnaire = f.CodeFonctionnaire
LEFT JOIN Echelon e
ON e.NumEchelon = p.NumEchelon

SQL Server 2012 : Multiple Queries in One Stored Procedure

How do I create Stored Procedure on these queries and he output should show which check the anomaly was captured from, along with all the relevant data.
SELECT cm.Cust_id, cm.cust_ref_id4, cm.cust_ref_id3, cm.plan_group, cm.Company_name, cm.Cust_firstname, cm.Cust_lastname
COALESCE(c.pkCustomerID, c2.fkCustomerID, c3.pkCustomerID, c4.pkCustomerID) AS pkCustomerID, c3.CompanyName FROM PRODUCTIONSQL.[SigmaPaTri].[dbo].[CUSTOMER_MASTER] cm
LEFT JOIN PHOENIX.CORE.dbo.Customers AS c ON cust_ref_id4 = c.pkCustomerID AND cm.cust_ref_id3 = c.pkCustomerID AND cm.cust_ref_id3 >= 1000000 AND cm.Cust_firstname + ' ' + cm.Cust_lastname = c.CompanyName
LEFT JOIN PHOENIX.CORE.dbo.Contracts AS c2 ON cm.cust_ref_id3 = c2.ConfirmationNumber
WHERE cm.cust_status IN ('A','P','R','G') AND COALESCE(c.pkCustomerID, c2.fkCustomerID) IS NULL ORDER BY cust_ref_id4;
and
SELECT [pkCustomerID],b.[pkContractID],[pkCustomerTypeID],[CustomerType],b.[ContractType] AS Contractype1,c.[ContractType]
AS Contractype2 FROM [CORE].[dbo].[Customers] a
JOIN [CORE].[dbo].[CustomerTypes] ON [pkCustomerTypeID] = [fkCustomerTypeID]
LEFT JOIN (SELECT [pkContractID],[ContractType],[fkCustomerID] FROM [CORE].[dbo].[Contracts]
JOIN [CORE].[dbo].[ContractTypes] ON [fkContractTypeID] = [pkContractTypeID] WHERE [ContractType] NOT LIKE 'Holdover%')b ON a.pkCustomerID=b.fkCustomerID
LEFT JOIN (SELECT [pkContractID],[fkCustomerID],[ContractType] FROM [CORE].[dbo].[Contracts]
JOIN [CORE].[dbo].[ContractTypes] ON [fkContractTypeID] = [pkContractTypeID] WHERE ContractType LIKE 'Holdover%')c ON b.fkCustomerID=c.fkCustomerID WHERE [CustomerType] IN ('Customer','Former Customer') AND (b.ContractType IS NULL OR c.ContractType IS NULL)
You question is lacking a very important piece of information, the explanation of what you are trying to do. I took a shot in the dark here as a guess to what you might be looking for. BTW, I ran this through a formatter so it was legible.
SELECT 'Found in query1'
,cm.Cust_id
,cm.cust_ref_id4
,cm.cust_ref_id3
,cm.plan_group
,cm.Company_name
,cm.Cust_firstname
,cm.Cust_lastname
,COALESCE(c.pkCustomerID, c2.fkCustomerID, c3.pkCustomerID, c4.pkCustomerID) AS pkCustomerID
,c3.CompanyName
FROM PRODUCTIONSQL.[SigmaPaTri].[dbo].[CUSTOMER_MASTER] cm
LEFT JOIN PHOENIX.CORE.dbo.Customers AS c ON cust_ref_id4 = c.pkCustomerID
AND cm.cust_ref_id3 = c.pkCustomerID
AND cm.cust_ref_id3 >= 1000000
AND cm.Cust_firstname + ' ' + cm.Cust_lastname = c.CompanyName
LEFT JOIN PHOENIX.CORE.dbo.Contracts AS c2 ON cm.cust_ref_id3 = c2.ConfirmationNumber
WHERE cm.cust_status IN (
'A'
,'P'
,'R'
,'G'
)
AND COALESCE(c.pkCustomerID, c2.fkCustomerID) IS NULL
SELECT 'Found in query 2'
,[pkCustomerID]
,b.[pkContractID]
,[pkCustomerTypeID]
,[CustomerType]
,b.[ContractType] AS Contractype1
,c.[ContractType] AS Contractype2
FROM [CORE].[dbo].[Customers] a
INNER JOIN [CORE].[dbo].[CustomerTypes] ON [pkCustomerTypeID] = [fkCustomerTypeID]
LEFT JOIN (
SELECT [pkContractID]
,[ContractType]
,[fkCustomerID]
FROM [CORE].[dbo].[Contracts]
INNER JOIN [CORE].[dbo].[ContractTypes] ON [fkContractTypeID] = [pkContractTypeID]
WHERE [ContractType] NOT LIKE 'Holdover%'
) b ON a.pkCustomerID = b.fkCustomerID
LEFT JOIN (
SELECT [pkContractID]
,[fkCustomerID]
,[ContractType]
FROM [CORE].[dbo].[Contracts]
INNER JOIN [CORE].[dbo].[ContractTypes] ON [fkContractTypeID] = [pkContractTypeID]
WHERE ContractType LIKE 'Holdover%'
) c ON b.fkCustomerID = c.fkCustomerID
WHERE [CustomerType] IN (
'Customer'
,'Former Customer'
)
AND (
b.ContractType IS NULL
OR c.ContractType IS NULL
)