Mysql Multiplying and adding Result of Subquery - mysql

Hi I am new to my sql I am trying to multiply and add the result of my subquery however my query is not working it gives me 0 output always for each rows
my column is like this Output of total column is wrong
Val1 Income Val2 Total
1 5 5 0
1 1 8 0
1 1 7 0
5 7 6 0
my query is like this
SELECT
COUNT(DISTINCT t1.id) AS 'Val1',
(SELECT SUM(CAST(COALESCE(r.t_payment_total,0) AS DECIMAL(18,2))) AS 'Income'
FROM reserv r
INNER JOIN newtbladds1 t ON t.t_parent_id = r.id
WHERE r.t_status!="Pending" && r.t_status!="Booked" AND r.c_mid = m.id AND t.t_type_id = t1.t_type_id
)AS 'Income',
num1 AS 'Val2',
'Val1'*'Income'+ 'Val2' as 'Total'
FROM tbladds1 t1
JOIN tbladds1_type tt ON tt.id = t1.t_type_id
JOIN tbladdress m ON m.id = t1.t_mid
JOIN tbladdressfr mf ON mf.id = t1.t_floor_id
JOIN tblppl mp ON mp.t_mid = m.id AND mp.t_type = 'try' AND mp.t_system_id = 'ok'
GROUP BY t1.t_tool_type_id
ORDER BY m.t_m ASC, tt.t_ttype ASC, mf.t_floor ASC;
Desired Output is like this. I will really appreciate any help or advice Thank you
Val1 Income Val2 Total
1 5 5 10
1 1 8 8
1 1 7 7
5 7 6 41

Related

Get the row with latest date after inner join

