Is it wrong to have count(*) as part of the select query - mysql

select id, first_name, count(*) from users;
The users table contains 10 entries, but the above select query shows only a single row. Is it wrong to mix count(*) as part of the above query?

COUNT is a function that aggregates. You can't mix it into your normal query.
If you want to receive the ten entries just do a normal select:
SELECT id, name FROM users;
and to get the number of entries:
SELECT COUNT(id) FROM users;

Its becuase you are using an aggregate function in the select part of the query,
to return the 10 records you just need the id, and first_name in the query.
EG:
SELECT id, first_Name
FROM users
if you wanted to get a count of the records in the table then you could use
SELECT (Count(id))
FROM [users]

It's not "wrong", but it is meaningless without a "group by" clause - most databases will reject that query, as aggregate functions should include a group by if you're including other columns.

Not sure exactly what you're trying to achieve with this?
select id, first_name,(select count(*) from users) AS usercount from users;
will give each individual user and the total count but again, not sure why you would want it.

select id, first_name from users,(select count(*) as total from users) as t;

COUNT is an aggregate function and it will always give you count of all records in table unless used in combination with group by.
If you use it in combination with normal query, then it will take priority in deciding the final output as in your case it returns 1.
If you want to return all 10 records, you should just write -
select id,first_name from users

If you need number of rows in a table, you can use MySQL's SQL_CALC_FOUND_ROWS clause. Check MySQL docs to see how it's used.

Related

GROUP BY clause in MySQL groups records with different values

