SQL GROUP BY query issue - mysql

I have a table with the following columns:
DriverNumber; DriverName; CarNumber; DriverConditions; LogonTime; VehicleID
this table has an entry for each LogonTime for each DriverNumber, and a driver can logon to different vehicles.
for example:
93070495 Mehar 189 Parcel, V, Wheelchair, M50, Special, Animal, COD P... Jan 2 2014 07:40:26:197AM 1029
93070495 Mehar 189 Parcel, V, Wheelchair, M50, Special, Animal, COD P... Jan 7 2014 08:09:50:097AM 1029
25184313 Kerry 895 Parcel, Cheques, V, Wheelchair, Special, Animal, C... Jan 3 2014 05:00:26:600PM 970
what i essentially want to do is show how many times a DriverNumber logs into each car.
this is what i have done so far:
SELECT DriverNumber, DriverName, CarNumber, DriverConditions, LogonTime,
count(DriverNumber) as DriverCount
FROM SilverDrivers
WHERE DriverNumber > 0
GROUP BY CarNumber
This gives me close to what i am after, but it only shows one CarNumber per DriverNumber. eg:
DRIVER HDL | DRIVER NAME | CAR NUMBER | DRIVER CONDITIONS | NUMBER OF LOGONS
98749492 | Manpreet | 3 | Parcel | 10
32176467 | Mark | 19 | Wheelchair | 7
92173581 | Varinder | 46 | Parcel | 1
what i want it to look like is:
DRIVER HDL | DRIVER NAME | CAR NUMBER | DRIVER CONDITIONS | NUMBER OF LOGONS
98749492 | Manpreet | 3 | Parcel | 7
98749492 | Manpreet | 12 | Parcel | 3
32176467 | Mark | 19 | Wheelchair | 4
32176467 | Mark | 214 | Wheelchair | 3
92173581 | Varinder | 46 | Parcel | 1

You should also group by driver number to get the count you want. Also, add all the other columns to your GROUP BY clause and remove columns that wouldn't be unique from SELECT (I left only DriverName as I assume it's always the same for one DriverNumber).
SELECT DriverNumber, DriverName, CarNumber, count(*) as DriverCount
FROM SilverDrivers
WHERE DriverNumber > 0
GROUP BY DriverNumber, DriverName, CarNumber

You want either
GROUP BY DriverNumber, CarNumber
or
GROUP BY CarNumber, DriverNumber

Related

Mysql - Get season from current month

I have the following table of seasons:
| id | name | start_month | end_month |
------------------------------------------
| 101 | Summer | 12 | 2 |
| 102 | Winter | 6 | 8 |
| 103 | Spring | 9 | 11 |
| 104 | Fall | 3 | 5 |
I need to get the season by month. Say current month is 2 (February), I want Summer to be the output.
I can get other seasons to work by simply having the where condition start_month >= 4 and end_month <= 4. But this won't work with Summer since the season crosses into next year.
What do I have to do to handle the case of Summer?
One solution I thought was to use dates instead of month number like 1980-12-01 and use between function but it gets a bit complicated for the user end.
It'd be great if it could work with just month numbers.
You could do:
(month(d) between start_month and end_month) or
(start_month>end_month and (month(d)>=start_month or month(d)<=end_month))
See db-fiddle

How to output a list by the results of two columns

