how to check the record occurrence in mysql - mysql

kindly suggest me a sql query to sort this.
there is a non normalized table named test.there ar2 two fields on is primary key and it is auto incremented. other field 'name' and it is repetitive as follow.
so i just need to know what insert/update mysql query should i used to get below output in the 'occurrence' field.
eg:- in the 5th row name 'occurance' value is 3 because 'name'= "chanaka" has included 3 times totally in the table with including record 5.

Read up on mysql row number simulation
Here's an example
MariaDB [sandbox]> select id,company_id
-> , if(company_id <> #p ,#rn:=1, #rn:=#rn+1) occurance
-> , #p:=company_id
-> from medication, (select #rn:=0,#p:=0) rn
-> order by company_id, id;
+------+------------+-----------+----------------+
| id | company_id | occurance | #p:=company_id |
+------+------------+-----------+----------------+
| 1 | 1 | 1 | 1 |
| 2 | 1 | 2 | 1 |
| 3 | 1 | 3 | 1 |
| 4 | 2 | 1 | 2 |
| 5 | 2 | 2 | 2 |
| 6 | 2 | 3 | 2 |
| 8 | 2 | 4 | 2 |
| 7 | 3 | 1 | 3 |
+------+------------+-----------+----------------+
8 rows in set (0.00 sec)

You should be able to count "name" and that should get you the amount of
occurrences.
SELECT id, name, count(name)
FROM test
GROUP by name

Related

getting data from 2 tables with one-to-many relation using limit and offset on a 'master' table

This seems simple so I'm a little embarrassed to ask, but here it is: I've got 2 tables - orders and items (of orders). One order can have one or more items and I'd like to use LIMIT to get e.g. first 10 orders, possibly using OFFSET too so, the question is: how to create a query that would do that? For example, if order 1 has 2 items, order 2: 1 item, order 3: 2 items, order 4: 1 item, and I need first 3 orders the expected result would be:
order 1 item 1
order 1 item 2,
order 2 item 1,
order 3 item 1,
order 3 item 2
Using a sub query to limit and given
MariaDB [sandbox]> select * from cat_books;
+--------+-------+
| idbook | name |
+--------+-------+
| 1 | book1 |
| 2 | book2 |
| 3 | book3 |
| 4 | book4 |
+--------+-------+
4 rows in set (0.001 sec)
MariaDB [sandbox]> select * from books_sold;
+---------+--------+--------+
| id_sold | idbook | iduser |
+---------+--------+--------+
| 1 | 1 | 1 |
| 2 | 2 | 1 |
| 3 | 1 | 2 |
| 4 | 1 | 3 |
| 4 | 3 | 5 |
+---------+--------+--------+
5 rows in set (0.001 sec)
MariaDB [sandbox]>
MariaDB [sandbox]> select *
-> from
-> (SELECT * FROM CAT_books order by idbook limit 2) cb
-> join
-> books_sold bs on bs.idbook = cb.idbook
-> order by cb.idbook;
+--------+-------+---------+--------+--------+
| idbook | name | id_sold | idbook | iduser |
+--------+-------+---------+--------+--------+
| 1 | book1 | 3 | 1 | 2 |
| 1 | book1 | 4 | 1 | 3 |
| 1 | book1 | 1 | 1 | 1 |
| 2 | book2 | 2 | 2 | 1 |
+--------+-------+---------+--------+--------+
4 rows in set (0.001 sec)

How to join 1 table to another table and get count result per date

I have 3 tables with corresponding fields.
Table 1 (List of Machines)
Machine_No | Machine_Description
1 | Hitachi
2 | Jet Printer
3 | Sumi
Table 2 (List of Manpower)
ID_Number | Employee_Name | Machine_No
1 | Taylor | 3
2 | James | 2
3 | David | 1
Table 3 (Actual Manpower use per machine)
Machine_No | Employee_Number | Date Posted
1 | 1 | 15-10-2019
1 | 2 | 15-10-2019
1 | 3 | 15-10-2019
Now... I want the results to go like this.
Machine_Now | Count(Employee Number) | Date_Posted
1 | 3 | 15-10-2019
Try this, it may work, if I understand your question correctly.
select Machine_No,Date_Posted,count(*) from Table3 group by Machine_No,Date_Posted;

about mysql excute order by 1 and rand(1)?

In mysql I built a table, which id is int type, name and password is varchar type.
excute
select * from test.new_table order by rand(1);
then the result is:
This is because after set seed for rand the sequence is fixed, I already know.But if excute
select * from test.new_table order by 1 and rand(1);
then the result is:
For such a result I do not understand. In addition, if excute order by 'xxx' the results are arranged.
Not quite understand, hope you to give pointers.
You can view the results of the expression as part of your query:
mysql> select *, 1, rand(1), 1 and rand(1) from new_table order by 1 and rand(1);
+----+------+----------+---+---------------------+---------------+
| id | name | password | 1 | rand(1) | 1 and rand(1) |
+----+------+----------+---+---------------------+---------------+
| 1 | ghi | 111 | 1 | 0.40540353712197724 | 1 |
| 3 | abc | 234 | 1 | 0.1418603212962489 | 1 |
| 5 | 5 | 5 | 1 | 0.04671454713373868 | 1 |
| 7 | 7 | 7 | 1 | 0.6108337804776 | 1 |
| 2 | jkl | 123 | 1 | 0.8716141803857071 | 1 |
| 4 | def | 555 | 1 | 0.09445909605776807 | 1 |
| 6 | 6 | 6 | 1 | 0.9501954782290342 | 1 |
+----+------+----------+---+---------------------+---------------+
See how the boolean expression always results in 1?
As #Barmar described, any expression 1 and n results in either 0 or 1, depending on the value of n being zero or nonzero.
So your expression ORDER BY 1 AND RAND(1) is just like ORDER BY true (a constant expression) which means the ordering is a tie between every row, and MySQL orders them in an arbitrary way.
But arbitrary is not the same as random.

grouped sql query (mysql) - order by

Lets's say i have a table sign_ins which has data like so: (the real table has 3.5 million rows)
+-----------+---------+------------------+
| school_id | user_id | date(created_at) |
+-----------+---------+------------------+
| 1 | 4 | 2009-04-20 |
| 1 | 4 | 2009-04-21 |
| 1 | 4 | 2009-05-06 |
| 1 | 5 | 2009-04-20 |
| 1 | 5 | 2009-06-26 |
| 1 | 5 | 2009-06-26 |
| 2 | 6 | 2009-04-21 |
| 2 | 6 | 2009-06-26 |
| 2 | 7 | 2009-04-20 |
| 2 | 7 | 2009-04-20 |
+-----------+---------+------------------+
created_at is a datetime field but i'm calling date() on it to get the day.
I have the concept of a "login_days" which is the number of distinct days on which a given user has a sign_in record. I want to order the schools by the number of login days, highest first, and return the number of login days.
So, looking at the data above, school 1 has two users (4 & 5). User 4 has three sign_ins, on 3 distinct days, so 3 "login_days". User 5 has three logins, but only 2 distinct days, so 2 "login_days". Therefore school 1 has 5 login days.
Looking at school 2, it has 3 login days: 2 from user 6 and 1 from user 7.
So, i would want to get this back from the query:
+-----------+------------+
| school_id | login_days |
+-----------+------------+
| 1 | 5 |
| 2 | 4 |
+-----------+------------+
I can't quite figure out how to do the query. I started off with this (i have the id < 11 part in there just to get my example data instead of my entire table of 3.5 million rows):
mysql> select school_id from sign_ins where id < 11 group by school_id, user_id, date(created_at);
+-----------+
| school_id |
+-----------+
| 1 |
| 1 |
| 1 |
| 1 |
| 1 |
| 2 |
| 2 |
| 2 |
+-----------+
8 rows in set (0.00 sec)
I can see in here that there are 5 rows for school 1 and 3 for school 2, which looks like it's worked. But i need to group that further, and order by that grouped number, to get it like in my required results. It must be something simple, can someone show me what i'm missing?
thanks, Max
MySQL allows you to count the number of distinct values for multiple expressions. So, this is basically an aggregation query with the appropriate count:
select school_id, count(distinct user_id, date(created_at)) as NumLoginDays
from sign_ins
group by school_id;

selecting all duplicates

How can I update this to select all duplicates?
SELECT address FROM list
GROUP BY address HAVING count(id) > 1
Currently, I think it just returs the addresses which are duplciated. I want all duplicates.
Select * from list
where address in (
select address from list group by address
having count(*) > 1);
Look at this sample query I ran:
mysql> select * from flights;
+--------+-------------+
| source | destination |
+--------+-------------+
| 1 | 2 |
| 3 | 4 |
| 5 | 6 |
| 6 | 1 |
| 2 | 4 |
| 1 | 3 |
| 5 | 2 |
| 6 | 3 |
| 6 | 5 |
| 6 | 4 |
+--------+-------------+
10 rows in set (0.00 sec)
mysql> select * from flights where source in
(select source from flights group by source having count(*) > 1);
+--------+-------------+
| source | destination |
+--------+-------------+
| 1 | 2 |
| 5 | 6 |
| 6 | 1 |
| 1 | 3 |
| 5 | 2 |
| 6 | 3 |
| 6 | 5 |
| 6 | 4 |
+--------+-------------+
8 rows in set (0.00 sec)
If I'm correct, you're looking for the actual rows that contain duplicates -- so that if you have three rows with the same address, you return all three rows.
Here's how to do it:
SELECT * FROM list
WHERE address in (
SELECT address FROM list GROUP BY address HAVING count(id) > 1
);
This should generally work unless your address is a 'text' field or if your address table has more than a few thousand duplicates.
Are you looking for this?
SELECT * FROM list
WHERE id IN (
SELECT id FROM list
GROUP BY address HAVING count(id) > 1
);