MySQL GROUP BY clause groups records even when they have different values.
However I would like it to as with DB2 SQL so that if records not contain exactly the same information they are not grouped.
Currently in MySQL for:
id Name
A Amanda
A Ana
the Group by id would return 1 record randomly (unless aggregation clauses used of course)
However in DB2 SQL the same Group by id would not group those: returning 2 records and never doing such a thing as picking randomly one of the values when grouping without using aggregation functions.
First, id is a bad name for a column that is not the primary key of a table. But that is not relevant to your question.
This query:
select id, name
from t
group by id;
returns an error in almost any database other than MySQL. The problem is that name is not in the group by and is not the argument of an aggregation function. The failure is ANSI-standard behavior, not honored by MySQL.
A typical way to write the query is:
select id, max(name)
from t
group by id;
This should work in all databases (assuming name is not some obscure type where max() doesn't work).
Or, if you want each name, then:
select id, name
from t
group by id, name;
or the simpler:
select distinct id, name
from t;
In MySQL, you can get the ANSI standard behavior by setting ONLY_FULL_GROUP_BY for the database/session. MySQL will then return an error, as DB2 does in this case.
The most recent versions of MySQL have ONLY_FULL_GROUP_BY set by default.
Group by in mysql will group the records according to the set fields. Think of it as: It gets one and the others will not show up. It has uses, for example, to count how many times that ID is repeated on the table:
select count(id), id from table group by id
You can, however, to achieve your purpose, group by multiple fields, something among the lines of:
select * from table group by id, name
I do not think there is an automated way to do this but using
GROUP BY id, name
Would give you the solution you are looking for

Database query select all columns including count with every record by 'group by'

Use Criteria or HQL(Hibernate Query Language), select all columns. Grouping by any one column of selected columns and also select count with every record for which we use group by.
Sample SQL Query ex: select *,count(1) from users group by name
Have you try run that SQL of yours? you can't run this query right?
select *,count(1) from users group by name
you will recheive some error like:
Column 'some_column_name' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
what you can is query something like this:
select name, count(name) from users group by name
In this case you can use projection in your criteria to count with group by, something like :
criteria.setProjection(Projections.projectionList()
.add(Projections.groupProperty("name"))
.add(Projections.count("name")));

Return all records in a table with count > 1 for specific field in mysql

I know how to count records in a table based on a distinct value in a field but I am trying now to return all the records in the table that have duplicate values in a given field (without seeing the records that do not) so I can do some analysis of those records. Can I use count this way? I tried
where count (distinct FIELD_A)>1
but it said I was using group incorrectly.
Try this:
SELECT
FIELD_A, count(*) no_of_records
FROM table
GROUP BY FIELD_A
HAVING count(*) > 1;
To restrict / filter the query output after aggregation has been performed, use a HAVING clause.
The WHERE clause is used to restrict / filter the query output BEFORE aggregation is performed (so if you had some rows you did not want to include in the COUNT, you can use the WHERE clause to filter them out).
Also you should not be using DISTINCT here, it will REMOVE all the duplicates before calculating the COUNT.
Use having statement
Select Field_Blah, Count(Distinct Field_A)
From table_a
group by Field_Blah
having Count(Distinct Field_A) > 1

mysql ORDER BY MIN() not matching up with id

I have a database that has the following columns:
-------------------
id|domain|hit_count
-------------------
And I would like to perform this query on it:
SELECT id,MIN(hit_count)
FROM table WHERE domain='$domain'
GROUP BY domain ORDER BY MIN(hit_count)
I would like this query to give me the id of the row that had the smallest hit_count for $domain. The only problem is that if I have two rows that have the same domain, say www.bestbuy.com, the query will just group by whichever one came first, and then although I will get the correct lowest hit_count, the id may or may not be the id of the row that has the lowest hit_count.
Does anyone know of a way for me to perform this query and to get the id that matches up with MIN(hit_count)? Thanks!
Try this:
SELECT id,MIN(hit_count),domain FROM table GROUP BY domain HAVING domain='$domain'
See, when you're using aggregates, either via aggregate functions (and min() is such a function) or via GROUP BY or HAVING operators, your data is being grouped. In your case it is grouped by domain. You have 2 fields in your select list, id and min(hit_count).
Now, for each group database knows which hit_count to pick, as you've specified this explicitly via the aggregate function. But what about id — which one should be included?
MySQL internally wraps such fields into max() aggregate function, which I find an error prone approach. In all other RDBMSes you will get an error for such a query.
The rule is: if you use aggregates, then all columns should be either arguments of aggregate functions or arguments of GROUP BY operator.
To achieve the desired result, you need a subquery:
SELECT id, domain, hit_count
FROM `table`
WHERE domain = '$domain'
AND hit_count = (SELECT min(hit_count) FROM `table` WHERE domain = '$domain');
I've used backticks, as table is a reserved word in SQL.
SELECT
id,
hit_count
FROM
table
WHERE
domain='$domain'
AND hit_count = (SELECT MIN(hit_count) FROM table WHERE domain='$domain')
Try this:
SELECT id,hit_count
FROM table WHERE domain='$domain'
GROUP BY domain ORDER BY hit_count ASC;
This should also work:
select id, MIN(hit_count) from table where domain="$domain";
I had same question. Please see that question below.
min(column) is not returning me correct data of other columns
You are using a GROPU BY. Which means each row in result represents a group of values.
One of those values is the group name (the value of the field you grouped by). The rest are arbitrary values from within that group.
For example the following table:
F1 | F2
1 aa
1 bb
1 cc
2 gg
2 hh
If u will group by F1: SELECT F1,F2 from T GROUP BY F1
You will get two rows:
1 and one value from (aa,bb,cc)
2 and one value from (gg,hh)
If u want a deterministic result set, you need to tell the software what algorithem to apply to the group. Several for example:
MIN
MAX
COUNT
SUM
etc etc
There is a most simplist way your query is OK just modify it with DESC keyword after GROUP BY domain
SELECT
id,
MIN(hit_count)
FROM table
WHERE domain = '$domain'
GROUP BY domain DESC
ORDER BY MIN(hit_count)
Explanation:
When you use group by with aggregate function it always selects the first record but if you restrict it with desc keyword it will select the lowest or last record of that group.
For testing puspose use this query that has only group_concat added.
SELECT
group_concat(id),
MIN(hit_count)
FROM table
WHERE domain = '$domain'
GROUP BY domain DESC
ORDER BY MIN(hit_count)
If you can have duplicated domains group by id:
SELECT id,MIN(hit_count)
FROM domain WHERE domain='$domain'
GROUP BY id ORDER BY MIN(hit_count)

How to tally column values of multiple rows with pure mysql?

hypothetic tables
user_id | hits
Can I get MySQL to return the total hits of a Select query? I know i could add them together with php or similar, just wondering if there is a pure MySQL way?
Total hits per user
SELECT userId, Sum(Hits)
FROM Table
GROUP by userId
OR
Total hits
SELECT Sum(Hits)
FROM Table
select sum(hits) from ...
Depending on the specific SQL query you're using you could either SUM a column or potentially use the 'WITH ROLLUP' GROUP modifier if you require a query-wide total.