I’ve a database where I store each product submitted by the curators, and there I register if it was approved. I need to generate a list where I show their score, ordered by the one who has more submitted (subm) and approved (appr). For that I need to get the approval rate (with the division of appr/subm) and we call it ar (Approval rate), and then I need a second operation to get the cs (Curator Score), which is the result of appr*(ar*ar).
The final output should be as the following:
| Curator | subm | appr| ar | cs |
------------------------------------------------
| 1 | 21 | 20 | 95.24% | 18.14058957 |
| 4 | 13 | 12 | 92.31% | 10.22485207 |
| 2 | 10 | 7 | 70.00% | 3.43 |
| 3 | 2 | 2 |100.00% | 2 |
To get the values from the table I use
SELECT curator, SUM(prop) subm, SUM(date) appr
FROM control
GROUP BY curator
ORDER BY cs
But I need to add somewhere:
SUM(appr/subm) ar, SUM(appr*(ar*ar)) cs
But I don’t know how to do this.
It's probably simplest to use your existing query as a subquery:
SELECT *, appr/subm AS ar, appr*(appr/subm*appr/subm)) AS cs
FROM (SELECT curator, SUM(prop) subm, SUM(date) appr
FROM control
GROUP BY curator) c
ORDER BY cs

Get Number of A's in Result Table - MySQL

This is the case. In my school all classes prepare excel sheet for each class with marks for each subject in term end test. There are 17 classes. I combine them in to access table. Then again export all data in to excel. make csv file . And import to Mysql Database using phpmyadmin. now I have result table as follow.
| ID | Name | Religion | Sinhala | science | english | maths | History | Categery 1 | Categery 2 | Categery 3 | Total | Average | Rank | |
|---- |------- |---------- |--------- |--------- |--------- |------- |--------- |------------ |------------ |------------ |------- |--------- |------ |--- |
| 1 | manoj | 45 | 65 | 78 | 98 | 67 | 67 | 63 | 76 | 64 | 654 | 62 | 12 | |
Sectional Head Need to get number of students who got >75 for all Subject.
And Number of Student Who got >75 for 8 subject out of 9.
I need to retrieve number of A s, B s (marks >=75) from this table.
Ex. Student names and Number of A s
Total Number of A for all 9 subject - 45
Total Number of A for all 8 subject (any 8 subject ) - 45
Total Number of A for all 7 subject (any 7 subject ) - 45
I Tried following SQL Statement
SELECT COUNT(SELECT COUNT()
FROM result
WHERE religion >=75
AND Math >=75)
FROM result
I read about same scenario in stack overflow.
Access 2010
this one get some point. but I cant solve it for my scenario.
Use GROUP BY studentName and SUM(grade = 'A') AS numberOfAs.
[Quick answer bc question is quickly formatted]

Place a footer row as an header row of a group of rows

