Getting counts of records within bands - mysql

I have a table of data which contains numbers from 0 to 100.
I would like to write a query that gets counts of records in the bands 0 to 10, 11 to 20 ......and 91 to 100
Is this possible?
Many thanks for any help.
Dave

Assuming your table looks something like this...
CREATE TABLE `test1` (
`ts` BIGINT(20) DEFAULT NULL
) ENGINE=INNODB;
...you could tackle this with a mathematical approach:
SELECT ROUND((T.ts-1)/10) AS "tt",
COUNT(*)
FROM test1 AS T
GROUP BY tt;

sub query would do the job for you
SELECT
(SELECT COUNT(brands) FROM data_table where brands BETWEEN 1 and 10 ) as '1-10',
...
(SELECT COUNT(brands) FROM data_table where brands BETWEEN 90 and 100 ) as '90-100',

Select count from(
Select * from (select * from table where val >= 'lowerlimit') where val<='upperlimit')

This should give you the results:
SELECT MIN(`id`) `id_from`, MAX(`id`) as `id_to`, COUNT(1) `count_id`
FROM `session`
GROUP BY (FLOOR(IF(id>0, id-1, id) / 10));
Please feel free to change the table and column names as per your schema.
Hope this helps.

Related

return Mysql value/s that don't find on table records

i have a table
users
id collection_id
1 xwkoss
2 cw2333
3 oipopp
And i run query:
SELECT * FROM USERS WHERE collection_id in ('xwkoss','cw2333', 'abcdeef')
that query work fine and return 2 values existing on table, but i need know, which value doesn't exist on table records example: 'abcdeef', based on search parameters
thanks
Create a table on-the-fly and check with NOT EXISTS:
SELECT user_code
FROM
(
SELECT 'xwkoss' AS user_code
UNION ALL
SELECT 'cw2333' AS user_code
UNION ALL
SELECT 'abcdeef' AS user_code
) codes
WHERE NOT EXISTS
(
SELECT NULL
FROM users
WHERE users.user_code = codes.user_code
)
ORDER BY user_code;

MySQL select all table data, gouped by one column data

I have a table that looks like this:
serial|vehicule|alert_emails
12411|AAA|yes
12411|BBB|yes
13411|CCC|yes
13411|DDD|yes
14411|EEE|yes
I want to do a mysql query to select all data and organize it by serial field to get a array result like this:
12411
AAA|yes
BBB|yes
13411
CCC|yes
DDD|yes
14411
EEE|yes
I tried group by the field serial but I'm not getting the desired result:
SELECT * FROM mytable GROUP BY serial;
Any help please?
Thanks.
Use UNION ALL to get the distinct serials of the table and all the rows of the table:
SELECT CASE WHEN t.col IS NULL THEN t.serial END serial, t.col
FROM (
SELECT DISTINCT serial, null AS col
FROM mytable
UNION ALL
SELECT serial, CONCAT(vehicule, '|', alert_emails)
FROM mytable
) t
ORDER BY t.serial, t.col IS NULL DESC
See the demo.

Mysql - select from two table as two values

I cannot understand why my query
SELECT SUM(DATE(date) = '2014-11-2') AS `rate` FROM `ratings` UNION SELECT COUNT(*) AS `users` FROM `user`
doesn't create two values - rate, users as in query but only one - rate - with two values.
Result:
rate
6
10
Expected result:
rate users
6 10
Do you know, what's wrong with my query?
You should do a JOIN instead of an UNION.
Based on the information you shared and the result you want to achieve, your query could look something like this:
SELECT SUM(DATE(date) = '2014-11-2') AS `rate`, (
SELECT COUNT(*) FROM `user`
) AS `users`
FROM `ratings`
...but this lacks of some relations/conditions between the too tables
Because union is used to 'collect' several rows from different queries into 1 result set:
Something like this might do the trick:
SELECT (SUM(DATE(date) = '2014-11-2') AS `rate` FROM `ratings`)
, (COUNT(*) AS `users` FROM `user`)
Does that work?
SELECT (COUNT(DATE(date) = '2014-11-2') AS `rate`
FROM `ratings`), (COUNT(*) AS `users` FROM `user`)

mysql - Get two greatest values from multiple columns

