How can I enhance this query to use only one view? - mysql

I am learning SQL and DB, I need to make the following query, I need to make a query that finds the dates that there were more car crashes and list the names of the people who were involved in these car crashes
person
| name | id_person |
|--------|------------|
| Oliver | 000000001 |
| Harry | 000000002 |
| Jacob | 000000003 |
| Maria | 000000004 |
| Jack | 000000005 |
participated
| id_person | num_crash | cost_damage |
|------------|-------------|---------------|
| 00000001 | 11111101 | 200 |
| 00000002 | 11111102 | 120 |
| 00000003 | 11111102 | 120 |
| 00000004 | 11111103 | 400 |
| 00000005 | 11111104 | 300 |
| 00000002 | 11111105 | 280 |
| 00000005 | 11111106 | 260 |
crash
| num_crash | date_crash | crash_scene |
|-------------|--------------|-------------|
| 11111101 | 2020/04/28 | bairro 4 |
| 11111102 | 2020/05/01 | bairro 1 |
| 11111103 | 2020/05/01 | bairro 2 |
| 11111104 | 2020/05/04 | bairro 3 |
| 11111105 | 2020/05/04 | bairro 1 |
| 11111106 | 2020/05/04 | bairro 3 |
output example
| data_crash | num_crash | name |
|--------------|-------------|-------|
| 2020/05/04 | 11111104 | Jack |
| 2020/05/04 | 11111105 | Harry |
| 2020/05/04 | 11111106 | Jack |
| 2020/05/01 | 11111102 | Harry |
| 2020/05/01 | 11111102 | Jacob |
| 2020/05/01 | 11111103 | Maria |
This is my sql query
CREATE VIEW vwfrequencedatecrash AS
SELECT date_crash, num_crash, crash_scene, ROW_NUMBER() OVER (PARTITION
BY date_crash ORDER BY date_crash) AS frequence
FROM crash
ORDER BY frequence DESC;
CREATE VIEW vwmorefrequencedate AS
SELECT date_crash, num_crash, crash_scene, frequence
FROM vwfrequencedatecrash
WHERE frequence > 1;
SELECT vw.date_crash, pa.num_crash, p.name
FROM vwmorefrequencedate vw
JOIN crash c ON c.date_crash = vw.date_crash
JOIN participated pa ON c.num_crash = pa.num_crash
JOIN person p ON pa.id_person = p.id_person
ORDER BY vw.frequence DESC, c.date_crash;
how can I improve this query?

Related

how to sort sql data for given table?

+---------+----------------+--------+
| aid | fn | col_no |
+---------+----------------+--------+
| 2011768 | ABDUL | 5 |
| 2011499 | ABDULLA | 4 |
| 2011198 | ADNAN | 3 |
| 2011590 | AKSHAYA PRAISY | 2 |
| 2011749 | AMIR | 1 |
| 2011213 | AMOGHA | 5 |
| 2011027 | ANU | 4 |
| 2011046 | ANUDEV D | 3 |
| 2011435 | B S SAHANA | 2 |
| 2011112 | BENAKA | 1 |
+---------+----------------+--------+
How to sort the number like col_no as 1 2 3 4 5 and again repeat as 1 2 3 4 5?
i need output like this
+---------+----------------+--------+
| aid | fn | col_no |
+---------+----------------+--------+
| 2011749 | AMIR | 1 |
| 2011590 | AKSHAYA PRAISY | 2 |
| 2011198 | ADNAN | 3 |
| 2011499 | ABDULLA | 4 |
| 2011768 | ABDUL | 5 |
| 2011112 | BENAKA | 1 |
| 2011435 | B S SAHANA | 2 |
| 2011046 | ANUDEV D | 3 |
| 2011027 | ANU | 4 |
| 2011213 | AMOGHA | 5 |
+---------+----------------+--------+
You can use row_number() partition by col_no:
select t.*
from t
order by row_number() over (partition by col_no order by fn),
col_no;
Here is a db<>fiddle.

