I'm having trouble joining two tables that come from two queries, meaning I don't have the actual table in my database. I have the following:
SELECT
fiscalYear,
BidOwner,
count(cbid) AS c
FROM
financials_tbl
GROUP BY
BidOwner,
fiscalYear
that one brings each BidOwner for each year with the amounts of bids he/she did that year.
Now this one:
SELECT
fiscalYear,
max(c)
FROM
(
SELECT
fiscalYear,
BidOwner,
count(cbid) AS c
FROM
financials_tbl
GROUP BY
BidOwner,
fiscalYear
) InputTable
GROUP BY
fiscalYear
brings the maximum amount of bids done by an employee that year (2 columns).
What I need is to join this last table with the corresponding bid owner from the previous one, like a vlookup to find who scored the max amount of deals each year shown in the second table.
It looks like you are trying to find a groupwise maximum on the result of your count query. Unfortunately, I do not know a way to do this without creating two of the same subquery, but I think this should work.
SELECT
t1.fiscalYear, t1.BidOwner, t1.c
FROM
(SELECT fiscalYear, BidOwner, count(cbid) AS c
FROM financials_tbl
GROUP BY BidOwner, fiscalYear) t1
LEFT JOIN
(SELECT fiscalYear, BidOwner, count(cbid) AS c
FROM financials_tbl
GROUP BY BidOwner, fiscalYear) t2
ON t1.fiscalYear = t2.fiscalYear AND t1.c < t2.c
WHERE t2.BidOwner IS NULL
You can join the results in such way:
SELECT
t2.fiscalYear,
t2.BidOwner,
t2.c
FROM (
SELECT
fiscalYear,
max(c) as max
FROM
(
SELECT
fiscalYear,
BidOwner,
count(cbid) AS c
FROM
financials_tbl
GROUP BY
BidOwner,
fiscalYear
) InputTable
GROUP BY
fiscalYear
) t1
JOIN (
SELECT
fiscalYear,
BidOwner,
count(cbid) AS c
FROM
financials_tbl
GROUP BY
BidOwner,
fiscalYear
) t2
ON t2.max = t1.c
AND t2.fiscalYear = t1.fiscalYear;
However performance of such query will not be nice for large data sets...
Related
I am trying to join two tables and get the count and grouped by specific field. However, it outputs same count values even if the other table consist only two rows. How should I fix this?
Here's my code:
SELECT tbl1.preferredDay, COUNT(tbl1.preferredDay) as count_1, COUNT(tbl2.preferredDay) as count_2
FROM tblschedule as tbl1
LEFT JOIN tblappointments as tbl2 ON (tbl1.preferredDay = tbl2.preferredDay)
WHERE tbl1.preferredDay = tbl2.preferredDay
GROUP BY preferredDay;
Here is the output but it should be [15, 0][3, 3]
Your query is based on left join it will return the same count().
This is a working query for Mysql 8:
with tbl1 as (
SELECT preferredDay, count(1) as count_1
FROM tblschedule
GROUP BY preferredDay
),
tbl2 as (
SELECT preferredDay, count(1) as count_2
FROM tblappointments
GROUP BY preferredDay
)
select t1.preferredDay, t1.count_1, t2.count_2
from tbl1 t1
inner join tbl2 t2 on t1.preferredDay = t2.preferredDay
There are two WITHs to get separately the count and then an INNER JOIN to join those results
For Mysql 5.7 and lower :
select t1.preferredDay, t1.count_1, t2.count_2
from (
SELECT preferredDay, count(1) as count_1
FROM tblschedule
GROUP BY preferredDay
) as t1
inner join (
SELECT preferredDay, count(1) as count_2
FROM tblappointments
GROUP BY preferredDay
) as t2 on t1.preferredDay = t2.preferredDay
I have 2 tables
Table1
Year,Month, data
2017,1,2
2018,2,10
Table2
Year,Month,data2
2017,1,5
2019,2,2
I am trying to consolidate the tables into 1 tables where we get all rows from both tables as follows.
Year,Month,data,data2
2017 ,1,2,5
2018,2,10,NULL
2019,2,NULL,2
It seems like standard outer joins will not work here and I can't use Union ALL either
Is there some kind of Outer join query to accomplish this?
You should use a UNION for obtain allthe year and month from both tables and use left join for relate this to table1 and table2
select a.Year , a.Month, b.data, c.data2
from (
select Year,Month
from Table1
union
select Year,Month
from Table2
) a
left join table1 b on a.Year = b.Year and a.month = b. month
left join table2 c on a.Year = c.Year and a.month = c. month
What you really want is a full join. One method that often works is union all and group by:
select year, month, max(data) as data, max(data2) as data2
from ((select year, month, data, null as data2
from table1
) union all
(select year, month, null, data2
from table2
)
) t
group by year, month;
I was not sure how to phrase my question as I am new to SQL. It should not be too hard. Here is the scenario.
I have 3 tables:
customers
id,
contact
subscribers_from_x
customer_id
subscriber_name
subscribers_from_y
customer_id,
subscriber_name
here is the question:
Now, I want to select
customer.id
the number of times/count of customer.id occurs in subscribers_from_x
the number of times/count of customer.id occurs in subscribers_from_y
from these 3 tables
I have tried GROUP_BY COUNT(*) but not figuring it out. THanks
I might go with using two separate subqueries which aggregate counts by subscriber for the x and y tables:
SELECT t1.id,
t1.contact,
COALESCE(t2.x_count, 0) AS subscribers_from_x,
COALESCE(t3.y_count, 0) AS subscribers_from_y
FROM customers t1
LEFT JOIN
(
SELECT customer_id, COUNT(*) AS x_count
FROM subscribers_from_x
GROUP BY customer_id
) t2
ON t1.id = t2.customer_id
LEFT JOIN
(
SELECT customer_id, COUNT(*) AS y_count
FROM subscribers_from_y
GROUP BY customer_id
) t3
ON t1.id = t3.customer_id
SELECT DISTINCT(users.id),count(x.customer_id) 'X count',count(y.customer_id) 'Y Count'
FROM customers
LEFT JOIN subscribers_from_x x ON customers.id = x.customer_id
LEFT JOIN subscribers_from_y y ON customers.id = y.customerid
GROUP BY customers.id,subscribers_from_x.pk_col -- primary key col of subscribers_from_x
It will give you required output
I need help getting the top 5 results and their counts from columns from two different tables in a mysql database joined together.
table1 cols
-------
id, country, timestamp
table2 cols
--------
id, table1_id, reason
The results id like to get are the top 5 countries and their number of times found between two timestamps, and the top 5 reasons and their counts for all the rows used to generate the first count. There is a one to many relationship between table1 and table2. This is stumping me and I appreciate any insight you could give me.
It's not entirely clear what resultset you want to return.
This may be of some help to you:
SELECT t.country
, COUNT(DISTINCT t.id) AS count_table1_rows
, COUNT(r.id) AS count_table2_rows
, COUNT(*) AS count_total_rows
FROM table1 t
LEFT
JOIN table2 r
ON r.table1_id = t.id
WHERE t.timestamp >= NOW() - INTERVAL 7 DAY
AND t.timestamp < NOW()
GROUP BY t.country
ORDER BY COUNT(DISTINCT t.id) DESC
LIMIT 5
That will return a maximum of 5 rows, one row per country, with counts of rows in table1, counts of rows found in table2, and a count of the total rows returned.
The LEFT keyword specifies an "outer" join operation, such that rows from table1 are returned even if there are no matching rows found in table2.
To get the count for each "reason", associated with each country, you could do something like this:
SELECT t.country
, COUNT(DISTINCT t.id) AS count_table1_rows
FROM table1 t
LEFT
JOIN ( SELECT s.country
, r.reason
, COUNT(*) AS cnt_r
FROM table1 s
JOIN table2 r
ON s.table1_id = t.id
WHERE s.timestamp >= NOW() - INTERVAL 7 DAY
AND s.timestamp < NOW()
GROUP
BY s.country
, r.reason
) u
ON u.country = t.country
WHERE t.timestamp >= NOW() - INTERVAL 7 DAY
AND t.timestamp < NOW()
GROUP
BY t.country
, u.reason
ORDER
BY COUNT(DISTINCT t.id) DESC
, t.country DESC
, u.cnt_r DESC
, u.reason DESC
This query doesn't "limit" the rows being returned. It would be possible to modify the query to have only a subset of the rows returned, but that can get complex. And before we muck the complexity of adding "top 5 within top 5" type limits, we want to ensure that the rows returned by a query are a superset of the rows we actually want.
Is this what you want?
select t2.reason, count(*)
from (select t1.country, count(*)
from table1 t1
where timestamp between #STARTTIME and #ENDTIME
group by country
order by count(*) desc
limit 5
) c5 join
table1 t1
on c5.country = t1.country and
t1.timestamp between #STARTTIME and #ENDTIME join
table2 t2
on t2.table1_id = t1.id
group by t2.reason;
The c5 subquery gets the five countries. The other two bring back the data for the final aggregation.
Lets say i have two tables
Table1:
product_id, design1, design2
1 A C
2 B A
Table2:
product_id, value
1 10
2 10
Now i want to to sum all the value for particular design for all products.
SELECT designA, SUM(value) FROM (
SELECT b.design1 AS designA, SUM(value) AS value FROM table2 AS a LEFT JOIN table1 AS b ON a.product_id = b.product_id GROUP BY b.design1) AS T GROUP BY designA
It gives me this:
designA SUM(value)
A 10
B 10
Now the problem is that if user has specified design2 in table1 then what ever is the value of design1 will automatically be added in design2. If design2 is not present design1 column then it will be a new row of result:
Desited result is this:
designA SUM(value)
A 20
B 10
C 10
select y.designA, sum(value) from
(select a.design1 as designA, value from
Table1 as a
inner join Table2 as b
on
a.product_id = b.product_id
union all
select a.design2 as designA, value from
Table1 as a
inner join Table2 as b
on
a.product_id = b.product_id) as y
group by y.designA
seems to work for your test data, not tried on other configurations but you should be able to tweak it, if you understand what it's doing.
UNION in the matches based on design2:
SELECT designA, SUM(value) FROM (
SELECT b.design1 AS designA, SUM(value) AS value FROM table2 AS a LEFT JOIN table1 AS b ON a.product_id = b.product_id GROUP BY b.design1
UNION
SELECT b.design2 AS designA, SUM(value) AS value FROM table2 AS a LEFT JOIN table1 AS b ON a.product_id = b.product_id GROUP BY b.design2
) AS T GROUP BY designA