Unable to get "inbetween" records if year is different - php

I am having this unique bug
TABLE : tbl
id | title | iscancel | sold_dt
id: UID
Title : varchar
iscancel : 0/1
sold_dt : timestamp
select * from tbl where iscancel = 0 and DATE_FORMAT(sold_dt,"%m/%d/%Y") BETWEEN "06/01/2015" AND "03/01/2016" GROUP BY day(sold_dt) order by (sold_dt) asc
(note that year is different)
0 records returned
but if i do
select * from tbl where iscancel = 0 and DATE_FORMAT(sold_dt,"%m/%d/%Y") BETWEEN "06/01/2015" AND "12/01/2015" GROUP BY day(sold_dt) order by (sold_dt) asc
or
select * from tbl where iscancel = 0 and DATE_FORMAT(sold_dt,"%m/%d/%Y") BETWEEN "01/01/2016" AND "03/01/2016" GROUP BY day(sold_dt) order by (sold_dt) asc
(note that year is same)
-I'll get some records
*Used DATE_FORMAT because my calendar is giving me MM/DD/YYYY (i can not change since it might affect other areas)
what i am doing wrong?

Instead of converting the stored value into another format try changing the parameter itself to correct format. If you cant do it on your website you can do it in your query as well
sold_dt BETWEEN
STR_TO_DATE('06/01/2015', '%m/%d/%Y') AND STR_TO_DATE('03/01/2016', '%m/%d/%Y')

Try by passing static dates into DATE_FORMAT() function
select * from tbl where iscancel = 0 and DATE_FORMAT(sold_dt,"%m/%d/%Y") BETWEEN DATE_FORMAT("06/01/2015","%m/%d/%Y") AND DATE_FORMAT("03/01/2016","%m/%d/%Y") GROUP BY day(sold_dt) order by (sold_dt) asc

Related

Sort table id's cut by a hyphen (PHP/MySQL)

I have a MySQL table that I would like to display in a decreasing way. The problem is that the ID is broken by a dash ... So MySQL does not understand my request.
SELECT * FROM table WHERE id ORDER BY id DESC
results
20633-18489
184945-190028
183661-188782
1575-1610
but I want this order
184945-190028
183661-188782
20633-18489
1575-1610
What is the solution in php?
What you are looking for is the REPLACE() FUNCTION
so your query would look like:
SELECT *, REPLACE(id, '-' , '') AS sortable_id WHERE id ORDER BY sortable_id DESC
In the SQL statement, we could do this:
ORDER BY id + 0 DESC
or this:
ORDER BY SUBSTRING_INDEX(id,'-',1) + 0 DESC
The "+ 0" is going to cause the string before it to be evaluated in a numeric context. That will return a number. And then the ordering will be by the numeric value.
As a demonstration
SELECT t.id
, t.id + 0 AS id0
, SUBSTRING_INDEX(t.id,'-',1)+0 AS id1
FROM ( SELECT '184945-190028' AS id
UNION ALL SELECT '183661-188782'
UNION ALL SELECT '20633-18489'
UNION ALL SELECT '1575-1610'
) t
ORDER BY t.id + 0 DESC
returns
id id0 id1
------------- ------ ------
184945-190028 184945 184945
183661-188782 183661 183661
20633-18489 20633 20633
1575-1610 1575 1575
Note: this is ordering only on the part of the id before the dash. This doesn't specify what order id values that "match" on the leading portion will be returned in. MySQL would be free to return these two in any order.
456-42
456-321
We can add more expressions to the ORDER BY clause to make the order of these deterministic.

How to order non-integer records in MySql?

I'm trying to order some MySQL records by DESC order and get the last record added.
These are my records and they're all stored as strings:
1/2017
1/2018
2/2017
2/2018
3/2017
I want to get the value 1/2018. The records are based on the current year
and the last record added was 1/2018 and the next will be 2/2018 and so on.
this is my query:
SELECT NoControl FROM cita ORDER BY NoControl DESC LIMIT 1
but I'm getting 3/2017 as the last record.
If you have ever the same pattern m/yyyy you could use some string manipulation function eg:
SELECT NoControl
FROM cita
ORDER BY right(NoControl,4), DESC left(NoControl,1) DESC LIMIT 1
But you should avoid of store date values as string ..
or convert the string as a proper date
SELECT NoControl
FROM cita
ORDER BY str_to_date(NoControl,'%m/%Y') DESC LIMIT 1
Use SUBSTRING_INDEX to extract the first and second part, CAST as integer and sort:
SELECT str
FROM testdata
ORDER BY
CAST(SUBSTRING_INDEX(str, '/', -1) AS UNSIGNED) DESC,
CAST(SUBSTRING_INDEX(str, '/', 1) AS UNSIGNED) DESC
LIMIT 0, 1
SQL Fiddle

MySQL ORDER BY multiple column ASC and DESC not working as expected