How to display all duplicate value

Is there anyway I could display all the duplicate values in mysql using group by and having
+---------+--------------+------------+--------+----------+----------+---------+
| ENumber | EmpName | Birthdate | Gender | Address | Salary | DNumber |
+---------+--------------+------------+--------+----------+----------+---------+
| E001 | GSInocencio | 1988-01-15 | F | Munoz | 18000.00 | D005 |
| E002 | EAVillanueva | 1988-04-20 | F | Munoz | 23000.00 | D003 |
| E003 | ALedesma | 1988-05-25 | M | CLSU | 21000.00 | D002 |
| E004 | APGamilla | 1991-10-15 | F | Maligaya | 25000.00 | D001 |
| E005 | ACTolentino | 1989-02-20 | F | Maligaya | 30000.00 | D002 |
| E006 | ANVillasoto | 1999-01-05 | M | CLSU | 15000.00 | D004 |
| E007 | JPPalada | 1997-01-10 | M | Munoz | 21000.00 | D001 |
| E008 | NTNicodemus | 1995-04-15 | F | Maligaya | 22000.00 | D003 |
+---------+--------------+------------+--------+----------+----------+---------+
I want to display all the duplicate value in DNumber
+---------+--------------+------------+--------+----------+----------+---------+
| ENumber | EmpName | Birthdate | Gender | Address | Salary | DNumber |
+---------+--------------+------------+--------+----------+----------+---------+
| E004 | APGamilla | 1991-10-15 | F | Maligaya | 25000.00 | D001 |
| E007 | JPPalada | 1997-01-10 | M | Munoz | 21000.00 | D001 |
| E003 | ALedesma | 1988-05-25 | M | CLSU | 21000.00 | D002 |
| E005 | ACTolentino | 1989-02-20 | F | Maligaya | 30000.00 | D002 |
| E002 | EAVillanueva | 1988-04-20 | F | Munoz | 23000.00 | D003 |
| E008 | NTNicodemus | 1995-04-15 | F | Maligaya | 22000.00 | D003 |
display all the duplicate values in mysql using group by and having
There is more than one way to do it, but if you want to use group by and having, then you can join the table with an aggregate subquery that identifies the duplicates, as follows:
select t.*
from mytable t
inner join (
select dnumber
from mytable
group by dnumber
having count(*) > 1
) x on x.dnumber = t.dnumber
order by t.dnumber, t.enumber

SQL Count each time row equal to column

So I have the carriesOut table:
+------------+------------+
| theatreNo | doctor |
+------------+------------+
| 1 | DD0094CYY |
| 1 | DD234CD1X |
| 2 | DD1199XYZ |
| 2 | DD1199XYZ |
| 4 | AB2323CYA |
| 4 | AB2323CYA |
+------------+------------+
And the doctor table:
+-------------+---------+
| NINumber | lname |
+-------------+---------+
| AB2323CYA | Falk |
| DD0094CYY | Gibbson |
| DD1199XYZ | Smith |
| DD234CD1X | Hammer |
+-------------+---------+
I'm trying to find how many times every doctor has been in an operation, for example, I should get the output:
+------------+---------+------------+
| doctor | lname | operations |
+------------+---------+------------+
| DD0094CYY | Gibbson | 1 |
| AB2323CYA | Falk | 2 |
| DD1199XYZ | Smith | 2 |
| DD234CD1X | Hammer | 1 |
+------------+---------+------------+
And here is what I've tried so far:
SELECT o.doctor
, d.lname
, COUNT(theatreNo) operations
FROM Hospital_CarriesOut o
JOIN Hospital_Doctor d
ON d.NINumber = o.doctor
WHERE theatreNo IN (1,2,4)
GROUP
BY statement DESC
I only get the the following output:
+------------+---------+------------+
| doctor | lname | operations |
+------------+---------+------------+
| DD0094CYY | Gibbson | 1 |
| AB2323CYA | Falk | 1 |
| AB2323CYA | Falk | 3 |
| DD234CD1X | Hammer | 1 |
+------------+---------+------------+
it should be group by Hospital_CarriesOut.doctor, Hospital_Doctor.lname
SELECT Hospital_CarriesOut.doctor, Hospital_Doctor.lname,
COUNT(theatreNo) AS operations
FROM Hospital_CarriesOut JOIN Hospital_Doctor ON Hospital_CarriesOut.doctor=Hospital_Doctor.NINumber WHERE theatreNo IN (1,2,4)
GROUP BY Hospital_CarriesOut.doctor, Hospital_Doctor.lname

