How to calculate Sum of 2 Count(*) in Mysql - mysql

I have two tables that I count rows of them.
SELECT COUNT(*)
FROM docgrados_directores
WHERE docgrados_directoresleido = '0' AND docgrados_directoresusu = '11'
result 1
SELECT COUNT(*)
FROM docgrados_lectores
WHERE docgrados_lectoresleido = '0' AND docgrados_lectoresusu = '11'
result 1
I need total count (result would be 2). How can I sum the result with a single statement? What is the correct syntax??

Use another SELECT to add the scalar values returned by your queries:
SELECT (SELECT COUNT(*)
FROM docgrados_directores
WHERE docgrados_directoresleido = '0' AND docgrados_directoresusu = '11' )
+
(SELECT COUNT(*)
FROM docgrados_lectores
WHERE docgrados_lectoresleido = '0' AND docgrados_lectoresusu = '11')
The above statement should return 2 as result if the result of both subqueries is a 1.

Related

mysql GROUP CONCAT not returning values

Here is my query
SELECT
SUM(o.order_disc + o.order_disc_vat) AS manualsale
FROM
orders o
WHERE
o.order_flag IN (0 , 2, 3)
AND o.order_status = '1'
AND (o.assign_sale_id IN (SELECT GROUP_CONCAT(CAST(id AS SIGNED)) AS ids FROM users WHERE team_id = 92))
AND DATE(o.payment_on) = DATE(NOW())
above query return null when i run this query in terminal
When i use subquery below it returns data
SELECT GROUP_CONCAT(CAST(id AS SIGNED)) AS ids FROM users WHERE team_id = 92)
above query returns
'106,124,142,179'
and when i run my first query like below
SELECT
SUM(o.order_disc + o.order_disc_vat) AS manualsale
FROM
orders o
WHERE
o.order_flag IN (0 , 2, 3)
AND o.order_status = '1'
AND (o.assign_sale_id IN (106,124,142,179))
AND DATE(o.payment_on) = DATE(NOW())
it return me value.
Why it is not working with subquery please help
This does not do what you want:
AND (o.assign_sale_id IN (SELECT GROUP_CONCAT(CAST(id AS SIGNED)) AS ids FROM users WHERE team_id = 92))
This compares a single value against a comma-separated list of values, so it never matches (unless there is just one row in users for the given team).
You could phrase this as:
AND assign_sale_id IN (SELECT id FROM users WHERE team_id = 92)
But this would probably be more efficently expressed with exists:
AND EXISTS(SELECT 1 FROM users u WHERE u.team_id = 92 AND u.id = o.assign_sale_id)
Side note: I would also recommend rewriting this condition:
AND DATE(o.payment_on) = DATE(NOW())
To the following, which can take advantage of an index:
AND o.payment_on >= current_date AND o.payment_on < current_date + interval 1 day

Why integer cast is not working with integer group_concat() list?

I'm stuck at the query where I need to concat IDs of the table. And from that group of IDs, I need to fetch that rows in sub query. But when I try to do so, MySQL consider group_concat() as a string. So that condition becomes false.
select count(*)
from rides r
where r.ride_status = 'cancelled'
and r.id IN (group_concat(rides.id))
*************** Original Query Below **************
-- Daily Earnings for 7 days [Final]
select
group_concat(rides.id) as ids,
group_concat(ride_category.name) as rideType,
group_concat(ride_cars.amount + ride_cars.commission) as rideAmount ,
group_concat(ride_types.name) as carType,
count(*) as numberOfRides,
(
select count(*) from rides r where r.ride_status = 'cancelled' and r.id IN (group_concat(rides.id) )
) as cancelledRides,
(
select count(*) from rides r where r.`ride_status` = 'completed' and r.id IN (group_concat(rides.id))
) as completedRides,
group_concat(ride_cars.status) as status,
sum(ride_cars.commission) + sum(ride_cars.amount) as amount,
date_format(from_unixtime(rides.requested_at/1000 + rides.offset*60), '%Y-%m-%d') as requestedDate,
date_format(from_unixtime(rides.requested_at/1000 + rides.offset*60), '%V') as week
from
ride_cars,
rides,
ride_category,
ride_type_cars,
ride_types
where
ride_cars.user_id = 166
AND (rides.ride_status = 'completed' or. rides.ride_status = 'cancelled')
AND ride_cars.ride_id = rides.id
AND (rides.requested_at >= 1559347200000 AND requested_at < 1561852800000)
AND rides.ride_category = ride_category.id
AND ride_cars.car_model_id = ride_type_cars.car_model_id
AND ride_cars.ride_type_id = ride_types.id
group by
requestedDate;
Any solutions will be appreciated.
Try to replace the sub-query
(select count(*) from rides r where r.ride_status = 'cancelled' and r.id IN (group_concat(rides.id) )) as cancelledRides,
with below to count using SUM and CASE, it will make use of the GROUP BY
SUM(CASE WHEN rides.ride_status = 'cancelled' THEN 1 ELSE 0 END) as cancelledRides
and the same for completedRides
And move to using JOIN instead of implicit joins

MS SQL query with multiple search criteria across rows

