Cannot use REPLACE function properly in MySQL - mysql

I have an SQL table whose columns are State_Code, School_Code and School_Type.
Sample Data:
State_Code School_Code School_Type
01 01014874 1
01 01018790 2
1 10189900 1
1 10277689 1
*(Note: 1st and 2nd digit of School_Code is the actual state-code while its 3rd and 4th digit is the District_Code of that particular state)*
Now, if I fire this query:
Select COUNT(School_Code) from Table1 where State_Code='1'+0;
It will return the number of schools present in the state, with code '1'; i.e. 4;
But if I want to retrieve the number of schools present in a state DISTRICT-WISE; I would fire this query:
Select State_Code,SUBSTRING(School_Code,3,2) AS District_Code,COUNT(School_Code) AS Number_of_Schools_In_District FROM Table1 GROUP BY State_Code+0;
This query returns me this output:
State_Code District_Code Number_of_Schools_In_District
01 01 2
1 18 1
1 27 1
But the correct output is:
State_Code District_Code Number_of_Schools_In_District
01 01 3
1 02 1
This is due to the incorrect data entered by user in SQL table for column School_Code. State '1' and '01' are actually the same state i.e. '01'. But since School-Code in the 3rd and 4th row does not start with '0', this lead to the incorrect behavior in the output.
So to resolve this problem, I will have to use this logic:
*If number of characters in State_Code is 1 and School_Code does not start with '0', then a '0' should be prefixed to the School_Code value to get the correct District_Code value.*
I tried this:
Select State_Code,SUBSTRING(School_Code,3,2) AS District_Code,COUNT(School_Code) AS Number_of_Schools_In_District FROM Table1 WHERE IF CHARACTER_LENGTH(State_Code)=1 AND School_Code NOT LIKE '0%' THEN REPLACE(School_Code,School_Code,CONCAT(0,School_Code)) END IF GROUP BY State_Code+0, SUBSTRING(School_Code,3,2)+0;
My expectation was if any value in State_code is a single digit and its corresponding School Code does not start with '0', then this will append '0' to it and then calculate district code taking the 3rd and 4th digit. But this does not happen. Still I get the error.
Note: I don't want to update original SQL table values.
Any help will be appreciated. Thanks in Advance!

Try below query
Select State_Code, IF(CHARACTER_LENGTH(State_Code)=1, SUBSTRING(School_Code,2,2), SUBSTRING(School_Code,3,2)) AS District_Code,COUNT(School_Code) AS Number_of_Schools_In_District FROM Table1 WHERE GROUP BY State_Code+0, SUBSTRING(School_Code,3,2)+0;

Related

How can I separate a single column into 3 separate columns

Want to execute a query to view single date-month-year time column to separate date column, month column and year column.
eg
joining_date
01-JAN-22 12.00.00AM
to
joining_date|joining_month|joining_year
01 | JAN | 22
You have some ways of doing this:
If your data is always in this 01-JAN-22 12.00.00AM format , no matter what comes after 22, you can use substring.
select substring('01-JAN-22 12.00.00AM',1,2) as joining_date,
substring('01-JAN-22 12.00.00AM',4,3) as joining_month,
substring('01-JAN-22 12.00.00AM',8,2) as joining_year;
Result:
joining_date joining_month joining_year
01 JAN 22
Another option is converting the string to proper date datatype an use MySQL functions, like :
select DAY(str_to_date('01-JAN-22 12.00.00AM', "%d-%b-%y")) as joining_date,
MONTH(str_to_date('01-JAN-22 12.00.00AM', "%d-%b-%y")) as joining_month,
YEAR(str_to_date('01-JAN-22 12.00.00AM', "%d-%b-%y")) as joining_year ;
Result:
joining_date joining_month joining_year
1 1 2022
Fiddle
Use YEAR, MONTH and DAY syntax:
SELECT
YEAR(`joining_date`) as joiningYear,
MONTH(`joining_date`) as joiningMonth,
DAY(`joining_date`) as joiningDay
FROM tableName
If you want your month name, then use MONTHNAME:
SELECT
YEAR(`joining_date`) as joiningYear,
MONTHNAME(`joining_date`) as joiningMonth,
DAY(`joining_date`) as joiningDay
FROM tableName

Finding count of unique value before a character

I have a some entries in database table rows as follows.
101 - 1
101 - 2
101 - 3
102 - 1
102 - 2
102 - 3
103
I need to get the result of SELECT Query for count as '3' since there are 101 and 102 are the only number before the -.
So is there any way to find the unique value in db table columns before a character?
EDIT : I have entries even without the - .
In case your entries have always the format you have provided us, you just have to find the position of the '-' character, split the values, get the first n characters and count the distinct values
This works for SQL Server, otherwise informs us about what DBMS you are using or replace the functions with the ones of your DBMS on your own
SELECT COUNT(DISTINCT SUBSTRING(val,0,CHARINDEX('-', val))) from YourTable
create table T1
(
id int primary key identity,
col1 varchar(20)
)
insert into T1 values('101 - 1'),('101 - 2'),('101 - 3'),('102 - 1'),('102 - 2'),('102 - 3')
select SUBSTRING(col1,0,CHARINDEX(' ',col1)) as 'Value',count(*) as 'Count' from T1 group by SUBSTRING(col1,0,CHARINDEX(' ',col1))

