Inserting Custom Auto-increment Field - mysql

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

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

MySQL: Count rows with similar not duplicated content as one

I am working with Codeigniter and its Query Builder class where I have a table with IDs and names.
Those names look like 1234_1a or 2345_2a where 1a can be 1b or 2a,2b,3a... and so on.
Now I want to count all these "1234" and "2345" but write them as one type.
So far I tried with:
$this->db->like('names', '1a', 'before');
$this->db->or_like('names', '1b', 'before');
return $this->db->count_all_results('table');
But the problem:
What if there is 3456_2a but no 3456_1a, than it doesn't work anymore...
id name
2 1212_1a
3 1243_1a
7 3142_1a
24 1243_2a
30 3142_2b
80 2315_2b
136 1243_3b
512 8562_1a
This is how I would like it:
Result:
name count
1212 1
1243 1
3142 1
2315 1
8562 1
If we always want to return a count value of 1, when the count of the number of rows in more than 1 ... then we aren't really returning a count.
And what is the pattern of the names... do they end with a digit and a letter, or is that underscore character important too?
What is to be done with name values such as 12345a or 5678_b2 or 11_22_3b? How are those to be handled?
Seems to me like we want to use a SQL query like this:
SELECT SUBSTRING_INDEX(t.name,'_',1) AS `foo`
, 1 AS `count`
FROM (
SELECT 2 AS `id`, '1212_1a' AS `name`
UNION ALL SELECT 3, '1243_1a'
UNION ALL SELECT 7, '3142_1a'
UNION ALL SELECT 24, '1243_2a'
UNION ALL SELECT 30, '3142_2b'
UNION ALL SELECT 80, '2315_2b'
UNION ALL SELECT 136, '1243_3b'
UNION ALL SELECT 512, '8562_1a'
) t
GROUP BY `foo`
ORDER BY `foo`
The inline view (derived table) is in the query for testing. Replace that with the table reference:
SELECT SUBSTRING_INDEX(t.name,'_',1) AS `foo`
, 1 AS `count`
FROM mytable t
GROUP BY `foo`
ORDER BY `foo`
The expression for foo may need to be adjusted, to get desirable behavior with values that don't follow the regular pattern. Consider name values with no underscore, with more than one underscore, with endings other than a digit. We could also include a WHERE clause to exclude rows that don't follow the pattern,
WHERE t.name REGEXP '_[0-9][a-z]$'
(only name values that end with underscore, digit, lowercase letter).
Without a tested SQL query, I wouldn't know what to implement in CodeIgniter Query Builder.

MySQL query to get that row which has the last day of first month of date field

In my database I have a field named DateLastSaved:
Suppose the values are:
1. 2016-05-12 08:07:00,
2. 2016-05-22 09:06:00,
3. 2016-05-22 09:06:00,
4. 2016-06-13 09:00:00,
5. 2016-06-13 09:00:00
I wan't such query that would return me that row whose DateLastSaved field has the minimum month, in above case "5" and the maximum date of that month, which is 2, 3, but my query should return one result, i.e either 2 or 3.
I am using the following query:
SELECT MIN(LAST_DAY(DateLastSaved))FirstMonth
FROM InitialLog
WHERE FileName='Dr. Adam Kotowski Patient Names.doc'
But it is returning me the first date, that is, minimum, not the maximum one. Any suggestions?
Try this:
SELECT *
FROM InitialLog
WHERE MONTH(DateLastSaved) = (SELECT MIN(MONTH(DateLastSaved)) FROM InitialLog)
ORDER BY DAY(DateLastSaved) DESC LIMIT 1
Demo here

Cannot use REPLACE function properly in 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;

How to select row with same id and add its field value

I have table medicine record with fields
Name qunty min expiry
a 2 3 14/2/2012
b 4 1 15/12/2010
a 5 3 16/5/2012
I have to select medicine which has qunty less than min value . Two rows can exist with same name but with different expiry . So in that condition i have to add qunty of same name row and than match with min value .
try this one,
SELECT Name, `min`, SUM(qunty) totalQunty
FROM medicine
GROUP BY NAME, `min`
HAVING SUM(qunty) < `min`
SQLFiddle Demo
in that case i have also a question with you, are min values constant for the same name?