Summing union of counts in a correlated subquery - mysql

I have a member table that has a foreign key to various other tables. I am checking each of these tables to see if a member has one or more records in it and if they do I return a value, if not I return 0, this is all selected as a total. This is mostly working except in one place. I need to check two tables and if there is a record in either of them the query will return 5,0 otherwise. I am trying to use a SUM of counts with a UNION for this but I am not getting the results I expect, it seems like only the first record in each of the two tables is being selected and that is it.
I am using(after some help ) a series of correlated queries with COUNT() and IF() to get the total. Here is what part of the query looks like :
SELECT
member_id,
(SELECT IF(COUNT(member_id)>0,10,0) FROM tbl1 WHERE member_id = m.member_id)
+
(SELECT IF(SUM(tbl_count) > 0,5,0) FROM
(
SELECT member_id, COUNT(tbl2.id) as tbl_count
FROM tbl2
UNION ALL
SELECT member_id, COUNT(tbl3.id) as tbl_count
FROM tbl3
) sub WHERE sub.member_id = m.member_id
)
as total
FROM members m
The actual query joins another 10 or so tables, again the only part that is not working is the SUM of COUNT with the UNION. Could anyone suggest how I should do this? Any help would be very much appreciated. Thank you very much.

I think you are looking for this:
First try (FAIL)
SELECT
member_id,
(SELECT IF(COUNT(member_id)>0,10,0) FROM tbl1 WHERE member_id = m.member_id)
+
(SELECT IF(SUM(tbl_count) > 0,5,0) FROM
(
SELECT COUNT(*) as tbl_count
FROM tbl2
WHERE tbl2.member_id = m.member_id
UNION ALL
SELECT COUNT(*) as tbl_count
FROM tbl3
WHERE tbl3.member_id = m.member_id
) sub
)
as total
FROM members m
Second try:
SELECT
member_id,
(SELECT IF(COUNT(member_id)>0,10,0) FROM tbl1 WHERE member_id = m.member_id)
+
(SELECT IF(SUM(tbl_count) > 0,5,0) FROM
(
SELECT member_id, COUNT(*) as tbl_count
FROM tbl2
GROUP BY member_id
UNION ALL
SELECT member_id, COUNT(*) as tbl_count
FROM tbl3
GROUP BY member_id
) sub
WHERE sub.member_id = m.member_id
)
as total
FROM members m
If the query has 10 joins maybe you have to think about refactoring... :-)

Related

Is it possible in mysql to display the sum of two count() results obtained from two different "group by" criteria on the same table?

I have the data table as follows
GameTable
And this is the result i need
ResultTable
I tried this but iit wouldn't work
(
(select count() from game group by team_1)
+
(select count() from game group by team_2)
)
Use union all:
select Team_id, sum(Game_count) as 'Game_count'
from (
select Team_1 as 'Team_id', count(*) as 'Game_count'
from games
group by Team_1
union all
select Team_2, count(*)
from games
group by Team_2
) as q
group by Team_id

MySQL take rows and override ones without user_id

I have table like this one:
I would like to all rows, but if there is user_id 5 if this case, override other rows which have no user_id.
I tried both with MAX(user_id) and GROUP BY country_name, but it still returns, wrong results.
Final result I'm expecting:
Try this;)
select t1.*
from yourtable t1
inner join (
select max(user_id) as user_id, country_name from yourtable group by country_name
) t2 on t1.country_name = t2.country_name and t1.user_id = t2.user_id
This is just a solution based on your sample data. If you have a variety of user_id, it should be more different.
As of SQL Select only rows with Max Value on a Column you can easily get rows with max value on a column by using both MAX(column) and GROUP BY other_column in one statement.
But if you want to select other columns too, you have to this in a subquery like in the following example:
SELECT a.*
FROM YourTable a
INNER JOIN (
SELECT country_name, MAX(user_id) user_id
FROM YourTable
GROUP BY country_name
) b ON a.country_name = b.country_name AND a.user_id = b.user_id

How to select * from table when group by?