mysql count last_column_data not working

I have a table name: serial
ID Name Date
---- -------- -----------
1 George 2013-07-24
2 John 2013-07-24
3 Thomas 2013-07-25
4 James 2013-07-31
5 Andrew 2013-07-20
6 Martin 2013-07-24
7 William 2013-07-21
8 Zachary 2013-07-25
9 Millard 2013-07-31
10 Chester 2013-07-24
Now I need count of the last value of column Date dynamically, here the last value of column Date is 2013-07-24, so the count is 4. But if some data insert into ID#11 with the Date value 2013-07-31,then the count will be 3.
I have made a function to do this:
function countdate(){
$SQL = "SELECT count( `ID` ) as countdate FROM serial WHERE `Date` = 'LAST(Date)'";
$result = mysql_query($SQL);
$cd= mysql_fetch_array($result);
return $cd['countdate'];
}
But it is not working. But if I put directly '2013-07-24' instead of 'LAST(Date)' into the function, it gives the result. I think 'LAST(Date)' is not working here dynamically.
What is the mistake here or any other way......By the way, I am not very expert coder, and it's my first question, so...
Here MAX(value) might not work as different dates are insert into here. MAX(value) may work here if we consider the column 'ID'. But the values of the column 'Date' not incremental here.
Try with a sub query:
SELECT COUNT(*) countdate FROM serial WHERE `Date` = (SELECT `Date` FROM serial order by ID desc limit 1)

Inserting Custom Auto-increment Field

I need a query to insert an auto-increment field in the following format:
150001 (15 is last two digit of year 2015 and an id which increments like 0001, 0002, 0003 etc)
Till year 2016 March it need to show as 2015 only (15) after March it should change to 2016 (16). Because that's when our financial year ends. Is it possible to achieve the same with a query:
150001
150002
160001 etc
It can be something like that(first assumption):
SELECT CONCAT(
IF(DATE_FORMAT(NOW(), '%m')<3,
DATE_FORMAT(t.created, '%y')-1,
DATE_FORMAT(t.created, '%y')),
LPAD(
id + 1 - (
SELECT MIN(id) FROM Tbl t2 WHERE
IF(DATE_FORMAT(NOW(), '%m')<3,
DATE_FORMAT(t2.created, '%y')-1,
DATE_FORMAT(t2.created, '%y')) =
IF(DATE_FORMAT(NOW(), '%m')<3,
DATE_FORMAT(t.created, '%y')-1,
DATE_FORMAT(t.created, '%y'))
),
4,
'0') super_id
FROM Tbl t;
Here's the trick...
-->> 1st: Get the last 2 digit of the year
SELECT RIGHT(YEAR(NOW()),2);
-->> 2nd: Pad 4 digit zeros
SELECT RIGHT(CONCAT('0000',1),4);
-->> 3rd: Concat the two query above, assuming that the column name is `ID_Column`
SELECT CONCAT(RIGHT(YEAR(NOW()),2), RIGHT(CONCAT('0000',ID_Column),4));
You can now insert the result of the 3rd query into your id.
Note: if your id is integer, you have to convert it into varchar
sample:
-->> Concat the two query above, replacing the column name value as 1
SELECT CONCAT(RIGHT(YEAR(NOW()),2), RIGHT(CONCAT('0000',1),4));
result: 150001

how to add two millisecond column in mysql

I have table as shown below
gid code time qid
1 123 08:108 15
1 145 11:012 15
1 145 11:216 16
1 123 12:102 16
Now U want to group the 'gid' and add the two time with same code column (ex: i am taking 123, calculating the time (08:108+12:102)/2. Divided by '2' because code 123 appears two time,if it appears three time then divided by 3 this should be dynamic.
I want the result should be
gid code time
1 123 10:105
1 145 11:114
i tried using this query
SELECT sum(time) FROM results group by code; // result in integer values
and SELECT timestamp(sum(time)) FROM results group by code; // result is null
Your time field does not look like it is of the type TIME. A TIME field is in the format HH:MM:SS and doesn't allow to store milliseconds. The MySQL Documentation states that trailing fractions of seconds are allowed in date and time values, but are discarded and not stored.
Your time field looks like it is a varchar and while you can use functions like SUM() or AVG() on that, your notation seconds:milliseconds is wrong.
You can use the following query:
SELECT code,AVG(REPLACE(time,':','.')) FROM results group by code
This replaces the : in your value with ., creating a float number AVG() can handle correctly.
The result:
code AVG(REPLACE(time,':','.'))
123 10.105
145 11.114
Of course this will create more operations on the SQL server. The best way would be to change your column definition to FLOAT and store your seconds and milliseconds as a float:
code time
123 8.108
145 11.012
145 11.216
123 12.102
The result of SELECT code,AVG(time) FROM results GROUP BY code:
code AVG(time)
123 10.1050000190735
145 11.1139998435974
You can use the avg aggregate function on a time column - you'd just need to convert it back to time when you're done, and use time_format if the default format doesn't suit you:
SELECT gid, code, TIME_FORMAT(TIME(AVG(`time`)), '%H-%i.%f')
FROM mytable
GROUP BY gid, code