I have below table and SQL query written, this query should not return any result but its returning ID = 1 , what is wrong with the SQL query? Can anyone please help?
** Note balance data type is decimal rest are varchar
ID code balance level
1 C 150.00
1 P 40027.42 F
1 P 40027.42 F
select distinct ID from table
(
(code = 'P' and balance = 40027.42 and level = 'F') or
(code = 'C' and balance = 151.00 )
)
group by ID
having count(ID) >=2
If you do not want to count the same code twice, you can use count(distinct code):
select ID
from t
where (code = 'P' and balance = 40027.42 and level = 'F')
or (code = 'C' and balance = 151.00 )
group by ID
having count(distinct code) >=2
If you want to only count a distinct set of values once, you can use a derived table/subquery to select distinct rows:
select ID
from (
select distinct id, code, balance, level
from t
) as s
where (code = 'P' and balance = 40027.42 and level = 'F')
or (code = 'C' and balance = 151.00 )
group by ID
having count(ID) >=2
rextester demo for both: http://rextester.com/LBKO57534

1242 Subquery returns more than 1 row

I got this error, I hope you may help me. I want to show a certain item in a search.
SELECT p.id, p.property_rank, p.pic_numb, p.att_numb, p.confirm, p.finalized ,p.deleted, p.user_id, p.add_date, p.visit_time,p.visit_date,p.sent_numb, p.contact_numb, zip_name, zip_id, p.street, p.sp_featured, p.property_title, p.b_price_unit, p.b_price_si, p.b_price, p.b_price, p.street_no, p.field_54,
p.field_409,
( SELECT `listing_type`.`id`
FROM `res_rpl_listing_types` AS `listing_type`
WHERE `listing_type`.`id` = (
SELECT `listing`.`type`
FROM `res_rpl_listings` AS `listing`
WHERE `listing`.`id` = p.`listing`)
) AS `listing_type_id`,
p.listing, p.googlemap_ln, p.googlemap_lt, p.category, p.b_bedrooms, p.b_bathrooms, p.sp_openhouse, p.b_price_period, p.b_lot_area_unit, p.b_lot_area_si, p.b_lot_area, p.b_lot_area, p.b_living_area_unit, p.b_living_area_si, p.b_living_area, p.b_living_area, p.description, p.sp_hot, p.sp_forclosure
FROM res_rpl_properties AS p
WHERE 1 AND p.`type` = '0' AND p.`confirm` = '1' AND p.`finalized` = '1' AND p.`deleted` = '0' AND p.`category` IN(9,8,10)
ORDER BY p.add_date DESC
LIMIT 0 , 12
The error is telling you that your subquery (selected as listing_type_id) returns more than one row. To rephrase - it's returning more than one value for listing_type_id. You should limit the results from the subquery to just one.
You have two options:
OR select just the first row of subquery
(SELECT `listing_type`.`id`
FROM `res_rpl_listing_types` AS `listing_type`
WHERE `listing_type`.`id` = (
SELECT `listing`.`type`
FROM `res_rpl_listings` AS `listing`
WHERE `listing`.`id` = p.`listing`
LIMIT 1
)
LIMIT 1
) AS `listing_type_id`
OR use IN to allow multiple comparation
(SELECT `listing_type`.`id`
FROM `res_rpl_listing_types` AS `listing_type`
WHERE `listing_type`.`id` IN (
SELECT `listing`.`type`
FROM `res_rpl_listings` AS `listing`
WHERE `listing`.`id` = p.`listing`)
LIMIT 1
) AS `listing_type_id`
The problem is there is 2 subqueries and you need to treat both. Both of them need to be limited to 1 row only.

MySQL Function, must bring back a row

I have this simple MySQL statement:
SELECT
((AVG(q1) + AVG(q8) + AVG(q15)) / 3 ) AS Res
FROM tresults
WHERE id = '1' AND date = 'MARCH2010' AND q25 = '1'
GROUP BY q25
Now, if there are no rows with the date MARCH2010 then the query returns zero results (which is correct) but I'd like it to return a row - even if the result is NULL.
You can just select a single row as a constant, and then left join it to your result set:
select l.*, r.*
from (select "your constant" as constant) as l
left join (
SELECT
((AVG(q1) + AVG(q8) + AVG(q15)) / 3 ) AS Res
FROM tresults
WHERE id = '1' AND date = 'MARCH2010' AND q25 = '1'
GROUP BY q25
) as r on 1
How this works:
select "your constant" as constant always returns a single row
left join always returns all of the rows in the left table at least once
if the right table has no rows, then the entire left table is extended with a bunch of null columns, and the result has one row
if the right table has n rows, the result has n rows that each have an additional "your constant" column
I'm not absolutely positive, but this case statement might work. I can't test it atm.
Case When
(SELECT
Count(*)
FROM tresults
WHERE id = '1' AND date = 'MARCH2010' AND q25 = '1'
GROUP BY q25) > 0
Then
SELECT
((AVG(q1) + AVG(q8) + AVG(q15)) / 3 ) AS Res
FROM tresults
WHERE id = '1' AND date = 'MARCH2010' AND q25 = '1'
GROUP BY q25
Else
SELECT null
End
SELECT
((AVG(q1) + AVG(q8) + AVG(q15)) / 3 ) AS Res
FROM tresults
WHERE id = '1' AND date = 'MARCH2010' AND q25 = '1'
GROUP BY q25
UNION ALL
SELECT NULL AS Res
FROM dual
WHERE NOT EXISTS (
SELECT
((AVG(q1) + AVG(q8) + AVG(q15)) / 3 ) AS Res
FROM tresults
WHERE id = '1' AND date = 'MARCH2010' AND q25 = '1'
GROUP BY q25
)
Will always return one row beacuse of second part.