I have a table like the following :
rfa_yea | rfa_idx | rfa_dsp | rfa_tpr
---------+---------+----------------------------------------------------+---------
2013 | 1 | PIGATO VERM.NO/ROSS/ORMEASCO CL75 | A
2013 | 2 | ESTATE\134134134047 BICCHIERE SING.VERDE | A
2013 | 3 | Rif. Trn. N. 17 del 17/04/2013 Cassa N. 00001 | C
2013 | 4 | BIB.RED BULL LAT.CL25 ENER.DRI | A
2013 | 5 | BIB.RED BULL LAT.CL25 ENER.DRI | A
2013 | 6 | SHOPPER 30X60 MAXI X 1000 | A
2013 | 7 | SHOPPER HD 27X50 MEDIE X 1000 | A
2013 | 8 | PIGATO VERM.NO/ROSS/ORMEASCO CL75 | A
2013 | 9 | * SCONTO SUBTOTALE | A
2013 | 10 | Rif. Trn. N. 19 del 17/04/2013 Cassa N. 00001 | C
The record with the field rfa_tpr marked as 'C' is the header of the group of rows that came before it. I need to place the row as an header of the group of rows instead of footer(separator) as at the moment, so I want to retrieve a result set like the following :
rfa_yea | rfa_idx | rfa_dsp | rfa_tpr
---------+---------+----------------------------------------------------+---------
2013 | 3 | Rif. Trn. N. 17 del 17/04/2013 Cassa N. 00001 | C
2013 | 1 | PIGATO VERM.NO/ROSS/ORMEASCO CL75 | A
2013 | 2 | ESTATE\134134134047 BICCHIERE SING.VERDE | A
2013 | 10 | Rif. Trn. N. 19 del 17/04/2013 Cassa N. 00001 | C
2013 | 4 | BIB.RED BULL LAT.CL25 ENER.DRI | A
2013 | 5 | BIB.RED BULL LAT.CL25 ENER.DRI | A
2013 | 6 | SHOPPER 30X60 MAXI X 1000 | A
2013 | 7 | SHOPPER HD 27X50 MEDIE X 1000 | A
2013 | 8 | PIGATO VERM.NO/ROSS/ORMEASCO CL75 | A
2013 | 9 | * SCONTO SUBTOTALE | A
Is there a solution with only SQL ? The solution should work on each of these kind of database server : MSSQL, PostgreSQL and MySQL.
Note
I can have multiple separators(footers) rows, not only two as in the example ...
SELECT a.rfa_yea ,
a.rfa_idx ,
a.rfa_dsp ,
a.rfa_tpr
FROM table1 a
INNER JOIN table1 c ON a.rfa_idx <= c.rfa_idx AND c.rfa_tpr = 'C'
GROUP BY a.rfa_yea ,
a.rfa_idx ,
a.rfa_dsp ,
a.rfa_tpr
ORDER BY MIN(c.rfa_idx), a.rfa_tpr DESC, a.rfa_idx
SQL Server Demo
MySQL Demo
PostgreSQL Demo
I found a solution by myself, below the SQL query if someone in the future will need to do something similar :
SELECT * FROM righfatture r
LEFT JOIN (
SELECT r1.rfa_tpr,r1.rfa_idx, COALESCE(r2.rfa_idx, -1) AS IDXP FROM righfatture r1
LEFT JOIN righfatture r2 ON r2.rfa_idx < r1.rfa_idx AND r2.rfa_tpr = r1.rfa_tpr
WHERE r1.rfa_tpr = 'C'
) j ON j.rfa_tpr = r.rfa_tpr AND r.rfa_idx = j.rfa_idx
ORDER BY CASE WHEN j.rfa_tpr IS NOT NULL THEN j.IDXP ELSE r.rfa_idx END
Solution is easy, problem is the problem...
Solution under assumption that last year should come first and rfa_idx comes behind rfa_yea.
select * from table1 order by rfa_yea desc, find_in_set(rfa_tpr, "C,A"), rfa_idx;
Problem is that you should not rely too much on increasing ids and the already mentioned design questions.
Marco
I think this is a database design issue. The "groups of rows" you are talking about have nothing in common besides the order of the rows.
I would suggest, adding a field and inserting a common value for these groups of rows, if possible. While this is not a convenient solution, I think a database design should reflect the way you want data to be organized.

Complicated MySQL Data Structure/Manipulation Problem

