I have a table like this
id status
1 Pass
2 Fail
3 Pass
How can I count total rows and rows where status is "Fail" with their id(s) by group_concat in one select query. I am trying to get output like this
total group_concat(id)
3 1,2,3
1 2
Any advice?
you'll need to union two separate queries:
select status,
count(*) as num,
group_concat(id) as ids
from tests as status_stats
union all
select null as status,
count(*) as num,
group_concat(id) as ids
from tests as total_stats
Related
I am doing a selection using GROUP BY, so I get a lot of different rows. What I need is to UPDATE the status field of each row affected by the SELECT query, but it is grouped... so I don't know all the ids, just the MAX(id).
This is the select query:
SELECT d.*, n.* FROM
(SELECT MAX(id) as id, MAX(datetime) as datetime, COUNT(DISTINCT content) as total FROM user_notifications
WHERE id_user
GROUP BY id_ref, type
ORDER BY datetime DESC) d
JOIN user_notifications n USING (id)
Edit:
Simple example, this is the table
id user content status
1 1 aaa 0
2 1 aaa 0
3 1 bbb 0
4 2 aaa 0
5 3 bbb 0
this is the query
select max(id), user, content from table where user=1 group by content
this is the result
id user content
2 1 aaa
3 1 bbb
in this query in fact sql internally select all user=1 (id= 1, 2, 3) and then the query is grouped, showing just two rows.
So, I want to update all ids involved in the query (id= 1 , 2 and 3)
Based on your example, you need the result exact to this query:
select id from `table` where user = 1;
But by using the query you provided which groups record by content
select max(id), user, content from `table` where user = 1 group by content
So, in such case you can join same table with derived table:
select id from `table` as t
join (select max(id), user, content from `table` where user = 1 group by content) as dt
on dt.content = t.content and dt.user = t.user;
This query is now equivalent to first straight forward query.
I am super new to access and having difficulty with a query. My table (tblpacks) is the following:
id user_id group_id quota_id
1 1 1 1
2 1 2 1
3 2 1 1
4 3 1 1
Ideally, what I now is to get hte number of unique users and groups for quota_id=1
The result will be:
total_users = 3
total_groups = 2
If you only wanted to count one field, there would by a simple solution, but since you want to count 2 separate fields, you in fact need at least 2 separate queries.
My answer is to use a UNION query as the source for counting. This UNION query returns the distinct user_id values (with Null as group_id) and the distinct group_id values (with Null as user_id). I omitted the DISTINCT keyword, because UNION (without ALL) does a DISTINCT query automatically. As the datatypes where not recognized correctly when using a constant Null field in the first SELECT statement of the UNION query, I added a third SELECT statement as the first one, which selects both fields from the table but returns no records:
SELECT Count(user_id) AS total_users, Count(group_id) AS total_groups
FROM (
SELECT user_id, group_id FROM tblpacks WHERE Yes=No
UNION
SELECT user_id, Null FROM tblpacks WHERE quota_id=1
UNION
SELECT Null, group_id FROM tblpacks WHERE quota_id=1
) AS qsub;
id class count day
1 2 5 5
2 2 4 5
3 2 4 5
3 2 4 5
4 2 5 3
4 1 5 3
4 2 5 3
So I have a query for finding all duplicates based on multiple columns, however, this also returns id's where not all entries are duplicate.
In above example, the query should only show/count id 3, as all the entries with id 3 are duplicate. Even though id 4 also has a duplicate, it should not show as it has another entry that is unique.
Any idea how to do this?
If you need rows with id where there is no row with the same id and unique row values then use NOT IN and HAVING
select *
from your_table t1
where t1.id not in(
select id
from your_table
group by id, class, count, day
having count(*) = 1
)
You can use this query : http://sqlfiddle.com/#!9/1a2536/8
select id
from test
group by id
having count(distinct id,class,count,day) = 1 and count(*)>1
you group each rows by id and count how many different row the group has, if the distinct total is 1 and the total row is > 1 , there is only duplicate rows for this id.
It's quite easy, a quick note it's a very bad idea to name a column count :
SELECT id, class, `count`,day, COUNT(*)
FROM myTable
GROUP BY id, class, `count`,day
HAVING COUNT(*) > 1
edit : I misread the question so here is my solution :
SELECT test.id, test.class, test.count, test.day , count(*), t.countID
FROM (SELECT id, Count(id) AS countID FROM test GROUP BY id ) t
INNER JOIN test on t.id = test.id
GROUP BY test.id, test.class, test.count, test.day
HAVING Count(*) > 1 AND t.countID = count(*)
I came up with this :
SELECT *
FROM (SELECT id,
Count(id) AS matched
FROM test
GROUP BY id,
class,
count,
day) t
GROUP BY id , matched
HAVING Count(id) = 1
AND matched >= 2
There is maybe a more efficient way to do it but it is easier to understand this way, first we group by every column to find duplicate data. Then the first part of the having eliminates the entries that actually have different variants by id and then we keep only the lines that actually only have duplicates.
Edit : compatible with "only_full_group_by" mode
Could you help me with simple table SUM and COUNT calculating?
I've simple table 'test'
id name value
1 a 4
2 a 5
3 b 3
4 b 7
5 b 1
I need calculate SUM and Count for "a" and "b". I try this sql request:
SELECT name, SUM( value ) AS val, COUNT( * ) AS count FROM `test`
result:
name val count
a 20 5
But should be
name val count
a 9 2
b 11 3
Could you help me with correct sql request?
Add GROUP BY. That will cause the query to return a count and sum per group you defined (in this case, per name).
Without GROUP BY you just get the totals and any of the names (in your case 'a', but if could just as well have been 'b').
SELECT name, SUM( value ) AS val, COUNT( * ) AS count
FROM `test`
GROUP BY name
You need group by
select
name,
sum(value) as value,
count(*) as `count`
from test group by name ;
I have table with, folowing structure.
tbl
id name
1 AAA
2 BBB
3 BBB
4 BBB
5 AAA
6 CCC
select count(name) c from tbl
group by name having c >1
The query returning this result:
AAA(2) duplicate
BBB(3) duplicate
CCC(1) not duplicate
The names who are duplicates as AAA and BBB. The final result, who I want is count of this duplicate records.
Result should be like this:
Total duplicate products (2)
The approach is to have a nested query that has one line per duplicate, and an outer query returning just the count of the results of the inner query.
SELECT count(*) AS duplicate_count
FROM (
SELECT name FROM tbl
GROUP BY name HAVING COUNT(name) > 1
) AS t
Use IF statement to get your desired output:
SELECT name, COUNT(*) AS times, IF (COUNT(*)>1,"duplicated", "not duplicated") AS duplicated FROM <MY_TABLE> GROUP BY name
Output:
AAA 2 duplicated
BBB 3 duplicated
CCC 1 not duplicated
For List:
SELECT COUNT(`name`) AS adet, name
FROM `tbl` WHERE `status`=1 GROUP BY `name`
ORDER BY `adet` DESC
For Total Count:
SELECT COUNT(*) AS Total
FROM (SELECT COUNT(name) AS cou FROM tbl GROUP BY name HAVING cou>1 ) AS virtual_tbl
// Total: 5
why not just wrap this in a sub-query:
SELECT Count(*) TotalDups
FROM
(
select Name, Count(*)
from yourTable
group by name
having Count(*) > 1
) x
See SQL Fiddle with Demo
The accepted answer counts the number of rows that have duplicates, not the amount of duplicates. If you want to count the actual number of duplicates, use this:
SELECT COALESCE(SUM(rows) - count(1), 0) as dupes FROM(
SELECT COUNT(1) as rows
FROM `yourtable`
GROUP BY `name`
HAVING rows > 1
) x
What this does is total the duplicates in the group by, but then subtracts the amount of records that have duplicates. The reason is the group by total is not all duplicates, one record of each of those groupings is the unique row.
Fiddle: http://sqlfiddle.com/#!2/29639a/3
SQL code is:
SELECT VERSION_ID, PROJECT_ID, VERSION_NO, COUNT(VERSION_NO) AS dup_cnt
FROM MOVEMENTS
GROUP BY VERSION_NO
HAVING (dup_cnt > 1 && PROJECT_ID = 11660)
I'm using this query for my own table in PHP, but it only gives me one result whereas I'd like to the amount of duplicate per username, is that possible?
SELECT count(*) AS duplicate_count
FROM (
SELECT username FROM login_history
GROUP BY username HAVING COUNT(time) > 1
) AS t;