SELECT Inside a Case in MySQL - mysql

Is it possible to create an SELECT Statement within Conditional CASE, like this
SELECT la.*,
(
CASE
WHEN la.SoftDelete = 1
SELECT SUM(la.LoansAmount) FROM loans_account
ELSE
SELECT 0
END
) AS outstanding
FROM loans_account
I have tried this, but it does not work, I would like to know how to go about something like this please.

I guess you need the sum of loan amount where softdelete is 1
SELECT la.*,
SUM(
CASE
WHEN la.SoftDelete = 1
THEN la.LoansAmount
ELSE
0
END
) AS outstanding
FROM loans_account la
WHERE ...
or if you need the sum from whole where softdelete is 1 then you can do so
SELECT la.*,
SUM(la.LoansAmount) outstanding
FROM loans_account la
WHERE la.SoftDelete = 1
Note sum is aggregate function and without group by it will result as a single row assuming the whole table as one group

try this
SELECT la.*, CASE
WHEN la.SoftDelete = 1 THEN SUM(la.LoansAmount)
ELSE 0 END AS outstanding
FROM loans_account

Related

How to display duplicate count from two tables where one column duplicate value separate in two column from each table

First of all I want to thank you all members of this community for posting very helpful answers. I am using this kind of plateform first so I am sorry for my grammatical mistakes and if it is a silly question.
I am having a use case as given in below image link.
Having two tables 1. is Office_1 and 2. is Office_2 and want the Desired Output
For this use case I am able to get Output separately only from one table using below query
First query is for one table (Office_1)
select EID as EID,sum(case when OP like 'come' then 1 else 0 end) as 'Office_1 Come COUNT',sum(case when OP like 'go' then 1 else 0 end) as 'Office_1 Go COUNT' from Office_1 where DATE >= '2022-01-16' AND DATE <= '2022-01-18' group by UID;
Second query is for another table (Office_2)
select EID as EID,sum(case when OP like 'come' then 1 else 0 end) as 'Office_2 Come COUNT',sum(case when OP like 'go' then 1 else 0 end) as 'Office_2 Go COUNT' from Office_2 where DATE >= '2022-01-16' AND DATE <= '2022-01-18' group by UID;
But I want that UID must be selected from first table and output must be combined to display. Please help me in this use case. How to get the desired output?
select* from(select EID as EID,sum(case when OP like 'come' then 1 else 0 end) as 'Office_1 Come COUNT',sum(case when OP like 'go' then 1 else 0 end) as 'Office_1 Go COUNT',date as dt from Office_1
union
select EID as EID,sum(case when OP like 'come' then 1 else 0 end) as 'Office_2 Come COUNT',sum(case when OP like 'go' then 1 else 0 end) as 'Office_2 Go COUNT',date as dt from Office_2)
where dt >= '2022-01-16' AND DATE <= '2022-01-18' group by UID;
Please refer here for more information about union select https://dev.mysql.com/doc/refman/8.0/en/union.html

SQL query - find values that meet m conditions out of n

Is there any way to find values that meet any m conditions out of given n conditions? For instance, if there are 10 conditions, and I want to find values that meet any 2 of them.
Use CASE expressions in the WHERE clause, 1 for each condition like this:
WHERE 2 =
CASE WHEN <condition1> THEN 1 ELSE 0 END +
CASE WHEN <condition2> THEN 1 ELSE 0 END +
CASE WHEN <condition3> THEN 1 ELSE 0 END +
..........................................
You can change the = sign to > or < to meet your requirement.
There is. It's not gonna be pretty though.
Start with your conditions as SELECT expressions.
select T.*,
case
when T.SOME_NUMERIC_COLUMN > 0 then 1
else 0
end IS_POSITIVE,
(select sign(COUNT(*))
from SOME_OTHER_TABLE
where parent_id = T.ID) HAS_CHILDREN
...
from SOME_TABLE T
Design these expression in such a way that you get 1 when a condition is met and 0 when it's not.
Then sum up the score and add a WHERE clause.
SELECT *
FROM (
SELECT R.*,
IS_POSITIVE + HAS_CHILDREN + ... SCORE
FROM (...) R)
WHERE SCORE > 2
Of course you're gonna pay a hefty price in performance for this. You won't be able to use your conditions directly to limit the resultset so I'd expect the execution plans to be extremely disappointing. That said, it's not like what you have in mind is a standard task for RDBMS so it should be enough for a proof of concept.

