How to Count Rows from two Tables with one Command in MySQL - mysql

i want to count 2 tables from diferent table, im select the date then i group it.
here what i try
SELECT
(SELECT date(date), COUNT(sh_sh) FROM sh_url GROUP BY date(date)) AS URLs,
(SELECT date(date), COUNT(ip) FROM tracking GROUP BY date(date)) AS IP
FROM dual
but i get error
1241 - Operand should contain 1 column(s)
is that posible to do it in one command?
the output should be like this
date(url) count(sh_sh) date(ip) count(ip)
--------- ------------ ---------- ----------
2018-04-25 123 2018-04-25 123123
2018-04-26 456 2018-04-26 321
2018-04-27 789 2018-04-27 3125

I would phrase your problems using a join of two subqueries:
SELECT
t1.date,
t1.url_cnt,
COALESCE(t2.ip_cnt, 0) AS ip_cnt
FROM
(
SELECT date, COUNT(*) url_cnt
FROM sh_url
GROUP BY date
) t1
LEFT JOIN
(
SELECT date, COUNT(*) ip_cnt
FROM tracking
GROUP BY date
) t2
ON t1.date = t2.date;

When you use a subquery as a value, it can only return one row and one column. You need to use a JOIN:
SELECT urls.date, urls.count AS sh_count, ip.count AS ip_count
FROM (SELECT date(date) AS date, COUNT(*) AS count FROM sh_url GROUP BY date(date)) AS urls
JOIN (SELECT date(date) AS date, COUNT(*) AS count FROM tracking GROUP BY date(date)) AS ip
ON urls.date = ip.date

Related

I want to calculate the sum of last transaction for A&B

Let's say the table looks like this:
user id
date
Amount
123
2022/11/01
5
456
2022/11/02
6
789
2022/11/03
8
123
2022/11/02
9
456
2022/11/04
6
789
2022/11/05
8
I want to calculate the sum of the very last transaction (only one for each user) for A & B FYI I'm using redash and I'm a beginner not sure what other info would you need, I tried MAX but was not sure how to apply it on more than one specific user.
Get the sum of Amount where user is A or B and date is the most recent date for each user
SELECT SUM(AMOUNT) AS total
FROM (
SELECT AMOUNT, ROW_NUMBER() OVER (PARTITION BY USERID ORDER BY DATE DESC) AS RN
FROM tableyoudidnotname
WHERE userid in ('A','B')
) X
WHERE X.RN = 1
You can try this, where we first calculate the maximum date by user in a common-table expression, then join that result-set to the table to sum the associated values.
WITH dat
AS
(
SELECT user_id, MAX(date) AS max_date
FROM credit.card
WHERE user_id IN ('A','B','ETC')
GROUP BY user_id
)
SELECT SUM(value) AS sum_on_max_dates
FROM credit.card t
INNER JOIN dat d ON t.user_id = d.user_id AND t.date = m.max_date;
You can try this, Used join with the subquery I mention below.
SELECT
SUM(t1.amount) AS count
FROM
transaction t1
JOIN
(SELECT
user_id, MAX(date) AS max_date
FROM
transaction
WHERE
user_id IN ('A', 'B')
GROUP BY user_id) t2 ON t1.user_id = t2.user_id
AND t2.max_date = t1.date;

can more than one aggregation functions be used in `select` in case of `group by`?

