MySQL - get date column from a table - mysql

I have a MySQL db with a MappingTable which consists of two columns. First column is a date column and another is ID - Autoincrement int column. I created this table for mapping dates and the ID's. When I query the date column with dates to retrieve the ID, no rows are getting selected. Any reason?
I tried
date_format in the SELECT query
str_to_date while checking in the WHERE clause
Compared like current_date > "2016-07-12" AND current_date <= "2016-07-12"
IfI compare LIKE "2016-07-1%" I'm getting matching rows but if I select "2016-07-12%" though there are matching rows, it is giving 0 rows.
I defined my column as DATE only.
Anything I'm missing here?
CREATE TABLE `mapping_table` (
`Current_date` date DEFAULT NULL,
`id` int(11) NOT NULL AUTO_INCREMENT, PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=26 DEFAULT CHARSET=utf8;
My question is, I want to select something like this.
select id from mapping_table where current_date="2016-07-12";
I tried with all approaches as mentioned above, but no rows are not retrieving.

use back tick on columns and table names so it wont be read/parse as keyword.
select `id` from `mapping_table` where `current_date` = "2016-07-12";

In the sample you provided you should use a date_format
select id from mapping_table where current_date= DATE_FORMAT("2016-07-12",'%Y-%d-%m') ;
or use a range
select id from mapping_table where current_date
BETWEEN DATE_FORMAT("2016-07-12",'%Y-%d-%m')
and DATE_FORMAT("2016-07-10",'%Y-%d-%m')

Related

insert a new record into a mysql table with one of the values incremented by 1

I've got the following table:
productId price
1 price_value1
2 price_value2
3 price_value3
I would like to insert a new product into the table and assign it a new productId. In this case its value equals to 4.
So I want my new table to look like so:
productId price
1 price_value1
2 price_value2
3 price_value3
4 price_value4
So as far as I understand, in order to do that I have to somehow retrieve the max value of productId and insert it using INSERT INTO mytable VALUES (productId + 1, price_value4).
But how do I find out the maximum value of productId?
I tried INSERT INTO mytable VALUES (SELECT MAX(productId) + 1 FROM mytable, price_value4) but it didn't work.
This should Work:
Select the max(productID) and price_value4 as a columns from mytable and insert the result.
INSERT INTO mytable (SELECT MAX(productId) + 1, 'price_value4' FROM mytable);
However, if you are not going to jump some number you can just add an auto increment id key to product_id and then you will have only to insert the price, the product ID will be incremented automatically..
This will do so :
ALTER TABLE mytable
MODIFY COLUMN `productId` INT(10) UNSIGNED PRIMARY KEY AUTO_INCREMENT;
you can change INT(10) with the INT(5) for example depanding on the size you want to give to your productId column
EDIT :
In return to the OP question in comments why his solution wouldn't work
Some suggetions says you have to make the SELECT statment in insert always between parenthesis
INSERT INTO mytable VALUES ( (SELECT MAX(ID)+1 FROM mytable) , price_value4)
.. In my Case it Return
(1093): You can't specify target table
'mytable' for update in FROM clause
AND HERE IS WHY (Quoting From the documentation)
When selecting from and inserting into the same table, MySQL creates
an internal temporary table to hold the rows from the SELECT and then
inserts those rows into the target table. However, you cannot use
INSERT INTO t ... SELECT ... FROM t when t is a TEMPORARY table,
because TEMPORARY tables cannot be referred to twice in the same
statement
BUT there is away to overcome by using a query instead of the table itself in the FROM, which has the effect of copying the requested table values instead of referencing the one that you are updating..
INSERT INTO mytable VALUES (
(SELECT MAX(ID)+1 FROM (SELECT * FROM mytable ) as mytmp ),
'price_value4');
OR (Quoting From the documentation)
To avoid ambiguous column reference problems when the SELECT and the
INSERT refer to the same table, provide a unique alias for each table
used in the SELECT part, and qualify column names in that part with
the appropriate alias.
INSERT INTO mytable Values ( (SELECT MAX(ID)+1 FROM mytable as mytmp) , 'price_value4')
This is a duplicate question. In order to take advantage of the auto-incrementing capability of the column, do not supply a value for that column when inserting rows.
A simple syntax to create table
CREATE TABLE Product (
productId MEDIUMINT NOT NULL AUTO_INCREMENT,
price INT NOT NULL,
PRIMARY KEY (productid)
);
While inserting supplied default or leave column as blank or supplied value as NULL. Take a look at below code snippet.
INSERT INTO Product (price) VALUES
('10'),('20'),('4'),
('30');
refer this link

If using sum>100, sums under 100 will still show

I have a table with some data. Many of these data have the name ICA Supermarket with different sums for every data. If I use the following SQL query, it will also show data with the sum under 100. This applies also if I change >= '100' to a higher digit, for an example 200.
SELECT *
FROM transactions
WHERE data_name LIKE '%ica%'
AND REPLACE(data_sum, '-', '') >= '100'
If I change >= to <= no data will show at all. Here's how the table looks like:
CREATE TABLE IF NOT EXISTS `transactions` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`data_name` tinytext NOT NULL,
`data_sum` decimal(10,2) NOT NULL
UNIQUE KEY `id` (`id`)
)
Is it because data_sum is a DECIMAL? How can I prevent this from happening? I want to use DECIMAL for sums :)
Note: data_sum will also contain sums that are above minus.
REPLACE(data_sum, '-', '') returns a string. Also '100' is a string. So a string compare will be used. You should use ABS function:
SELECT *
FROM transactions
WHERE data_name LIKE '%ica%'
AND ABS(data_sum) >= 100
Are you looking for values >= 100 and <= -100? Or just values <= -100.
If the latter, then
... AND data_sum <= -100
This applies to DECIMAL, INT, FLOAT, etc.
Every table 'needs' a PRIMARY KEY. Promote that UNIQUE to PRIMARY.