I have 1 mySQL table. Table entries are:
I want to show a list under 2 conditions. First the highest right_answers and also depending on lowest time_spent
I used this sql code to retrieve the list
mysql_query("SELECT * FROM `table_name` WHERE `contest_id` = '2' ORDER BY right_answers desc,time_spent")
I am getting this output:
My expected output shoulb be:
I tried many times with different queries but the result is still wrong. Could you give me some solutions?
Thanks in advance!
I guess your time_spent column has a VARCHAR(x) datatype, not a numeric datatype. So, MySQL is ordering the values in alphabetical order like this.
1
10
259
46
5
6
7894
9
Your best repair of this problem is to change the datatype of that column to INT. (Also repair the right_answers column.)
ALTER TABLE table_name CHANGE COLUMN time_spent time_spent INT NOT NULL DEFAULT '0'
ALTER TABLE table_name CHANGE COLUMN right_answers right_answers INT NOT NULL DEFAULT '0'
Then your ORDER BY operation will work numerically and give you expected results.
Your second best repair is to coerce the data to numeric in your ORDER BY clause, like this:
ORDER BY 0+right_answers DESC, 0+time_spent ASC
You try this way,I am trying its working
mysql_query("SELECT * FROM table_name WHERE contest_id = '2' ORDER BY table_name.right_answers desc,time_spent ASC");
Try something like this:
SELECT *
FROM `table_name` WHERE `contest_id` = '2'
ORDER BY SUBSTRING( time_spent
FROM 1
FOR 1 ) ASC , right_answers DESC
Try this
mysql_query("SELECT * FROM table_name WHERE contest_id = '2' and id in (SELECT ID FROM table_name ORDER BY right_answers DESC) ORDER BY time_spent ASC")
interchange column names and try again.

MySQL PHP - SELECT WHERE based on a different position

Is it possible to sort data based on an order value set on a certaid IDs?
I want to make the following:
ID - Position
1 - 3rd
2 - 4th
3 - 5th
4 - 6th
10 - 7th
11 - 8th
12 - 9th
13 - 10th
14 - 11th
83 - 2nd
84 - 1st
I’ve been trying to implement this one, but it doesn’t generate the correct order:
SELECT * FROM table_name WHERE id IN (1,2,3,4,5,6,7,81,82) ORDER BY id = 3 DESC, id = 4 DESC, id = 5 DESC, id = 6 DESC, id = 7 DESC, id = 8 DESC, id = 9 DESC, id = 1 DESC, id = 2 DESC
If I was unclear, please ask me for more info. Thank you in advance.
SELECT * FROM table_name WHERE id IN (1,2,3,4,5,6,7,81,82) ORDER BY CAST(SUBSTR(position, 1, CHAR_LENGTH(position) - 2) as unsigned)
Yes you can use order by FIELD , below is an example you can modify the way you want.
SELECT * FROM
table_name
WHERE id IN (1,2,3,4,5,6,7,81,82)
order by FIELD(id,3,4,5,1,2,6,7,81,82)
http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_field
I think this is sufficient you dont need to add anything in this.
SELECT * FROM table_name WHERE id IN (1,2,3,4,5,6,7,81,82) ORDER BY id DESC
or you can use, if want in particular sequence of ID,
SELECT * FROM table_name WHERE id IN (1,2,3,4,5,6,7,81,82) order by FIELD(id,3,4,5,6,7,8,9,1,2)
or you can use ORDER BY CASE

Select adjacent records in Mysql

Assuming this table is ordered by date
id | date | customer
3 | 2009-10-01| Frank
1 | 2010-10-11| Bob
4 | 2010-11-01| Mitchel
2 | 2010-11-02| Jim
I would like to make a query so that knowing ID = 4 the resulting rows are
$row[0]['id'] == 1 //previous
$row[1]['id'] == 4 //most recent/current
$row[2]['id'] == 2 //next
A mysql only solution would be best, but if there is an elegant php solution that would be cool as well.
As the table IS sorted by date column, you can run following queries to get it:
For previous row:
select * from tablename where `date` < (select `date` from tablename where id=4) order by `date` desc limit 1
For current row:
select * from tablename where id=4
For next row:
select * from tablename where `date` > (select `date` from tablename where id=4) order by `date` asc limit 1
Output: These three queries return the result (one by one) as following:
id date customer
1 2010-10-11 Bob
4 2010-11-01 Mitchel
2 2010-11-02 Jim
Since you are ordering by date, but basing the row you want the adjacent rows on id, your going to have to do 2 queries. The first to determine the date for the ID you have selected, the second to get the adjacent rows.
Step 1 - Get the date
Select date
FROM yourtable
WHERE id = 4
Step 2 - Get all the rows
SELECT *
FROM yourtable
WHERE date IN ( (select MAX( date ) from yourtable where date < $datefromquery1)
, $datefromquery1
, (select MIN( date ) from yourtable where date > $datefromquery1)
)
The LIMIT function can take two arguments, an offset and a number of rows to return. In your case, you want the offset to be (the number of rows with dates before the desired row) - 1, or in this case 2 - 1 = 1, and the number of rows to be three. So the SQL you want is
SELECT * FROM customers ORDER BY date ASC LIMIT 1,3;
and the number "1" will be the result of the query
SELECT COUNT(*)-1 FROM customers WHERE date > "2010-11-01";
I don't believe MySQL will let you use a subselect or function value as the argument of LIMIT, so you'll have to store that using PHP and construct the next query that way.

Categories