here is the table:
here is my query
select sum(if(customer_pref_delivery_date = min(order_date), 1, 0)) immidiate_percentage
from Delivery
group by customer_id;
then I get error
Invalid use of group function
Ignore what I want to do logically, I'm wondering why I get this error? when I remove sum from the select it works, so I'm thinking maybe in sql only one aggregation function (like min in this case) be allowed to use in select when doing group by? is that true?
You can't nest aggregations in the select list.
If you want to get the percentage of the orders that need to be delivered at the same day as the order per customer then do this:
select customer_id,
100.0 * avg(customer_pref_delivery_date = order_date) immediate_percentage
from Delivery
group by customer_id;
See the demo.
Results:
| customer_id | immediate_percentage |
| ----------- | -------------------- |
| 1 | 0 |
| 2 | 50 |
| 3 | 50 |
| 4 | 100 |
You cannot nest aggregation functions. It simply doesn't make sense. Each aggregation function produces one value per group -- the value cannot then be compared to the rows that comprise the group in the same select.
I don't think you need any second aggregation for what you are doing:
select customer_id, sum( customer_pref_delivery_date = order_date ) as immediate_percentage
from (select d.*,
min(order_date) over (partition by customer_id) as min_order_date
from Delivery
) d
group by customer_id;
It seems strange that you are calling a sum a "percentage" but that is the logic you have in your query.
If you really want to compare to the minimum order date for each customer, you can use a window function:
select customer_id, sum( customer_pref_delivery_date = min_order_date ) as immediate_percentage
from (select d.*,
min(order_date) over (partition by customer_id) as min_order_date
from Delivery
) d
group by customer_id;
You cannot nest aggregate functions.
One way to work around this would to compute the minimum order date per customer in a subquery, and then join it with the original table, as follows:
select
d.customer_id
sum(if(d.customer_pref_delivery_date = dmin.min_order_date), 1, 0)) immidiate_percentage
from
delivery d
inner join (
select customer_id, min(order_date) min_order_date
from delivery
group by customer_id
) dmin on dmin.customer_id = d.customer_id
group by d.customer_id;
In MySQL 8.0, you can use window functions:
select
d.customer_id,
sum(if(customer_pref_delivery_date = min_order_date), 1, 0)) immidiate_percentage
from (
select
customer_id,
customer_pref_delivery_date,
min(order_date) over(partition by customer_id) min_order_date
from delivery
) t
group by customer_id

How to create list of names of customers who have exceed the number of transactions in day and transaction limit

table 1
'name' 'amount' 'day'
---------------------------------------------
hemanth 10000 2019-06-21
hemanth 1000 2019-06-21
hemanth 5000 2019-06-21
hemanth 10000 2019-07-21
kumar 100 2019-06-21
kumar 5000 2019-06-21
kumar 1000 2019-07-21
kiranmai 10000 2019-06-21
kiranmai 500 2019-07-21
kiranmai 10000 2019-06-21
table 2 contains transcation limit per day & transcation amount limit
tranlimperday transamontlim
--------------------------------------------
3 10000
I am already convert the Date column into Day and month wise but after that we need find the count of transactions in day and sum of amount for thta we need to capmare the month column with month(date) but Im unable to find the query
expect oputput
Name
---------
Hemanth
kiranmai
I would suggest two separate queries and union:
select name
from (select name, day,
sum(amount) as total_amount, count(*) as cnt
from table1
group by name, day
) nd join
table2 t2
on t1.cnt >= t2.tranlimperday
union -- on purpose to remove duplicates
select name
from (select name, year(day) as yyyy, month(day) as mm,
sum(amount) as total_amount, count(*) as cnt
from table1
group by name, year(day), month(day)
) nym join
table2 t2
on t1.total_amount >= t2.transamontlim;
In MySQL 8+, you could also use window functions:
select distinct name
from (select name, day,
sum(amount) as daily_total_amount, count(*) as daily_cnt,
sum(sum(amount)) over (partition by name, year(day), month(day)) as monthly_total_amount,
sum(count(*)) over (partition by name, year(day), month(day)) as monthly_cnt
from table1
group by name, day
) nd join
table2 t2
on t1.daily_cnt >= t2.tranlimperday or
t1.monthly_total_amount >= t2.transamontlim;
If I understand correctly, you are looking for the aggregated results with either crossed daily transaction limit or crossed limit of daily translation amount limit. You can try this below option as well-
SELECT name,Day,
COUNT(1) num_tran,
SUM(amount) tran_amt
FROM Table1
CROSS JOIN Table2
GROUP BY name,Day,YEAR(day),MONTH(Day),DAY(Day)
HAVING COUNT(1) >= MAX(Table2.tranlimperday) -- Considering Single row in the table2
OR SUM(amount) > MAX(Table2.transamontlim) -- Considering Single row in the table2