select
OrderNo,
Sum(QtyIn) as QuantityIn,
Sum(QtyOut) as QuantityOut
from
tbl_Assign
group by
OrderNo
I want to select * from table also group by from table. How to do it?
To group by on all columns with a sum you cannot use *, you have to list all of the columns out and every column that isn't a function like Sum must be included in the group by.
So if you have other fields in your database such as OrderName, OrderedBy you can perform a group by like this:
Select
OrderNo,
OrderName,
OrderBy,
Sum(QtyIn) as QuantityIn,
Sum(QtyOut) as QuantityOut
From
tbl_Assign
Group By
OrderNo, OrderName, OrderBy
The following will create one row for every row in the tbl_Assign.
Each row will also show the summary information for the order.
This might not be what you need, but it's useful to understand it anyway.
SELECT T1.*, T2.*
FROM
( select * FROM tbl_Assign ) AS T1
LEFT JOIN ( select
OrderNo,
Sum(QtyIn) as QuantityIn,
Sum(QtyOut) as QuantityOut
from
tbl_Assign
group by
OrderNo
) AS T2
ON T1.OrderNo = T2.OrderNo
Harvey

MySQL slow on subquery

This following query take 1-2 seconds for querying.
SELECT updated, COUNT( * ) count
FROM v2_subscription
WHERE ss_id IN (SELECT MAX(ss_id) ss_id FROM v2_subscription GROUP BY uid, card_id)
while the subquery do take only few milliseconds.
SELECT MAX(ss_id) ss_id FROM v2_subscription GROUP BY uid, card_id
I do have index on uid, card_id and both uid, card_id
It's my sql and i have no idea how to optimize this.
Please advise,
Try this, May be it would help, let me know, if it does.
SELECT a.updated, COUNT( * ) count
FROM v2_subscription a
inner join v2_subscription b
on a.ss_id = max(b.ss_id)
GROUP BY b.uid, b.card_id
Or perhaps this
SELECT a.updated, COUNT( * ) count
FROM v2_subscription a
inner join v2_subscription b
on a.ss_id = (SELECT MAX(b.ss_id) b.ss_id FROM v2_subscription b GROUP BY b.uid, b.card_id)
Finally i have found the solution beside #arkumar above answer.
Adding "ORDER BY ss_id" inside the subquery also do the trick
Since without order by, the result of subquery do not have index.

How to select the MAX from the COUNT in SQL

That is a picture of my table.
I must select "Fastanumer" of all cars where "Tegund" is the most common value (which is Toyota in this example)
This is the code i tried
SELECT Fastanumer FROM `Bill`
WHERE Tegund =
(SELECT MAX(y.cnt) FROM (SELECT COUNT(Tegund) AS cnt FROM Bill ) AS y)
Which i had to work pretty hard to figure out only to end up beating myself in the head over the fact that MAX will only turn into a number. (And since Tegund isn't a list of numbers...)
Is this even possible? How can i do this?
I guess it should work this way:
SELECT Fastanumer
FROM `Bill`
WHERE Tegund = (
SELECT Tegund
FROM (
SELECT Tegund,COUNT(*) FROM Bill GROUP BY Tegund ORDER BY COUNT(*) DESC LIMIT 1
) t1
)
Or even like this:
SELECT Fastanumer
FROM `Bill`
WHERE Tegund = (
SELECT Tegund FROM Bill GROUP BY Tegund ORDER BY COUNT(*) DESC LIMIT 1
)
Here's my solution:
SELECT Bill.*
FROM Bill
WHERE Tegund IN (
SELECT Tegund
FROM Bill
GROUP BY Tegund
HAVING COUNT(*) = (
SELECT MAX(cnt) FROM (
SELECT COUNT(*) cnt
FROM Bill
GROUP BY Tegund
) s
)
)
A little more complicated than others, but if more than one Tegund shares the same number of rows, this query will show all Tegunds which are the most common.
Please see fiddle here or here.
What you want to do first is figure out which Tegund appears the most in your table. That is what the subquery is doing. Then you will select the Fastanumer which matches that Tegund.
SELECT DISTINCT Fastanumer
FROM 'BILL'
WHERE Tegund = (
SELECT TOPT 1 Tegund,
COUNT(*) as Count
FROM `BILL`
GROUP BY Tegund
ORDER BY Count DESC)
Depends on the DB (and associated SQL). Try
select fastanumber from bill
inner join
(select count(*) as cnt, tegund from Bill group by tegund) grpby
on bill.tegund = grpby.tegund
and grpby.cnt = (select max(cnt) from (select count(*) as cnt, tegund from Bill group by tegund))