To get total count based on condition

I am struggling to get the count of a particular person. As I am new to tableau I don't know how to write the condition for this query.
SELECT COUNT(*) as cnt
FROM
Expert_CollaborationsRequests
WHERE
ExpertID=3 AND
IsAccepted = 1
Generate a calculated field as:
Calculation1: IF ExpertID=3 AND IsAccepted = 1 THEN 1 ELSE 0 END
Then, place this field on a shelf (row, columns, etc.) and select Measure (Sum).
You can use LOD (Level of Detail) like so:
{ FIXED [ExpertID]: SUM(IF [IsAccepted]= 1 THEN 1 ELSE 0 END) }
This will give you aggregated values for each user.
For more information on LOD, please follow official Tableau help link here
SELECT COUNT(ExpertID),COUNT(IsAccepted ) as cnt
FROM
Expert_CollaborationsRequests
WHERE
ExpertID=3 OR
IsAccepted = 1

How can I multiply numbers(data) in one column in MySQL?

How can I multiply all numbers in one column?
for example:
Status(finished or not finished)
1
1
1
1
0
I know how to use sum.
sum(Status)=4
I need some thing like sum for multiply
mul(status)=0
do we have something like mul(status)?
I don't know of a multiply aggregate function. However, in the case of a column containing only zeroes and ones the product will be one only if every value be one, otherwise it will be zero:
SELECT
CASE WHEN SUM(status) = COUNT(status) THEN 1 ELSE 0 END AS product
FROM yourTable
CASE WHEN SUM(status) = COUNT(status) THEN 1 ELSE 0 END AS product

MAX with extra criteria

I have the following part of a query I'm working on in MYSQL.
SELECT
MAX(CAST(MatchPlayerBatting.BatRuns AS SIGNED)) AS HighestScore
FROM
MatchPlayerBatting
It returns the correct result. However there is another column I need it to work off.
That is if the maximum value it finds also has a value of "not out" within "BatHowOut", it should show the result as for example 96* rather than just 96.
How could this be done?
To help make the data concrete, consider two cases:
BatRuns BatHowOut
96 not out
96 lbw
BatRuns BatHowOut
96 not out
102 lbw
For the first data, the answer should be '96*'; for the second, '102'.
You can achieve this using self-join like this:
SELECT t1.ID
, CONCAT(t1.BatRuns,
CASE WHEN t1.BatHowOut = 'Not Out' THEN '*' ELSE '' END
) AS HighScore
FROM MatchPlayerBatting t1
JOIN
(
SELECT MAX(BatRuns) AS HighestScore
FROM MatchPlayerBatting
) t2
ON t1.BatRuns = t2.HighestScore
See this sample SQLFiddle with highest "Not Out"
See this another sample SQLFiddle with highest "Out"
See this another sample SQLFiddle with two highest scores
How about ordering the scores in descending order and selecting only the first record?
select concat(BatRuns , case when BatHowOut = 'not out' then '*' else '' end)
from mytable
order by cast(BatRuns as signed) desc,
(case when BatHowOut = 'not out' then 1 else 2 end)
limit 1;
Sample here.
If you want to find highest score score for each player, here is a solution that may not be elegant, but quite effective.
select PlayerID,
case when runs != round(runs)
then concat(round(runs),'*')
else
round(runs)
end highest_score
from (select PlayerID,
max(cast(BatRuns as decimal) +
case when BatHowOut = 'not out' then 0.1 else 0 end
) runs
from MatchPlayerBatting
group by PlayerID) max_runs;
This takes advantage of the fact that, runs can never be fractions, only whole numbers. When there is a tie for highest score and one of them is unbeaten,
adding 0.1 to the unbeaten score will make it the highest. This can be later removed and concatenated with *.
Sample here.