First off, I apologize for the length. This is kind of complicated (at least for me).
Background on the database:
I have a products, variables, and prices table. "Products" are the main information regarding a product (description, title, etc). "Prices" have information about each price (price, cost, minimum qty required, shipping cost, etc), as some products can have more than one price (a 10" widget is a different price than a 12" widget, for instance). "Variables" are variations to the product that do not change the price, such as color, size, etc.
Initially (when I built this database about 7 years ago) I had the variable information stored in the first price in a list of prices for the same product in a pipe-delimited format (yes, I know, badbadbad). This worked in general, but we've always had a problem, though, where sometimes a variable wouldn't be consistent among all the prices.
For instance, a Widget (product) may be 10" or 12" and sell for $10 and $20 (prices) respectively. However, while the 10" widget may be available in blue and red (variables), the 12" widget is only available in red. We ameliorated this problem by adding a little parenthetical statement in the incongruent variable like "Red (10" ONLY)". This sort of works, but customers are not always that smart and a lot of time is devoted to fixing mistakes when a customer selects a 12" widget in red.
I have since been tasked with modernizing the database and have decided to put the variables in their own table and making them more dynamic and easier to match with certain prices, as well as keep a more dummy-proof inventory (you can't imagine the nightmares).
My first step was to write a stored procedure on my test db (for when I do the conversion) to process all the existing variables into a new variable table (and label table, but that's not really important, I don't think). I effectively parsed out the variables and listed them with the correct product id and the product id they were initially associated with in the variable table. However, I realized this is only a part of the problem, since I (at least for the initial transformation of the database) want each variable to be listed as being connected to each price for a given product.
To do this, I created another table, like so:
tblvariablesprices
variablepriceid | variableid | priceid | productid
which is a many-to-many with the variable table.
Problems:
My problem now is, I don't know how to create the rows. I can create a left join on my prices and variables tables to get (I think) all the necessary data, I just don't know how to go through it. My sql is (mysql 5.0):
SELECT p.priceid, p.productid, variableid, labelid
FROM tblprices p
LEFT JOIN tblvariables v ON p.priceid = v.priceid
ORDER BY productid, priceid
This will get me every priceid and productid and any matching variable and label ids. This is good in certain instances, such as when I have something like:
priceid | productid | variableid | labelid
2 | 7 | 10 | 4
2 | 7 | 11 | 4
2 | 7 | 12 | 4
3 | 7 | (null) | (null) --- another price for product
because now I know that I need to create a record for priceid 2 and variableids 10, 11, 12, and then also for priceid 3 for that product. However, I also get results from this dataset for products with no variables, products with one price and multiple variables, and products with multiple prices and no variables, for instance:
priceid | productid | variableid | labelid
2 | 7 | 10 | 4
2 | 7 | 11 | 4
2 | 7 | 12 | 4
3 | 7 | (null) | (null)
4 | 8 | (null) | (null) --- 1 price no variables
5 | 9 | 13 | 5 --- mult vars, 1 price
5 | 9 | 14 | 5
5 | 9 | 15 | 6
5 | 9 | 16 | 6
6 | 10 | (null) | (null) --- mult price, no vars
7 | 10 | (null) | (null)
8 | 10 | (null) | (null)
Taking the above dataset, I want to add entries into my tblpricesvariables table like so:
variablepriceid | variableid | priceid | productid
1 | 10 | 2 | 7
2 | 11 | 2 | 7
3 | 12 | 2 | 7
4 | 10 | 3 | 7
5 | 11 | 3 | 7
6 | 12 | 3 | 7
7 | 13 | 5 | 9
8 | 14 | 5 | 9
9 | 15 | 5 | 9
10 | 16 | 5 | 9
I have thousands of records to process, so obviously doing this manually is not the answer. Can anyone at least point me in the correct direction, if not come up with a sproc that could handle this type of operation? I also would welcome any comments on how to better organize and/or structure this data.
Thank you so much for reading all this and helping me out.
How about:
SELECT DISTINCT b.variableid, a.priceid, a.productid
FROM tblprices AS a
JOIN tblprices AS b ON a.productid = b.productid
WHERE b.labelid IS NOT NULL
ORDER BY priceid;
+------------+---------+-----------+
| variableid | priceid | productid |
+------------+---------+-----------+
| 10 | 2 | 7 |
| 11 | 2 | 7 |
| 12 | 2 | 7 |
| 10 | 3 | 7 |
| 11 | 3 | 7 |
| 12 | 3 | 7 |
| 13 | 5 | 9 |
| 14 | 5 | 9 |
| 15 | 5 | 9 |
| 16 | 5 | 9 |
+------------+---------+-----------+
INSERTing into tblvariables is left as an exercise for the reader ;)
I think this should work:
SELECT v.variableid, p.productid, p.priceid
FROM tblvariables v, tblprices p
WHERE v.priceid IN (SELECT s.priceid
FROM tblprices s
WHERE s.productid = p.productid);
Next time, can you throw in create and insert statements to replicate your setup? Thanks.