MYSQL: How to get Maximum and Second Maximum Date in single query

I am trying to select Maximum Date and Second Max Date but can't get success.
This is table data.
ID Country DATE
1 Canada 2016-05-26
2 Canada 2016-05-25
3 Canada 2016-05-24
4 USA 2016-04-02
5 USA 2016-04-01
6 USA 2016-03-20
Expecting Output
Country Max_Date 2nd_Date
Canada 2016-05-26 2016-05-25
USA 2016-04-02 2016-04-01
What I have done so for:
Get Max Date using this query.
select Country, MAX(Date) from tbl GROUP BY (Country);
For Second Max date but failed to get result:
SELECT Country, MAX(date) FROM tbl WHERE Date NOT IN
( select MAX(FROM) from tbl GROUP BY (Country)) GROUP BY (Country)
What should I try to get expected output. Thanks
Or you could try this
SELECT s.Country, Max(s.Date) Max_Date,
(SELECT t.Date
FROM tbl t
Where s.Country=t.Country
ORDER BY Date DESC
LIMIT 1,1) 2nd_Date
FROM tbl s
GROUP BY COUNTRY;
The LIMIT clause is zero based, so using parameters 1,1 skips the first (ie max) value & returns just one value (2nd max).
NOTE - if the max date is duplicated the query will return Max_Date & 2nd_Date as the same value - if that is not what you want, then you can add DISTINCT to the inner query.
No need for nested queries to solve this:
SELECT t1.country, max(t1.date), max(t2.date)
FROM tbl t1
JOIN tbl t2 ON t1.country = t2.country AND t2.date < t1.date
GROUP BY t1.country;
This can be a pain. Here is one method:
select t.country, maxdate, max(t.date) as secondate
from tbl t left join
(select country, max(date) as maxdate
from tbl
group by country
) c
on t.country = c.country and t.date < c.maxdate
group by t.country;
Try this one
Select Country, MAX(Date) As Date From tbl GROUP BY Country Order By Date Desc Limit 2;

Get greatest common value in a column across tables

I have 4 tables (say A, B, C and D) all with the column 'date'. I need to find the greatest common date value across all four tables. That is, the greatest value of date that exists in all four tables. How can I do this?
For now, I'm making do with finding the MIN of the MAX date values of all four tables, but this fails in the cases where the MIN exists in one table but not in the second.
Here is an example to make things clearer :
A.date
------
2015-03-31
2015-03-30
2015-03-29
2015-03-27
B.date
------
2015-03-30
2015-03-29
2015-03-28
2015-03-27
C.date
------
2015-03-29
2015-03-27
2015-03-26
2015-03-25
D.date
------
2015-03-28
2015-03-27
2015-03-26
2015-03-25
What I was doing to find the highest common date was :
SELECT MIN(max_date) FROM (
SELECT MAX(date) AS max_date FROM A
UNION
SELECT MAX(date) AS max_date FROM B
UNION
SELECT MAX(date) AS max_date FROM C
UNION
SELECT MAX(date) AS max_date FROM D
) T;
This gives me 2015-03-28, but then I realized that some tables might not have this date at all. The date I actually want to get is 2015-03-27.
Here is one method:
select date
from (select date, 'a' as which from a union all
select date, 'b' as which from b union all
select date, 'c' as which from c union all
select date, 'd' as which from d
) x
group by date
having count(distinct which) = 4
order by date desc
limit 1;
The following version might perform a bit better, especially if you have an index on date in each table:
select date
from (select distinct date, 'a' as which from a union all
select distinct date, 'b' as which from b union all
select distinct date, 'c' as which from c union all
select distinct date, 'd' as which from d
) x
group by date
having count(*) = 4
order by date desc
limit 1;
You need to get an intersection of all date values across the 4 separate tables. Then, select the MAX of these values:
SELECT MAX(date)
FROM A
WHERE date IN (
SELECT date
FROM B
WHERE date IN (
SELECT date
FROM C
WHERE date IN (
SELECT date
FROM D)))
SQL Fiddle Demo here