Subconsultation in MySQL - mysql

How to do this subquery I started doing it with IN but I was investigating and changed it to INNER JOIN but it still makes me wrong.
SELECT DISTINCT
TIMESTAMPDIFF (YEAR, date_nac, CURDATE ()) AS age
FROM patient
WHERE date_nac
INNER JOIN (
select count(patient id) as Quantity
from patient
group by age
order by Quantity desc limit 6
);
Show me this error:
Error Code: 1235. This version of MariaDB doesn't yet support 'LIMIT &
IN/ALL/ANY/SOME subquery'

Assuming that your syntax for calculating age is correct, you can use something like this:
Select age, count(age)
From
(SELECT distinct patient_id, TIMESTAMPDIFF(YEAR, date_nac, CURDATE ()) AS age
FROM patient
) a
Group by age;

You can just use aggregation:
select
timestampdiff(year, date_nac, current_date) age,
count(distinct patient_id) no_patients
from patient
group by age
order by no_patients desc
If there are no duplicate patient_ids in the patient table (as it should be), you can use count(*) instead of the more expensive count(distinct patient_id).
I am speculating that you want the top 6 most populated ages only: if so, you can just add limit 6 t the end of the query.

Related

How to count a field per day and then GROUP BY YEARWEEK

If i have a database with 2 columns, date and account and i want to first count account per day and then group by week. How wrong is my code and how to do it?
I edited my code a little bit, i was not thinking right from the beginning. I want the sum to be 9 for week 48.
SELECT date, account,
(SELECT date, COUNT(DISTINCT account)
FROM t1
GROUP BY date
) AS sum
FROM t1
GROUP BY YEARWEEK(date)
You seem to be looking for a simple aggregate query with count(distinct ...):
select yearweek(date) year_week, count(distinct account) cnt_account
from t1
group by yearweek(date)
order by year_week
Note: yearweek() gives you the year and week; this is better than week(), if your data spreads over several years.
EDIT
From the comments, you need two levels of aggregation:
select yearweek(dy) year_week, sum(cnt) cnt_account
from (
select date(t1.date) dy, count(distinct t1.account) cnt
from t1
group by date(t1.date)
) t
group by yearweek(dy)
order by year_week

Sum up grouped values with MySql

I have the following problem:
I have this query:
SELECT DATE(timestamp) Date, COUNT(DISTINCT ipNum) as totalCount
FROM tableName
GROUP BY DATE(timestamp)
I get a result like this:
Date totalCount
1.1. 7
2.1. 19
I need just the sum of all totalCount values. Is this possible with MySql?
I googled a lot (Link1, Link2, Link3) but nothing really answers my question.
I created a fiddle to illustrate my case: http://sqlfiddle.com/#!2/e4fd9/22
The trick is to use a derived table like this:
SELECT SUM(amount)
FROM (
SELECT COUNT(DISTINCT ipNum) as amount, DATE(timestamp)
FROM tableName
GROUP BY DATE(timestamp)
) x

How to Group a table and get results for a row based on the previous rows' data

I have a lookup table that relates dates and people associated with those dates:
id, user_id,date
1,1,2014-11-01
2,2,2014-11-01
3,1,2014-11-02
4,3,2014-11-02
5,1,2014-11-03
I can group these by date(day):
SELECT DATE_FORMAT(
MIN(date),
'%Y/%m/%d 00:00:00 GMT-0'
) AS date,
COUNT(*) as count
FROM user_x_date
GROUP BY ROUND(UNIX_TIMESTAMP(created_at) / 43200)
But, how can get the number of unique users, that have now shown up previously? For instance this would be a valid result:
unique, non-unique, date
2,0,2014-11-01
1,1,2014-11-02
0,1,2014-11-03
Is this possibly without having to rely on a scripting language to keep track of this data?
I think this query will do what you want, at least it seems to work for your limited sample data.
The idea is to use a correlated sub-query to check if the user_id has occurred on a date before the date of the current row and then do some basic arithmetic to determine number of unique/non-unique users for each date.
Please give it a try.
select
sum(u) - sum(n) as "unique",
sum(n) as "non-unique",
date
from (
select
date,
count(user_id) u,
case when exists (
select 1
from Table1 i
where i.user_id = o.user_id
and i.date < o.date
) then 1 else 0
end n
from Table1 o
group by date, user_id
) q
group by date
order by date;
Sample SQL Fiddle
I didn't include the id column in the sample fiddle as it's not needed (or used) to produce the result and won't change anything.
This is the relevant question: "But, how can get the number of unique users, that have now shown up previously?"
Calculate the first time a person shows up, and then use that for the aggregation:
SELECT date, count(*) as FirstVisit
FROM (SELECT user_id, MIN(date) as date
FROM user_x_date
GROUP BY user_id
) x
GROUP BY date;
I would then use this as a subquery for another aggregation:
SELECT v.date, v.NumVisits, COALESCE(fv.FirstVisit, 0) as NumFirstVisit
FROM (SELECT date, count(*) as NumVisits
FROM user_x_date
GROUP BY date
) v LEFT JOIN
(SELECT date, count(*) as FirstVisit
FROM (SELECT user_id, MIN(date) as date
FROM user_x_date
GROUP BY user_id
) x
GROUP BY date
) fv
ON v.date = fv.date;