find_in_set return different value

I have a table with this declaration:
CREATE TABLE foobar (
id int(11) NOT NULL AUTO_INCREMENT,
dow set('q','w','e','r','t','y', 'u') NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT;
With those values inside:
id, dow
'1', '1,3,6'
'1', '2,4,7'
Those query returns different values.
SELECT dow, FIND_IN_SET('4', dow) FROM (SELECT * from pippo.pluto) as B;
SELECT dow, FIND_IN_SET('4', dow) FROM pippo.pluto as B;
The first query returns those results:
'1,3,6', '0'
'2,4,7', '2'
The second query returns those results:
'1,3,6', '0'
'2,4,7', '4'
Why?
Tested against 5.6 and 5.7 mysql version.
Edit:
This behaviour remains the same if I use the mysql views.
CREATE VIEW selectInner AS SELECT dow, FIND_IN_SET('r', dow) FROM (SELECT * from pippo.foobar) as B;
CREATE VIEW selectDirect AS SELECT dow, FIND_IN_SET('r', dow) FROM pippo.foobar as B;
There are two things interacting here:
"If the first argument is a constant string and the second is a column of type SET, the FIND_IN_SET() function is optimized to use bit arithmetic." per FIND_IN_SET docs
One of the two queries operates directly on the table, and the second on a derived table.
The behaviour demonstrates this:
When operating directly on the table (where dow refers to the defined column in that table's metadata), FIND_IN_SET returns the index of the entry in the column's definition
When operating on a derived table (where dow refers to a derived column), FIND_IN_SET returns the index of the entry in the derived value
This is clear if you search for e.g. y and u in a column containing q,e,y,u: you'd get 6 and 7 when querying the table directly, where dow is a SET containing q,w,e,r,t,y,u and FIND_IN_SET uses bitwise optimizations; but 3 and 4 when searching the derived table, where dow is the string containing q,e,y,u for that row.

Mysql min function returning incorrect result

I have Book_Details table
CREATE TABLE `Book_Details` (
`bookId` int(11) NOT NULL,
`book_name` varchar(45) DEFAULT NULL,
`book_desc` varchar(45) DEFAULT NULL,
`price` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
And this table contains three rows
insert into book_details values (1,'Java for beginners','Java Book for beginners',99);
insert into book_details values (2,'Learn Advanced java','Advanced Java Book',223);
insert into book_details values (3,'Learn Practical java','Practical Java Book',78);
While I am executing the below query
select min(price) min_price,book_name from book_details;
I was expecting below result
min_price | book_name
-----------------------
78 | Learn Practical java
but surprisingly I am getting below output
min_price | book_name
-----------------------
78 | Java for beginners
Could someone please explain me why I am getting this output? Where I am wrong?
My MYsql DB version is 5.5.38. Please help.
You get the minimum price and arbitrary values for the other columns. You are using a MySQL extension that you should just simply stop using -- always be sure that all columns in the select that are not arguments to aggregation functions -- are in the group by.
Try this instead:
select bd.*
from book_details
order by price
limit 1;
This SELECT statement is not proper SQL but MySQL accepts it. The query always returns a single row, but several books may have the same price and the query could return any of the book_name values. You should use a SELECT that returns multiple rows for all the books that have the minimum price
select price,book_name from book_details where price = (select min(price) from book_details)

MySQL: SUM in WHERE clause

I've got this table
CREATE TABLE `subevents` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(150) DEFAULT NULL,
`content` text,
`class` tinyint(4) NOT NULL DEFAULT '1',
PRIMARY KEY (`id`)
) ENGINE=MyISAM
Each row can have a different value in the 'class' field.
I'd like to select any number of rows, ordered randomly, as long as the sum of the values in the 'class' field is equal to 100.
How could I accomplish it directly in the MySQL query without doing it later in PHP?
Thanks everybody!
By "ordered randomly" I assume you mean that the order of the rows doesn't matter but no row can be used more than once. So you are looking for a combination of rows in which the sum of class equals 100. Use the brute force method. Randomly generate possible solutions until you find one that works.
delimiter //
CREATE PROCEDURE subsetsum(total)
BEGIN
DECLARE sum INTEGER;
REPEAT
CREATE OR REPLACE VIEW `solution`
AS SELECT * FROM `subevents`
WHERE 0.5 <= RAND();
SELECT SUM(`class`) INTO sum FROM `solution`;
UNTIL sum = total END REPEAT;
END
//
delimiter ;
CALL subsetsum(100); /* For example */
SELECT * FROM `solution`;
I have tested this with tables having a TINYINT column of random values and it is actually reasonably fast. The only problem is that there is no guarantee that subsetsum() will ever return.
I don't think this is possible with only SQL...the only thing which comes to my mind is to redo a the sql query as long the sum isn't 100
But I have no clue how to select a random number of rows at once.