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`)
Related
I'm trying to run a somewhat complex sql statement using the 'group_concat' function for statistics.
When I run the sql statement using navicat, the correct result is returned.But when I use mybatis debug this sql in idea, it returns null value.
I use HashMapHashMap<String,Long> to receive the result set executed by mybatis,
I guess the result set returned by mybatis executing sql is wrongly encapsulated.
But I tried for a long time and couldn't find a solution.
I can't post pictures here,I display the results in a table.
cha
hege
lianghao
youxiu
1
1
2
1
Receive declaration at the mapper layer
HashMap<String, Long> getOption(#Param("column") String column);
Here is the sql code:
<select id="getOption" resultType="java.util.HashMap">
SELECT GROUP_CONCAT(form.cha SEPARATOR '') cha,
GROUP_CONCAT(form.hege SEPARATOR '') hege,
GROUP_CONCAT(form.lianghao SEPARATOR '') lianghao,
GROUP_CONCAT(form.youxiu SEPARATOR '') youxiu
FROM (
SELECT
( CASE WHEN #{column} = '0' THEN count(*) ELSE NULL END) AS 'cha',
( CASE WHEN #{column} = '1' THEN count(*) ELSE NULL END ) AS 'hege',
( CASE WHEN #{column} = '2' THEN count(*) ELSE NULL END ) AS 'lianghao',
( CASE WHEN #{column} = '3' THEN count(*) ELSE NULL END ) AS 'youxiu'
FROM corp_feedback_student
GROUP BY #{column}
) form
</select>
Thanks everyone for helping me!!
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Referring to a Column Alias in a WHERE Clause
SELECT
Trade.TradeId,
Isnull(Securities.SecurityType,'Other') SecurityType,
TableName,
CASE
WHEN
SecurityTrade.SecurityId IS NOT NULL
THEN
SecurityTrade.SecurityId
ELSE
Trade.SecurityId
END AS PricingSecurityID,
sum(Trade.Quantity)OVER(Partition by Securities.SecurityType, SecurityTrade.SecurityId,Trade.Price, Buy,Long ) as sumQuantity,
--added porfolio id for Getsumofqantity
Trade.PortfolioId,
Trade.Price,
case
when (Buy = 1 and Long = 1) then 1
when (Buy = 0 and Long = 0) then 1
else 0
end Position
from
Fireball_Reporting..Trade
where porfolioid =5 and Position =1
i want to use Position =1 in my where clause which is an alias of case
case
when (Buy = 1 and Long = 1) then 1
when (Buy = 0 and Long = 0) then 1
else 0
end Position
How can I use it in where clause?
I tried zo directly use that CASE statement in where clause, but failed.
WHERE Trade.SecurityId = #SecurityId AND PortfolioId = #GHPortfolioID AND
(case when (Buy = 1 and Long = 1) then 1 when (Buy = 0 and Long = 0) then 1 else 0 end Position = 1)
The SQL-Server docs says:
column_alias can be used in an ORDER BY clause, but it cannot be used in a WHERE, GROUP BY, or HAVING clause.
Similar in the MySQL doc it says:
Standard SQL disallows references to column aliases in a WHERE clause. This restriction is imposed because when the WHERE clause is evaluated, the column value may not yet have been determined.
In MySQL you can at least reuse aliases in the SELECT clause
You can't, not directly.
If you wrap the whole query in a sub-query, however, it works fine.
SELECT
*
FROM
(
SELECT
Trade.TradeId,
Isnull(Securities.SecurityType,'Other') SecurityType,
TableName,
CASE
WHEN SecurityTrade.SecurityId IS NOT NULL THEN SecurityTrade.SecurityId
ELSE Trade.SecurityId
END AS PricingSecurityID,
sum(Trade.Quantity)OVER(Partition by Securities.SecurityType,
SecurityTrade.SecurityId,Trade.Price, Buy,Long ) as sumQuantity,
--added porfolio id for Getsumofqantity
Trade.PortfolioId,
Trade.Price,
case
when (Buy = 1 and Long = 1) then 1
when (Buy = 0 and Long = 0) then 1
else 0
end Position
from
Fireball_Reporting..Trade
where
porfolioid = 5
)
AS data
WHERE
Position = 1
This means that you don't need to repeat the CASE statement in WHERE clause. (Maintainable and DRY).
It is also a structure that allows the optimiser to behave as if you had simply repeated yourself in the WHERE clause.
It's also very portable to other RDBMSs.
In SQL Server, then you also have another option...
SELECT
Trade.TradeId,
Isnull(Securities.SecurityType,'Other') SecurityType,
TableName,
CASE
WHEN SecurityTrade.SecurityId IS NOT NULL THEN SecurityTrade.SecurityId
ELSE Trade.SecurityId
END AS PricingSecurityID,
sum(Trade.Quantity)OVER(Partition by Securities.SecurityType,
SecurityTrade.SecurityId,Trade.Price, Buy,Long ) as sumQuantity,
--added porfolio id for Getsumofqantity
Trade.PortfolioId,
Trade.Price,
position.val AS Position
from
Fireball_Reporting..Trade
CROSS APPLY
(
SELECT
case
when (Buy = 1 and Long = 1) then 1
when (Buy = 0 and Long = 0) then 1
else 0
end AS val
)
AS position
where
porfolioid = 5
AND position.val = 1
You can't directly do this...but you can wrap an additional select around it all and use the where clause:
select * from
( SELECT
Trade.TradeId,
Isnull(Securities.SecurityType,'Other') SecurityType,
TableName,
CASE
WHEN
SecurityTrade.SecurityId IS NOT NULL
THEN
SecurityTrade.SecurityId
ELSE
Trade.SecurityId
END AS PricingSecurityID,
sum(Trade.Quantity)OVER(Partition by Securities.SecurityType, SecurityTrade.SecurityId,Trade.Price, Buy,Long ) as sumQuantity,
--added porfolio id for Getsumofqantity
Trade.PortfolioId,
Trade.Price,
case
when (Buy = 1 and Long = 1) then 1
when (Buy = 0 and Long = 0) then 1
else 0
end Position
from
Fireball_Reporting..Trade
where porfolioid =5 and Position =1
)x
where x.position = 1
I'm probably missing something but surely this will cover it:
WHERE (Buy = 1 and Long = 1) OR (Buy = 0 and Long = 0)
Hello I have this query that i am trying to execute and i keep getting this error "Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.", Kindly help please.
DECLARE #NUMCOUNT BIT
Select #NUMCOUNT = (SELECT
CASE WHEN
(SELECT COUNT(R5REQUISLINES.RQL_REQ)
WHERE R5REQUISLINES.RQL_STATUS IN ('A')
) IN
(SELECT COUNT(R5REQUISLINES.RQL_REQ)
WHERE R5REQUISLINES.RQL_STATUS IN ( 'A','C') ) THEN 1 else 0 END AS NUMCOUNT1
FROM R5REQUISLINES JOIN
R5REQUISITIONS ON R5REQUISLINES.RQL_REQ = R5REQUISITIONS.REQ_CODE
GROUP BY R5REQUISLINES.RQL_REQ, R5REQUISITIONS.REQ_CODE,R5REQUISLINES.RQL_STATUS
)
IF #NUMCOUNT = '1'
begin
UPDATE R5REQUISITIONS
SET R5REQUISITIONS.REQ_STATUS = 'CP'
end
Ok, it sounds like what you actually want to do is update R5REQUISITIONS when there is no RQL_STATUS = 'C' in R5REQUISLINES, since you said you want to count the records where the RQL_STATUS is A and where it's A or C, and then do the update if the counts are the same.. You can greatly simplify this task with the following query:
UPDATE r5
SET r5.REQ_STATUS = 'CP'
FROM R5REQUISITIONS r5
WHERE NOT EXISTS (SELECT 1 FROM R5REQUISLINES r5q WHERE r5q.RQL_REQ = r5.REQ_CODE AND r5q.RQL_STATUS = 'C')
Your 'SELECT CASE' is returning more than 1 record, so it can't be assigned to #NUMBER. Either fix the sub-query to only return the record your looking for or hack it to return only 1 with a 'LIMIT 1' qualification.
I don't know what your data looks like so I can't tell you why your case subquery returns more records than you think it should.
Try running this and see what it returns, that will probably tell you wall you need to know:
SELECT
CASE WHEN
(SELECT COUNT(R5REQUISLINES.RQL_REQ)
WHERE R5REQUISLINES.RQL_STATUS IN ('A')
) IN
(SELECT COUNT(R5REQUISLINES.RQL_REQ)
WHERE R5REQUISLINES.RQL_STATUS IN ( 'A','C')
)
THEN 1
ELSE 0
END AS NUMCOUNT1
FROM R5REQUISLINES JOIN
R5REQUISITIONS ON R5REQUISLINES.RQL_REQ = R5REQUISITIONS.REQ_CODE
GROUP BY R5REQUISLINES.RQL_REQ, R5REQUISITIONS.REQ_CODE,R5REQUISLINES.RQL_STATUS
If there is more than 1 row returned, that's where your problem is.
I'm writing a query to get gross profit percentage "GP%" of a certain product to put it in a C# grid view by product by year. I Want the query result to be dynamic that in some years this product was n't sold so the result will be (profit/sales)=(0/0) it will be null. this null isn't accepted by C#.
The query is
SELECT
FORMAT((SELECT ((ISNULL(SUM([Profit]), NULL)) / ISNULL(SUM([Sales]), NULL))
FROM [dbo].[Sales]
WHERE [ProdHeir01_2] = 'Batteries'
AND [Sales_Year] = 2015
AND [Month_Number] BETWEEN 1 AND 8, 'P') AS [Percentage]
This query results in 'Null'. How can I insert a condition to transfer null to a string value. so the query to be dynamic :).
Thanks a lot in advance......
Regards
Here is on technique you may find helpful:
select 0 / CASE WHEN IsNull([Sales],0) = 0 THEN 1 ELSE [Sales] END
Hady, here you go.
--CTE(Common Table Expression) with your query
WITH preselect AS
(
SELECT
FORMAT(
(SELECT ISNULL(SUM([Profit]), NULL) / ISNULL(SUM([Sales]), NULL)
FROM [dbo].[Sales]
WHERE [ProdHeir01_2] = 'Batteries'
AND [Sales_Year] = 2015
AND [Month_Number] BETWEEN 1 AND 8
)
,'P'
) AS [Percentage])
--Case statement that will return Null as string when Null and the percentage
--when it isn't null
SELECT CASE WHEN [Percentage] IS NULL THEN 'Null' ELSE [Percentage] END AS [Percentage]
FROM preselect
I have a table with 3 columns( name, objectroot_dn, distinguishedname). Here distinguishedname is like a parent to objectroot_dn. I have to find whether for each objectroot_dn is there a child exists or not?
I can do this using the query below. It will return True if there is a child, False if there is not. But my problem is when the total dataset gets increased it takes lots of time.
For example, If the total number of row is 50,000 then it takes 10 mins for this query to complete.
Since I'm using a framework for different database, I can't index the columns.
SELECT
name,
objectroot_dn,
distinguishedname,
CASE
WHEN (SELECT count(*)
FROM (SELECT name
FROM elaoucontainergeneraldetails
WHERE objectroot_dn = dn.distinguishedname
LIMIT 1) AS tabel1) > 0
THEN 'True'
ELSE 'False'
END
FROM elaoucontainergeneraldetails AS dn
WHERE objectroot_dn = 'SOME_VALUE';
Please let me know how can I increase the speed of this query.
Thanks in advance. Appreciate all help.
You can have the same solution using left join or exists:
SELECT
dn.name,
dn.objectroot_dn,
dn.distinguishedname,
CASE
WHEN dn_in.objectroot_dn is not null
THEN 'True'
ELSE 'False'
END
FROM elaoucontainergeneraldetails AS dn
LEFT JOIN elaoucontainergeneraldetails dn_in on dn_in.objectroot_dn = dn.distinguishedname
WHERE objectroot_dn = 'SOME_VALUE';
EXISTS(subquery) yields a boolean value:
SELECT dn.name
, dn.objectroot_dn
, dn.distinguishedname
, EXISTS (SELECT *
FROM elaoucontainergeneraldetails nx
WHERE nx.objectroot_dn = dn.distinguishedname
) AS truth_value
FROM elaoucontainergeneraldetails AS dn
WHERE dn.objectroot_dn = 'SOME_VALUE'
;