I have this query:
SELECT
achievements.id,
achievements.name,
achievements.category,
userAchievements.createdAt
FROM
achievements
INNER JOIN
userAchievements ON userAchievements.achievementId = achievements.id
AND userAchievements.userId = 12
WHERE
achievements.type = 2
Result of this query is:
id
name
category
createdAt
8
First
1
2021-02-11
13
Second
2
2021-02-12
14
Third
4
2021-03-01
15
Fourth
4
2021-03-02
I have to leave only unique category with max createdAt field.
I need a query that will give the following result:
id
name
category
createdAt
8
First
1
2021-02-11
13
Second
2
2021-02-12
15
Fourth
4
2021-03-02
If I use group by then it returns row with id 14.
MySQL version - 5.7.33.
Achievements table:
id
name
category
8
First
1
13
Second
2
14
Third
4
15
Fourth
4
UserAchievements table:
id
achievementId
userId
createdAt
3
8
12
2021-02-11
7
13
12
2021-02-12
36
15
12
2021-03-02
40
14
12
2021-03-01
P.S.
I managed to write a query that solves the problem
SELECT
*
FROM
(SELECT
*,
IF(#prev <> category, #rn:=0, #rn),
#prev:=category,
#rn:=#rn + 1 AS rn
FROM
(SELECT
achievements.id,
achievements.name,
achievements.category,
userAchievements.createdAt
FROM
achievements
INNER JOIN userAchievements ON userAchievements.achievementId = achievements.id
AND userAchievements.userId = 12
WHERE
achievements.type = 2) as ach, (SELECT #rn:=0) rn, (SELECT #prev:='') prev
ORDER BY ach.createdAt DESC) t
WHERE
rn = 1
You can use window functions:
SELECT a.*
FROM (SELECT a.*,
ROW_NUMBER() OVER (PARTITION BY a.category ORDER BY a.created_at DESC) as seqnum
FROM achievements JOIN
userAchievements ua
ON ua.achievementId = a.id AND
ua.userId = 12
WHERE a.type = 2
) a
WHERE seqnum = 1;
This subquery basically search for all maximum dates, grouped by category.
SELECT MAX(_ua.createdAt) FROM `achievements` _a INNER JOIN user_achievements _ua ON _a.id = _ua.achievementId group by _a.category
So you maybe you can do :
SELECT a.* FROM achievements a
INNER JOIN user_achievements ua ON a.id = ua.achievementId
AND ua.createdAt IN (SELECT MAX(_ua.createdAt) FROM `achievements` _a INNER JOIN
user_achievements _ua ON _a.id = _ua.achievementId group by _a.category)

Filter a SQL table according to a condition

I have a table like this in MySQL :
Group Seqno Event
1 1 A
1 2 B
1 3 C
1 4 B
1 5 E
1 6 B
1 7 D
1 8 A
I want to count all the rows from last (most recent entry) for each Group with Event = B, and return all remaining rows as soon as it hit count of 2.
The output will be
Group Seqno Event
1 4 B
1 5 E
1 6 B
1 7 D
1 8 A
Any idea how to achieve it.
You seem to want all rows from the second to last "B"?
If so, you can use a correlated subquery:
select t.*
from t
where t.seqno >= (select t2.seqno
from t t2
where t2.group = t.group and t2.event = 'B'
order by t2.seqnum desc
limit 1, 1
);
To handle the case where there may be no "second" sequence number, you can use coalesce():
select t.*
from t
where t.seqno >= coalesce( (select t2.seqno
from t t2
where t2.group = t.group and t2.event = 'B'
order by t2.seqnum desc
limit 1, 1
), t.seqno
);

Two where condition for same column using group by

I am having two tables, t1, t2. My tables and expected result are given below.
My table schema is in sqlfiddle
t1:
id branch_name
1 branch1
2 branch2
3 branch3
4 branch4
5 branch5
t2:
id VBRNCH VTOBRN vqty
1 1 0 10
2 2 0 20
3 3 0 30
4 0 4 40
5 0 5 50
Expected Result is:
branch_name send received
1 10 0
2 20 0
3 30 0
4 0 40
5 0 50
What i have tried is:
SELECT
b1.branch_name,
i1.vqty AS send,
i2.vqty AS received
FROM t2 i1
INNER
JOIN t1 b1
ON b1.id = i1.VBRNCH
INNER JOIN t2 i2
ON b1.id = i2.VTOBRN
GROUP
BY i1.VTOBRN,
i2.VBRNCH;
But I am getting zero rows.
I think this is the query you are looking for:
SELECT t1.branch_name,
COALESCE(SUM(send.vqty), 0) AS send,
COALESCE(SUM(receive.vqty), 0) AS received
FROM t1
LEFT JOIN t2 AS send on t1.id = send.VBRNCH
LEFT JOIN t2 AS receive on t1.id = receive.VTOBRN
GROUP BY t1.branch_name
Demo here
E.g.
SELECT x.*
, COALESCE(sent,0) sent
, COALESCE(received,0) received
FROM t1 x
LEFT
JOIN
( SELECT from_br
, SUM(vqty) sent
FROM t2
GROUP
BY from_br
) a
ON a.from_br = x.id
LEFT
JOIN
( SELECT to_br
, SUM(vqty) received
FROM t2
GROUP
BY to_br
) b
ON b.to_br = x.id
ORDER
BY id;
http://sqlfiddle.com/#!9/af0973/21

MySQL getting value in same column as where conditional

Need some help creating a query that can get me the results I want.
I'm pulling information from 2 tables in the mysql database.
TABLE 1 - tblclients
ID firstname lastname
1 Bob K
2 Mary J
3 Tod M
tblcustomfieldsvalues.RelId = tblclients.ID
TABLE 2 - tblcustomfieldsvalues
ID fieldid RelId value
1 15 3 3500
2 15 2 1500
3 17 3 Calp
4 17 2 Amazon
5 17 2 Calp
TABLE 3 - tblcustomfields (JUST FOR REFERENCE)
ID FieldID name
1 15 Purchase Amount
2 17 Site
Desired Result:
I want to show the Purchase Amount in column 4 (FieldID = 15) where FieldID = 17 and value = 'calp'
ID FirstName LastName Value
1 Tod M 3500
2 Mary J 1500
Current Query:
SELECT tblclients.id, tblclients.firstname, tblclients.lastname, tblcustomfieldsvalues.value FROM tblclients INNER JOIN tblcustomfieldsvalues ON tblclients.id = tblcustomfieldsvalues.relid WHERE tblcustomfieldsvalues.fieldid = 17 AND tblcustomfieldsvalues.value = 'Calp'
Current Result:
ID FirstName LastName Value
1 Tod M Calp
2 Mary J Calp
One approach to this is conditional aggregation:
select c.*, value15 as value
from tblclients c join
(select cfv.relid,
max(case when fieldid = 15 then value end) as value15,
sum(case when fieldid = 17 and value = 'Calp' then 1 else 0 end) as cnt17
from tblcustomfieldsvalues cfv
group by cfv.relid
) cv
where cnt17 > 0;
You can also do this with joins. But you need separate joins for each for each of the fields:
SELECT c.id, c.firstname, c.lastname, cfv15.value
FROM tblclients c INNER JOIN
tblcustomfieldsvalues cfv17
ON c.id = cfv17.relid AND
cvf17.fieldid = 17 AND cfv17.value = 'Calp' INNER JOIN
tblcustomfieldsvalues cfv15
ON c.id = cfv15.relid AND
cvf15.fieldid = 15;
I am not clear what result you are expecting...
First of all I am sure you wrote fieldid=17 to get this result not 47.
If so
Your result is normal. You ask for fieldid 17 and also value 'Calp'.
Do you want fieldid 15 maybe ? Those were the ones has prices...
Or maybe
SELECT tblclients.id, tblclients.firstname, tblclients.lastname, tblcustomfieldsvalues.value FROM tblclients INNER JOIN tblcustomfieldsvalues ON tblclients.id = tblcustomfieldsvalues.relid WHERE tblcustomfieldsvalues.fieldid in (15,17) OR tblcustomfieldsvalues.value = 'Calp'
Your Query:
SELECT tblclients.id, tblclients.firstname, tblclients.lastname, tblcustomfieldsvalues.value FROM tblclients INNER JOIN tblcustomfieldsvalues ON tblclients.id = tblcustomfieldsvalues.relid WHERE tblcustomfieldsvalues.fieldid = 47 AND tblcustomfieldsvalues.value = 'Calp'

except alternative on mysql

I need to have first select values that are not in the second select.
select tnum,user from resp order by tnum, user
except
select test.tnum,cursa.user from cursa inner join test on test.curso = cursa.curso;
results:
select tnum,user from resp order by tnum, user;=
tnum user
1 1
1 7
1 8
1 10
2 7
select test.tnum,cursa.user from cursa inner join test on test.curso = cursa.curso;=
tnum user
1 1
1 7
1 8
1 10
2 1
2 8
3 1
3 7
3 8
3 10
4 1
4 7
4 8
4 10
I need of return tnum 2 and user 7.
This would often be solved using not exists:
select r.tnum, r.user
from resp r
where not exists (select 1
from cursa c inner join
test t
on t.curso = c.curso
where t.tnum = r.tnum and c.user = r.user
);
This has a slight difference in how it handles NULL values. If either rep.tnum or resp.user are NULL, then the row will not be removed.
If this is a possibility, then change the where clause in the subquery to:
where (t.tnum = r.tnum or (t.tnum is null and r.tnum is null) ) and
(c.user = r.user or (c.user is null and r.user is null) )
You can use a LEFT JOIN:
select tnum, user
from resp AS t1
left join (
select test.tnum, cursa.user
from cursa
inner join test
on test.curso = cursa.curso ) AS t2
ON t1.tnum = t2.tnum AND t1.user = t2.user
WHERE t2.num IS NULL AND t2.user IS NULL
order by tnum, user
The WHERE clause filters out all rows of resp that are related to rows of the derived table.