I would like get the id and the number of id. So, I write this command sql:
SELECT count(id), id
FROM tblExample
It's doesn't work. Have you a solution for me ? For to get the value of my id and the number of id.
Or a function PHP for count my resultset.
Just add a GROUP BY id:
SELECT id, COUNT(id)
FROM tblExample
GROUP BY id;
Demo
Update:
The query you posted:
SELECT count(id), id
FROM tblExample;
Won't work in most of the RDBMS and it shouldn't. In SQL Server, you will got an error; saying that:
Column 'id' is invalid in the select list because it is not contained in either an
aggregate function or the GROUP BY clause.
Strangely though, MySQL allow this(The OP didn't say what RDBMS he is using), and in this case, it will get an arbitrary value (this is also depends on an option to set), for the id column, and the COUNT in this case would be all the id's count.
But it is not recommended to do so.
Related
I have a PHP array with numbers of ID's in it. These numbers are already ordered.
Now i would like to get my result via the IN() method, to get all of the ID's.
However, these ID's should be ordered like in the IN method.
For example:
IN(4,7,3,8,9)
Should give a result like:
4 - Article 4
7 - Article 7
3 - Article 3
8 - Article 8
9 - Article 9
Any suggestions? Maybe there is a function to do this?
Thanks!
I think you may be looking for function FIELD -- while normally thought of as a string function, it works fine for numbers, too!
ORDER BY FIELD(field_name, 3,2,5,7,8,1)
You could use FIELD():
ORDER BY FIELD(id, 3,2,5,7,8,1)
Returns the index (position) of str in the str1, str2, str3, ... list. Returns 0 if str is not found.
It's kind of an ugly hack though, so really only use it if you have no other choice. Sorting the output in your app may be better.
Standard SQL does not provide a way to do this (MySQL may, but I prefer solutions that are vendor-neutral so I can switch DBMS' at any time).
This is something you should do in post-processing after the result set is returned. SQL can only return them in an order specified in the "order by" clause (or in any order if there's no such clause).
The other possibility (though I don't like it, I'm honor-bound to give you the choice) is to make multiple trips to the database, one for each ID, and process them as they come in:
select * from tbl where article_id = 4;
// Process those.
select * from tbl where article_id = 7;
// Process those.
: : : : :
select * from tbl where article_id = 9;
// Process those.
You'll just need to give the correct order by statement.
SELECT ID FROM myTable WHERE ID IN(1,2,3,4) ORDER BY ID
Why would you want to get your data ordered unordered like in your example?
If you don't mind concatening long queries, try that way:
SELECT ID FROM myTable WHERE ID=1
UNION
SELECT ID FROM myTable WHERE ID=3
UNION
SELECT ID FROM myTable WHERE ID=2
Table has approximately 100 000 records(tuples). Without where clause it takes only few miliseconds whereas takes 4-5 secs when use where clause.
SELECT COUNT(DISTINCT id) FROM tablename WHERE shippable = '1'
I also tried this one but it takes more time as compared to previous one.
SELECT count(rowsss) FROM (SELECT count(*) as rowsss FROM tablename WHERE shippable = '1' GROUP BY id) as T
This is the output when I use EXPLAIN keyword before starting of mysql query
If you a need a filter you could use an index on shippable eg:
create index shippable_ixd on tablename (shippable);
in this way the scan for the table is limited to values that match
and avoid the scan for entire table
and based on the fact you also need the column id you could also trying alternatively a composite index
create index shippable_ixd on tablename (shippable, id);
the sqloptimizer should retrive directly form the index the info needed.
In this case The use of composite index ( with a redundant id not need by where clause) is useful because the SQL engine retrive all the data needed to the query just scanning the index, avoiding the access to the data in the table. This tecnique is use frequently for db queries tuning.
When you checking any condition that time both value should be in same type then execution of query will be fast.
SELECT count(rowsss) FROM (SELECT count(*) as rowsss FROM tablename WHERE CAST(shippable AS CHAR) = '1' GROUP BY id) as T
I'm a bit confused about DISTINCT keyword. Let's guess that this query will get all the records distincting the columns set in the query:
$query = "SELECT DISTINCT name FROM people";
Now, that query is fetching all the records distincting column "name" and at the same time only fetching "name" column. How I'm supposed to ONLY distinct one column and at the same time get all the desired columns?
This would be the scheme:
NEEDED COLUMNS
name
surname
age
DISTINCTING COLUMNS
name
What would be the correct sintaxis for that query? Thanks in advance.
If you want one row per name, then a normal method is an aggregation query:
select name, max(surname) as surname, max(age) as age
from t
group by name;
MySQL supports an extension of the group by, which allows you to write a query such as:
select t.*
from t
group by name;
I strongly recommend that you do not use this. It is non-standard and the values come from indeterminate matching rows. There is not even a guarantee that they come from the same row (although they typically do in practice).
Often, you want something like that biggest age. If so, you handle this differently:
select t.*
from t
where t.age = (select max(t2.age) from t t2 where t2.name = t.name);
Note: This doesn't use group by. And, it will return duplicates if there are multiple rows with the same age.
Another method uses variables -- another MySQL-specific feature. But, if you are still learning about select, you should probably wait to learn about variables.
I have 2 tables with similar columns in MYSQL. I am copying data from one to another with INSERT INTO table2 SELECT * FROM table1 WHERE column1=smth. I have different columns as autoincrement and KEY in tables. When I use mysqli_insert_id i get the first one rather then last one inserted. Is there any way to get the last one?
Thanks
There is no inherit ordering of data in a relational database. You have to specify which field it is that you wish to order by like:
INSERT INTO table2
SELECT *
FROM table1
WHERE column1=smth
ORDER BY <field to sort by here>
LIMIT 1;
Relying on the order a record is written to a table is a very bad idea. If you have an auto-numbered id on table1 then just use ORDER BY id DESC LIMIT 1 to sort the result set by ID in descending order and pick the last one.
Updated to address OP's question about mysqli_insert_id
According to the Mysql reference the function called here is last_insert_id() where it states:
Important If you insert multiple rows using a single INSERT statement,
LAST_INSERT_ID() returns the value generated for the first inserted
row only. The reason for this is to make it possible to reproduce
easily the same INSERT statement against some other server.
Unfortunately, you'll have to do a second query to get the true "Last inserted id". Your best bet might be to run a SELECT COUNT(*) FROM table1 WHERE column1=smth; and then use that count(*) return to add to the mysqli_insert_id value. That's not great, but if you have high volume where this one function is getting hit a lot, this is probably the safest route.
The less safe route would be SELECT max(id) FROM table2 or SELECT max(id) FROM table2 Where column1=smth. But... again, depending on your keys and the number of times this insert is getting hit, this might be risky.
With PHP I'm trying to run a SQL query and select normal columns as well as COUNT.
$sql_str = "select COUNT(DISTINCT name), id, adress from users";
$src = mysql_query($sql_str);
while( $dsatz = mysql_fetch_assoc($src) ){
echo $dsatz['name'] . "<br>";
}
The problem is that when I have "COUNT(DISTINCT name)," in my query, it will only return the first entry. When I remove it, it will return all matching entries from the db.
I could separate it and do 2 queries, but I'm trying to avoid this due to performance concerns.
What do I make wrong?
thx, Mexx
The ability to mix normal columns and aggregate functions is a (mis)feature of MySQL.
You can even read why it's so dangerous on MySQL's documentation:
https://dev.mysql.com/doc/refman/5.6/en/group-by-extensions.html
But if you really want to mix normal rows and a summary in a single query, you can always use the UNION statement:
SELECT COUNT(DISTINCT name), null, null FROM users GROUP BY name --summary row
UNION
SELECT name, id, address FROM users --normal rows
COUNT() is an aggregate function, it aggregates against the results of the rest of your query. If you want to count all distinct names, and not just the distinct names associated with the id and address that you are selecting, then yes, you will have to run two queries. That's just how SQL works.
Note that you should also have a group by clause when aggregating. I think the fact that MySQL doesn't require it is horrible, and it encourages really bad habits.
From what I understand, you want to get :
one line per user, to get each name/id/address
one line for several users at the same time, to get the number of users who have the same name.
This is not quite possible, I'd say.
A solution would be, like you said, two queries...
... Or, in your case, you could do the count on the PHP side, I suppose.
ie, not count in the query, but use an additionnal loop in your PHP code.
When you have a count() as part of the field list you should group the rest of the fields. In your case that would be
select count(distinct name), id, adress from users group by id, adress
select count(distinct name), id, adress
from users
group by id, adress
I'm assuming you want to get all your users and the total count in the same query.
Try
select name, id, address, count(id) as total_number
from users
group by name, id, address;