How to avoid multiple <Debtor> and <Creditor> elements that are created.
Below is a query I need to improve. Basically I need to get both <name> and <address> inside either <Creditor> or <Debtor> depending on Amt expressed by CASE condition.
SELECT
(SELECT [Amt/#Curr] = t.Curr
,t.Amt
,[EntryDetails/TxnDetails/PostClassDt] = CASE WHEN Amt < 0 THEN 'debit' END
,[EntryDetails/TxnDetails/PostClassCr] = CASE WHEN Amt >= 0 THEN 'return' END
,[EntryDetails/TxnDetails/Parties/Creditor/Name] = CASE WHEN Amt < 0 THEN Contractor END
,[EntryDetails/TxnDetails/Parties/Debtor/Name] = CASE WHEN Amt >= 0 THEN Contractor END
,[EntryDetails/TxnDetails/Parties/Creditor/Address] = CASE WHEN Amt < 0 THEN [Address] END
,[EntryDetails/TxnDetails/Parties/Debtor/Address] = CASE WHEN Amt >= 0 THEN [Address] END
FROM (VALUES
('EUR', -123.45, 'John Doe','St.John'),
('USD', 456.78, 'Jane Doe', 'St.Jane')
) t (Curr, Amt, Contractor, [Address])
FOR XML PATH('Entry'), TYPE
) [Statement]
FOR XML PATH('Schema'), ROOT('Document')
Required formatting shown below. Anyone help, please ?
<Document>
<Schema>
<Statement>
<Entry>
<Amt Curr="EUR">-123.45</Amt>
<EntryDetails>
<TxnDetails>
<PostClassDt>debit</PostClassDt>
<Parties>
<Creditor>
<Name>John Doe</Name>
<Address>St.John</Address>
</Creditor>
</Parties>
</TxnDetails>
</EntryDetails>
</Entry>
<Entry>
<Amt Curr="USD">456.78</Amt>
<EntryDetails>
<TxnDetails>
<PostClassCr>return</PostClassCr>
<Parties>
<Debtor>
<Name>Jane Doe</Name>
<Address>St.Jane</Address>
</Debtor>
</Parties>
</TxnDetails>
</EntryDetails>
</Entry>
</Statement>
</Schema>
</Document>
Change the order of your select:
SELECT
(SELECT [Amt/#Curr] = t.Curr
,t.Amt
,[EntryDetails/TxnDetails/PostClassDt] = CASE WHEN Amt < 0 THEN 'debit' END
,[EntryDetails/TxnDetails/PostClassCr] = CASE WHEN Amt >= 0 THEN 'return' END
,[EntryDetails/TxnDetails/Parties/Creditor/Name] = CASE WHEN Amt < 0 THEN Contractor END
,[EntryDetails/TxnDetails/Parties/Creditor/Address] = CASE WHEN Amt < 0 THEN [Address] END
,[EntryDetails/TxnDetails/Parties/Debtor/Name] = CASE WHEN Amt >= 0 THEN Contractor END
,[EntryDetails/TxnDetails/Parties/Debtor/Address] = CASE WHEN Amt >= 0 THEN [Address] END
FROM (VALUES
('EUR', -123.45, 'John Doe','St.John'),
('USD', 456.78, 'Jane Doe', 'St.Jane')
) t (Curr, Amt, Contractor, [Address])
FOR XML PATH('Entry'), TYPE
) [Statement]
FOR XML PATH('Schema'), ROOT('Document')
Related
I have the following tables:
deals:
PositionID - int
Login - int,
VolumeClosed - int,
Time = datetime
I have the following query:
select
d.PositionID,
d.login,
case
when d.VolumeClosed = 0 then d.Time
else ''
end as Open_Time,
case
when d.VolumeClosed = 0 then (
select
`TIME`
from
deals
where
volumeclosed <> 0
and d.PositionID = PositionID)
else ''
end as Close_Time
from
deals d
Is there a way to optimize the select in the Case statement ?
The result is the following:
"PositionID","Login","Open_Time","Close_Time"
0,250052,"2022-08-01 10:32:29",
6218368,250052,"2022-08-01 10:45:11","2022-08-01 10:45:12"
6218368,250052,"",""
6218374,250052,"2022-08-01 10:45:41","2022-08-01 10:45:42"
6218374,250052,"",""
This composite index on deals may speed up the subquery some:
INDEX(PositionID, volumeclosed, `TIME`)
I have a procedure that contains CASE expression statement like so:
BEGIN
....
WHILE counter < total DO
....
CASE ranking
WHEN 1 OR 51 OR 100 OR 167 THEN SET
project_name = 'alpha';
WHEN 2 THEN SET
project_name = 'beta';
WHEN 10 OR 31 OR 40 OR 61 THEN SET
project_name = 'charlie';
....
ELSE SET
project_name = 'zelta';
END CASE;
INSERT INTO project (id, name) VALUES (LAST_INSERT_ID(), project_name);
SET counter = counter + 1;
END WHILE;
END
$$
DELIMITER ;
When I call the above procedure, cases with OR statements are either skipped completely or only the first item in the list is matched. What am I doing wrong?
CASE ranking
WHEN 1 THEN 'alpha'
WHEN 2 THEN 'beta'
WHEN 10 THEN 'charlie'
ELSE 'zelta'
END CASE;
You can use one of expresions that WHEN has, but you cannot mix both of them.
1) WHEN when_expression
Is a simple expression to which input_expression is compared when the simple CASE format is used. when_expression is any valid expression. The data types of input_expression and each when_expression must be the same or must be an implicit conversion.
2) WHEN Boolean_expression
Is the Boolean expression evaluated when using the searched CASE format. Boolean_expression is any valid Boolean expression.
You could program:
1)
CASE ProductLine
WHEN 'R' THEN 'Road'
WHEN 'M' THEN 'Mountain'
WHEN 'T' THEN 'Touring'
WHEN 'S' THEN 'Other sale items'
ELSE 'Not for sale'
2)
CASE
WHEN ListPrice = 0 THEN 'Mfg item - not for resale'
WHEN ListPrice < 50 THEN 'Under $50'
WHEN ListPrice >= 50 and ListPrice < 250 THEN 'Under $250'
WHEN ListPrice >= 250 and ListPrice < 1000 THEN 'Under $1000'
ELSE 'Over $1000'
END
But in any case you can expect that the variable ranking is going to be compared in a boolean expresion.
http://msdn.microsoft.com/en-us/library/ms181765.aspx
you can use in to compare the values both numeric or character
CASE
WHEN ranking in(1,2,3) THEN '1Q'
WHEN ranking in(4,5,6) THEN '2Q'
ELSE '3Q'
END CASE;
CASE
WHEN ranking in('1','2','3') THEN '1Q'
WHEN ranking in('4','5','6') THEN '2Q'
ELSE '3Q'
END CASE;
this will also work in select statement and stored procedure also.
select case when month(curdate()) in (4,5,6) then 1 when month(curdate()) in (7,8,9) then 2 else 3 end as fiscal_quarter ;
This is also possible:
select (case when (var1 = 0 or var2 = 1) then 'x' else 'y' end)
from...
Hi i have the following SQL question:
SELECT station_id, filling_station_status,date_created ,
case when filling_station_status="FREE" then 0
else 1 end as status
FROM efahrung.electric_station_time_status
where station_id=11
In my table have a column filling_station_status.
It can be "FREE" or "IN_USE".
I want to group elements so, that if the filling_station_status is changed (from "FREE" to "IN_USE") it will create a date range in my case, date_created.
In the next change again from ("IN_USE" to "FREE") it creates a new date range.
Thanks for a suggestions.
If you just need SQL query to generate date range in output, then try this:
Select s.station_id,
Coalesce(e.filling_station_status, s.filling_station_status) fillingStationStatus,
case e.filling_station_status
when "FREE" then 0 else 1 end status,
s.date_created startDate,
e.date_created endDate
From efahrung.electric_station_time_status s
Left Join efahrung.electric_station_time_status e
On e.station_id = s.station_id
and s.filling_station_status = 'IN_USE'
and e.filling_station_status = 'FREE'
and e.date_created =
(Select Min(date_created)
From efahrung.electric_station_time_status
Where station_id = s.station_id
and date_created > s.date_created)
I got this query in my SQL Server 2008 procedure
insert into tableXYZ(ID, CODPROY, NOMPROY, TITOBS, OBSERVACION, RECOMENDACION, RESPUESTA, UNIDRESP, CONTACTO, FECHAEMISION, RIESGO, ULTIMAACTUALIZACION, FECHAVENCIMIENTO, ESTADO, FECHACARGATC, REGULADOR, REGULADO)
select
ID_Obs, CodigoProyecto, NombreProyecto, TituloObservacion, Incidencia,
Recomendacion, Respuesta, UnidadResponsable, Propietario,
case when isdate(FechaEmision) = 1 then CONVERT(DATETIME, FechaEmision, 103) end,
Riesgo, EstadoActualizacion,
case when isdate(FechaRevisada) = 1 then (CONVERT(DATETIME, FechaRevisada, 103)) else (case when isdate(FechaEstimada) = 1 then CONVERT(DATETIME,FechaEstimada,105) end) end,
Estado,
case when isdate(FechaCargaTC) = 1 then CONVERT(DATETIME, FechaCargaTC, 103) end,
Grupo, 'BCPPE'
from
#myTableType
where
GRUPO <> '467' and GRUPO <> '912' and GRUPO <> '910' and GRUPO <> ''
As you can see this query has many cast methods, the problem is that the results of this sentence is so differente between two users. Can you give me some clues?
PD: Look this part:
case when isdate(FechaRevisada) = 1 then (CONVERT(DATETIME, FechaRevisada, 103))
else (case when isdate(FechaEstimada) = 1 then CONVERT(DATETIME, FechaEstimada, 105) end)
end
This part of the query works right with me, but do not with my partner.
Is it possible I can do the case comparison on the assigned variable 'YRSUMGTHAN75'? When I try to do the case statement it barks at me saying 'incorrect syntax near '>''.
Here's my SQL:
SELECT A.DUR, A.TL_QUANTITY,
(SELECT SUM(TL_QUANTITY) FROM PS_TL_RPTD_TIME
WHERE DUR BETWEEN '01-01-2013' AND '12-31-2013' AND EMPLID = A.EMPLID AND TRC IN ('JNC', 'SRJ')
HAVING SUM(TL_QUANTITY) > 75) AS YRSUMGTHAN75
CASE YRSUMGTHAN75 WHEN > 75 THEN 'NewValue'
End
FROM PS_TL_RPTD_TIME A WHERE A.EMPLID = '10000106052' AND A.DUR > '01-01-2013'
I don't completely understand what you're trying to do, but this may be it:
select
DUR,
TL_QUANTITY,
case when YRSUMGTHAN75 > 75 then 'NewValue' else 'OldValue' end
from
(
SELECT
A.DUR,
A.TL_QUANTITY,
(SELECT SUM(TL_QUANTITY)
FROM PS_TL_RPTD_TIME
WHERE DUR BETWEEN '01-01-2013' AND '12-31-2013' AND EMPLID = A.EMPLID AND TRC IN ('JNC', 'SRJ')
HAVING SUM(TL_QUANTITY) > 75) AS YRSUMGTHAN75
FROM
PS_TL_RPTD_TIME A
WHERE
A.EMPLID = '10000106052' AND A.DUR > '01-01-2013'
) dt
If that doesn't help, please construct a small artificial example using dummy tables and data to illustrate your question clearly.