MySQL: Count the distinct rows per day including 0

Thereis a good answer to the main question here: MySQL: Count the distinct rows per day
I need it with the days with values also included but the query
SELECT DATE(timestamp) Date, COUNT(DISTINCT ipNum) totalCOunt
FROM tableName
WHERE totalCOunt < 1
GROUP BY DATE(timestamp)
gives an error ( #1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'WHERE totalCOunt < 1
LIMIT 0, 25' at line 3 ). Where did I go wrong?
Sample data here: http://sqlfiddle.com/#!2/11aa6/146
It is throwing Unknown column 'totalCOunt' in 'where clause' error:
Please try the below query(replaced WHERE clause with HAVING clause):
SELECT DATE(timestamp) Date, COUNT(DISTINCT ipNum) totalCOunt
FROM tableName
GROUP BY DATE(timestamp)
HAVING totalCOunt<1
You have a few errors:
Date should be escaped, as it is a keyword in MySQL.
The syntax is wrong. You forgot AS.
So the corrected one is:
SELECT CAST(`timestamp` AS Date) AS `Date`, COUNT(DISTINCT(`ipNum`)) AS totalCOunt
FROM `tableName`
GROUP BY CAST(`timestamp` AS Date)
Fiddle: http://sqlfiddle.com/#!2/809838/8
You can't use an alias in the WHERE clause
SELECT DATE(timestamp) Date, COUNT(DISTINCT ipNum) totalCOunt
FROM tableName
WHERE totalCOunt < 1
GROUP BY DATE(timestamp)
Use HAVING instead:
SELECT DATE(timestamp) Date, COUNT(DISTINCT ipNum) totalCOunt
FROM tableName
GROUP BY DATE(timestamp)
HAVING totalCOunt =1

conversion mysql to postgresql

I have a working mysql query, but I can not get it work with postgres. This is the query (I already changed date format to to_char
SELECT country as grouper, date(users.created_at) as date,
to_char(users.created_at, '%Y-%m') as date_group,
count(id) as total_count
FROM "users"
WHERE (users.created_at >= '2011-12-01')
AND (users.created_at <= '2014-02-11')
GROUP BY grouper, date_group
ORDER BY date ASC
I am getting the error:
PG::Error: ERROR: column "users.created_at" must appear in the GROUP BY clause or be used in an aggregate function
LINE 1: SELECT country as grouper, date(users.created_at) as date, t...
Thank for your help.
SELECT country as grouper, date(MIN(users.created_at)) as date,
to_char(MIN(users.created_at), '%Y-%m') as date_group,
count(id) as total_count
FROM "users"
HAVING (users.created_at >= '2011-12-01')
AND (users.created_at <= '2014-02-11')
GROUP BY grouper, date_group
ORDER BY date ASC
MySQL is not very strict. In standard conform SQL all column values have to use an aggrate function (SUM, COUNT, MAX, MIN) on non-grouping fields - when using GROUP BY.
Honestly said, I am not entirely sure about data_group in the GROUP BY; can it be dropped?
Also note that I have switched WHERE with a HAVING.
You should use every selected column in GROUP BY section.
SELECT country as grouper, to_char(created_at, '%Y-%u') as date_group, count(id) as total_count
FROM "users"
WHERE created_at >= '2013-10-01'
AND created_at <= '2014-02-11'
GROUP BY grouper, date_group
ORDER BY date_group ASC