We can use GREATEST to get greatest value from multiple columns like below
SELECT GREATEST(mark1,mark2,mark3,mark4,mark5) AS best_mark FROM marks
But now I want to get two best marks from all(5) marks.
Can I do this on mysql query?
Table structure (I know it is wrong - created by someone):
student_id | Name | mark1 | mark2 | mark3 | mark4 | mark5
This is not the most elegant solution but if you cannot alter the table structure then you can unpivot the data and then apply a user defined variable to get a row number for each student_id. The code will be similar to the following:
select student_id, name, col, data
from
(
SELECT student_id, name, col,
data,
#rn:=case when student_id = #prev then #rn else 0 end +1 rn,
#prev:=student_id
FROM
(
SELECT student_id, name, col,
#rn,
#prev,
CASE s.col
WHEN 'mark1' THEN mark1
WHEN 'mark2' THEN mark2
WHEN 'mark3' THEN mark3
WHEN 'mark4' THEN mark4
WHEN 'mark5' THEN mark5
END AS DATA
FROM marks
CROSS JOIN
(
SELECT 'mark1' AS col UNION ALL
SELECT 'mark2' UNION ALL
SELECT 'mark3' UNION ALL
SELECT 'mark4' UNION ALL
SELECT 'mark5'
) s
cross join (select #rn := 0, #prev:=0) c
) s
order by student_id, data desc
) d
where rn <= 2
order by student_id, data desc;
See SQL Fiddle with Demo. This will return the top 2 marks per student_id. The inner subquery is performing a similar function as using a UNION ALL to unpivot but you are not querying against the table multiple times to get the result.
I think you should change your database structure, because having that many marks horizontally (i.e. as fields/columns) already means you're doing something wrong.
Instead put all your marks in a separate table where you create a many to many relationship and then perform the necessary SELECT together with LIMIT.
Suggestions:
Create a table that you call mark_types. Columns: id, mark_type. I
see that you currently have 5 type of marks; it would be very simple
to add additional types.
Change your marks table to hold 3 columns: id,
mark/grade/value, mark_type (this column foreign constraints to
mark_types).
Write your SELECT query with the help of joins, and GROUP BY mark_type.
you can create a temporary table and then
Create a temporary table in a SELECT statement without a separate CREATE TABLE
query that table as follows
SELECT TOP 2 * FROM temp
ORDER BY mark DESC
then
drop temp table
Okay here's a new answer that's should work with the current table structure:
SELECT `student_id`, `Name`, `mark` FROM (SELECT `student_id`, `Name`, `mark1` AS `mark` FROM `marks`
UNION ALL
SELECT `student_id`, `Name`, `mark2` AS `mark` FROM `marks`
UNION ALL
SELECT `student_id`, `Name`, `mark3` AS `mark` FROM `marks`
UNION ALL
SELECT `student_id`, `Name`, `mark4` AS `mark` FROM `marks`
UNION ALL
SELECT `student_id`, `Name`, `mark5` AS `mark` FROM `marks`) AS `marks`
ORDER BY `mark` DESC
LIMIT 2

PHP SQL - Advanced delete query

I have a table with 3 columns: id, date and name. What I am looking for is to delete the records that have a duplicate name. The rule should be to keep the record that has the oldest date. For instance in the example below, there is 3 records with the name Paul. So I would like to keep the one that has the oldest date (id=1) and remove all the others (id = 4 and 6). I know how to make insert, update, etc queries, but here I do not see how to make the trick work.
id, date, name
1, 2012-03-10, Paul
2, 2012-03-10, James
4, 2012-03-12, Paul
5, 2012-03-11, Ricardo
6, 2012-03-13, Paul
mysql_query(?);
The best suggestion I can give you is create a unique index on name and avoid all the trouble.
Follow the steps as Peter Kiss said from 2 to 3. Then do this
ALTER Table tablename ADD UNIQUE INDEX name (name)
Then Follow 4 Insert everything from the temporary table to the original.
All the new duplicate rows, will be omitted
Select all the records what you want to keep
Insert them to a temporary table
Delete everything from the original table
Insert everything from the temporary table to the original
Like Matt, but without the join:
DELETE FROM `table` WHERE `id` NOT IN (
SELECT `id` FROM (
SELECT `id` FROM `table` GROUP BY `name` ORDER BY `date`
) as A
)
Without the first SELECT you will get "You can't specify target table 'table' for update in FROM clause"
Something like this would work:
DELETE FROM tablename WHERE id NOT IN (
SELECT tablename.id FROM (
SELECT MIN(date) as dateCol, name FROM tablename GROUP BY name /*select the minimum date and name, for each name*/
) as MyInnerQuery
INNER JOIN tablename on MyInnerQuery.dateCol = tablename.date
and MyInnerQuery.name = tablename.name /*select the id joined on the minimum date and the name*/
) /*Delete everything which isn't in the list of ids which are the minimum date fore each name*/
DELETE t
FROM tableX AS t
LEFT JOIN
( SELECT name
, MIN(date) AS first_date
FROM tableX
GROUP BY name
) AS grp
ON grp.name = t.name
AND grp.first_date = t.date
WHERE
grp.name IS NULL
DELETE FROM thetable tt
WHERE EXISTS (
SELECT *
FROM thetable tx
WHERE tx.thename = tt.thename
AND tx.thedate > tt. thedate
);
(note that "date" is a reserver word (type) in SQL, "and" name is a reserved word in some SQL implementations)