MySQL: Rows concatenation

May be this is really a simple question, thanks in advance.
What I currently have:
+-----+---+---+---+---+
| sid | a | b | c | d |
+-----+---+---+---+---+
| 123 | | | | 4 |
| 123 | | 2 | | |
| 123 | | | 3 | |
| 123 | 1 | | | |
| 456 | | 5 | | |
| 456 | | | 6 | |
| 789 | | | | 8 |
| 789 | 7 | | | |
+-----+---+---+---+---+
What I am trying to get:
+-----+------+------+------+------+
| sid | a | b | c | d |
+-----+------+------+------+------+
| 123 | 1 | 2 | 3 | 4 |
| 456 | | 5 | 6 | |
| 789 | 7 | | | 8 |
+-----+------+------+------+------+
How such "rows concatenation" could be done in MySQL?
You can do this with the MAX() aggregation function with a GROUP BY clause in your query.
SELECT sid, MAX(a), MAX(b), MAX(c), MAX(d)
FROM table
GROUP BY sid
I used MAX() because it will filter the NULL values with others values.
More explanation here : MySQL Documentation

How can I count the users with more than 1 Order?

I'm working on a MySQL database and I need to query the database and find out the users with more than one order. I tried using COUNT() but I cannot get it right. Can you please explain the correct way to do this?.
Here are my tables:
User
+-------------+----------+------------------+------------+
| userID | fName | email | phone |
+-------------+----------+------------------+------------+
| adele012 | Adele | aash#gmail.com | 0123948498 |
| ana022 | Anna | ashow#gmail.com | 0228374847 |
| david2012 | David | north#gmail.com | 902849302 |
| jefAlan | Jeffery | jefal#gmail.com | 0338473837 |
| josquein | Joseph | jquein#gmail,com | 0098374678 |
| jweiz | John | jwei#gmail.com | 3294783784 |
| jwick123 | John | jwik#gmail.com | 0998398390 |
| kenwipp | Kenneth | kwip#gmail.com | 0112938394 |
| mathCler | Maththew | matc#gmail.com | 0238927483 |
| natalij2012 | Natalie | nj#gmail.com | 1129093210 |
+-------------+----------+------------------+------------+
Orders
+---------+------------+-------------+-------------+
| orderID | date | User_userID | orderStatus |
+---------+------------+-------------+-------------+
| 1 | 2012-01-10 | david2012 | Delivered |
| 2 | 2012-01-15 | jweiz | Delivered |
| 3 | 2013-08-15 | david2012 | Delivered |
| 4 | 2013-03-15 | natalij2012 | Delivered |
| 5 | 2014-03-04 | josquein | Delivered |
| 6 | 2014-01-15 | jweiz | Delivered |
| 7 | 2014-02-15 | josquein | Delivered |
| 8 | 2015-10-12 | jwick123 | Delivered |
| 9 | 2015-02-20 | ana022 | Delivered |
| 10 | 2015-11-20 | kenwipp | Processed |
+---------+------------+-------------+-------------+
select user_userID, count(*) as orders_count from orders
group by user_userID having orders_count > 1
if you want additional data from your users table, you can do:
select * from user where user_id in (
select user_userID as orders_count from orders
group by user_userID having orders_count > 1
)