Finding Maximum value from a Varchar Field - php

I have a database field know as SCORES which has Scores
the value may be like the following
123
14
56*
342
423*
I am storing that in a Varchar Field in the database.
Suppose If I convert that to a integer a datatype, then I can write
max(SCORES) and get the Maximum score or Highest Scores.
But Integer doesnot allow special character like *.
(Here * represent some clause for that scores)
To accomadate that I have made that to the varchar.
What will be best way to get the Highest score very easily with minimum programming method.
So that If I execute a query I should be get the answer as
423*
Please suggest me

The best way to handle this situation is to change you table structure to make
SCORES of int data type.
Add a new field in the table called
clause
If most of your SCORES are without a
clause, you must normalize the table
to move the clause field to a
different table.

You should change table schema ...
SELECT scores
FROM tablename
ORDER BY replace(scores, '*', '') DESC
LIMIT 1;

I think your query should be generic for getting maximum score, today you have only '*' is attached with score but in future may be you use some others character or may be you use some combination of character so you should take care of that scenario.
so i thing it will be better if you create a user define function which takes varchar as a input and return number from input string like if you pass '1234*' then function will return 1234 and if you pass 1234** it will return 1234.
CREATE FUNCTION dbo.ParseNumeric
(
#string VARCHAR(8000)
)
RETURNS VARCHAR(8000)
AS
BEGIN
DECLARE #IncorrectCharLoc SMALLINT
SET #IncorrectCharLoc = PATINDEX('%[^0-9A-Za-z]%', #string)
WHILE #IncorrectCharLoc > 0
BEGIN
SET #string = STUFF(#string, #IncorrectCharLoc, 1, '')
SET #IncorrectCharLoc = PATINDEX('%[^0-9]%', #string)
END
SET #string = #string
RETURN #string
END
GO
then use:
select max(cast(dbo.ParseNumeric(score) as int)) from tableName

SELECT MAX(CAST(scores AS SIGNED))
FROM tablename
But this query will be quite slow, since it cannot be optimized using indexes.

You could move the asterisk to a new field (depends if you need it or not). After that you can change the datatype.
UPDATE
tableName
SET
score = REPLACE(score, '*', ''),
specialCharField = IF(CONTAINS(score, '*'), '*', '');

Try this SQL:
SELECT MAX(CONVERT(REPLACE(FIELD,'*',''),signed)) FROM TABLE
It:
Replace the * from your varchar
Covnert the result into integer (signed)
Select the MAX value
EDIT 1:
I have been tring the SQL with some data, i have a table with one field (varchar, no key), I've inserted 62962 values (one each 1000 have a '*', the results as follow :)
SELECT MAX(CONVERT(REPLACE(FIELD,'*',''),signed)) FROM TABLE
Took 0.0666sec.
SELECT scores FROM tablename ORDER BY replace(scores, '*', '') DESC LIMIT 1;
Took 0.089sec to execute and got the wrong value:
HTH :)

Related

mysql query for selecting data in multiple columns

I have table with 10 columns and I want to check input value in where clause of the MySQL query.
I want to do something like this. But, when I use this query I am getting an error.
for example :
SELECT * FROM user_data
where poll_title='$poll_title'
and '$voter' IN (user_vote_1,user_vote_2,user_vote_3...user_vote_10)
order by idpoll ASC
user_vote_1 to 10 (value is null'ed in the database) and I want to retrieve only that rows from a column which have $voter value.
I think you need this comparison (Not Sure OfCourse) :-
SELECT * FROM user_data
where poll_title = "$poll_title"
and (user_vote_1 = "$voter"
OR user_vote_2 = "$voter"
OR user_vote_3 = "$voter"
OR user_vote_4 = "$voter"......OR user_vote_10 = "$voter")
order by idpoll ASC
If I've understood what you want to do - return only the column with the value - then would coalesce do the job? This assumes that the value in user_vote_n will either match the value you're looking for or be null, since coalesce returns the first non-null argument.
(untested)
select coalesce(user_vote_1, user_vote_2, user_vote_3, ) as UserVote from user_data
where coalesce(user_vote_1, user_vote_2, user_vote_3, ) = '$voter';
That aside, this looks like a structure that could do with normalising - a single 'user_vote' column and a single 'user_vote_number' column.

Update the first row mysql php

I'm trying to update my first row in my database. I use the Limit 1 to only update the first row but nothing is happening. There are definitely matching rows but nothing changes in the database.
Here is the code:
foreach ($player_fromsite as $match_player_in_game) {
//$querytwo = 'INSERT INTO `'.$tablename.'` '.' (`'.$match_player_in_game.'`) '.'VALUES'.'("' . 'yes' . '")';
$querytwo = 'UPDATE '.$tablename.' SET `'.$match_player_in_game.'` = "'.'yes'.'" WHERE `'.$match_player_in_game.'` = "'.'NULL'.'" LIMIT 1';
$querythree = 'UPDATE '.$tablename.' SET `'.$match_player_in_game.'` = "'.'yes'.'" WHERE `'.$match_player_in_game.'` = "'.'NULL'.'" LIMIT 1';
for($a=0;$a<11;$a++){
if($match_player_in_game == $home_players[$a]){
// Insert a row of information into the table "example"
mysql_query($querytwo) or die(mysql_error());
}else{
mysql_query($querythree) or die(mysql_error());
}
}
}
Is the query correct?
In MySQL use IS NULL to compare with NULL.
For example: "UPDATE table SET field = 'yes' WHERE field IS NULL"
NULL isn't a string, so you shouldn't be using = 'NULL', unless you actually set it to that string value. Use IS NULL instead.
You need to define "first row". First row based on an autoincrementing id value? First based on a timestamp date? You need to specify this as MySQL has no concept of "first row".
For example, if you do something like this in MySQL:
SELECT * FROM table LIMIT 1
You are not guaranteed to get the same record back each time.
Most likely you will need to specify an ORDER BY condition on a key column, as without it, you have no guarantee of which row your LIMIT 1 will apply to. I really can't think of a case where one might use LIMIT without an ORDER BY clause, as the two really go hand in hand.
So your query should look like:
UPDATE table
SET field = 'yes'
WHERE field IS NULL
ORDER BY some_key_field ASC
LIMIT 1
Note that even this query would not update the same row every time. It would update the first record (as specified by ORDER BY) that has a NULL value for the specified field. So if you ran this query 10 times, it would change 10 different records (assuming there are that many records with NULL values).

PHP/MySQL make top 10 out of selection

A user can input it's preferences to find other users.
Now based on that input, I'd like to get the top 10 best matches to the preferences.
What I thought is:
1) Create a select statement that resolves users preferences
if ($stmt = $mysqli->prepare("SELECT sex FROM ledenvoorkeuren WHERE userid = you"))
$stmt->bind_result($ownsex);
2) Create a select statement that checks all users except for yourself
if ($stmt = $mysqli->prepare("SELECT sex FROM ledenvoorkeuren WHERE userid <> you"))
$stmt->bind_result($othersex);
3) Match select statement 1 with select statement 2
while ($stmt->fetch()) {
$match = 0;
if ($ownsex == $othersex) {
$match = $match + 10;
}
// check next preference
4) Start with a variable with value 0, if preference matches -> variable + 10%
Problem is, I can do this for all members, but how can I then select the top 10???
I think I need to do this in the SQL statement, but I have no idea how...
Ofcourse this is one just one preference and a super simple version of my code, but you'll get the idea. There are like 15 preference settings.
// EDIT //
I would also like to see how much the match rating is on screen!
Well, it was a good question from the start so I upvoted it and then wasted about 1 hour to produce the following :)
Data
I have used a DB named test and table named t for our experiment here.
Below you can find a screenshot showing this table's structure (3 int columns, 1 char(1) column) and complete data
As you can see, everything is rather simple - we have a 4 columns, with id serving as primary key, and a few records (rows).
What we want to achieve
We want to be able to select a limited set of rows from this table based upon some complex criteria, involving comparison of several column's values against needed parameters.
Solution
I've decided to create a function for this. SQL statement follows:
use test;
drop function if exists calcMatch;
delimiter //
create function calcMatch (recordId int, neededQty int, neededSex char(1)) returns int
begin
declare selectedQty int;
declare selectedSex char(1);
declare matchValue int;
set matchValue = 0;
select qty, sex into selectedQty, selectedSex from t where id = recordId;
if selectedQty = neededQty then
set matchValue = matchValue + 10;
end if;
if selectedSex = neededSex then
set matchValue = matchValue + 10;
end if;
return matchValue;
end//
delimiter ;
Minor explanation
Function calculates how well one particular record matches the specified set of parameters, returning an int value as a result. The bigger the value - the better the match.
Function accepts 3 parameters:
recordId - id of the record for which we need to calculate the result(match value)
neededQty - needed quantity. if the record's qty matches it, the result will be increased
neededSex - needed sex value, if the record's sex matches it, the result will be increased
Function selects via id specified record from the table, initializes the resulting match value with 0, then makes a comparison of each required columns against needed value. In case of successful comparison the return value is increased by 10.
Live test
So, hopefully this solves your problem. Feel free to use this for your own project, add needed parameters to function and compare them against needed columns in your table.
Cheers!
Use the limit and offset in query:
SELECT sex FROM ledenvoorkeuren WHERE userid = you limit 10 offset 0
This will give the 10 users data of top most.
You can set a limit in your query like this:
SELECT sex FROM ledenvoorkeuren WHERE userid <> yourid AND sex <> yourpreferredsex limit 0, 10
Where the '0' is the offset, and the '10' your limit
More info here
you may try this
SELECT sex FROM ledenvoorkeuren WHERE userid = you limit 0, 10 order by YOUR_PREFERENCE

SQLSRV Query to return all products listed under a column

Here is my code
if (isset($_GET["range"])) { $range = $_GET["range"]; } else { $range = BLOB; }
Basically, I'm using the GET variable to search a table under the column 'range'. Only problem is, in the case that range is not set I would like a default variable that could return all the products.
I'm doing this so I can avoid including multiple SQL queries. Mind you, the part of the code I'm trying to replace is BLOB. Any thoughts?
EDIT: If you're going to vote down my question, at least have the decency to comment why.
You're asking 'I have a place where I put a piece of data to use as a filter (the name of a clothing range) to limit the returns on my search. If I don't pick a specific clothing range, what can I put in that filter?'
SQL has a data value to indicate 'I have no meaningful data in this field': NULL.
You have no meaningful information on what clothing range you would like to filter on, so one possible method for handling this would be to pass in a NULL for range, and then have the SQL side process that parameter with a range_variable = range_column OR range_variable IS NULL
Here's a quick and dirty example so you can see how it works:
create table clothing (range varchar (20))
insert into clothing
select 'Value1'
union select 'value2'
union select 'value3'
select * from clothing
declare #range_var varchar(20)
set #range_var = 'value2'
select * from clothing
where range = #range_var or #range_var is null
set #range_var = NULL
select * from clothing
where range = #range_var or #range_var is null
GO
drop table clothing
I would like to comment, but I can't, because of my reputation, so I'll try to answer the question as I understand it.
If your query ends with something like (no matter the correct syntax) :
LIMIT 0, $range
Try something like
<?php
if(isset($_GET['range']) && is_int($_GET['range']))
$range = ' LIMIT 0, '.$_GET['range'];
else
$range = '';
Or in just one line
<?php
$range = (isset($_GET['range']) && is_int($_GET['range'])) ? ' LIMIT 0, '.$_GET['range'] : '';
I hope I'm not off base...

How to find missing data either in array or in mySQL table?

I have an array filled with values (twitter ids) and I would like to find the missing data between the lowest id and the highest id? Any care to share a simple function or idea on how to do this?
Also, I was wondering if I can do the same with mySQL? I have the key indexed. The table contains 250k rows right now, so a temporary table and then a join wouldn't be very fast or efficient. I could do a PHP loop to loop through the data, but that would also take a long time, and a great deal of memory. Is there a specific mysql query I can run? or can I somehow use the function from above with this?
Thanks,
James Hartig
http://twittertrend.net
I had a similar requirement and wrote a function that would return a list of missing IDs.
---------------------------
create function dbo.FreeIDs ()
---------------------------
returns #tbl table (FreeID int)
as
begin
declare #Max int
declare #i int
select #Max = MAX(ID) from [TheTable]
set #i = 0
while #i < #Max begin
set #i = #i + 1
if not exists (select * from [TheTable] where ID = #i)
insert into #tbl select #i
end
return
end
Do you mean sequential ID's?
In that case
$new_ids = range($lowid, $highid, 1);
$ids = array_merge($ids, $new_ids);
$ids = array_unique($ids);
sort($ids);
And in SQL (with placeholders)
SELECT key, other_data from `table` WHERE key > :low_id AND key < :high_id
Your range() gave me a good idea, your code didn't work as unique preserves unique keys, so I was just left with the range functions result.
However, this worked:
$diff = array_values(array_diff(range(min($array), max($array), 1), $array)); //returns array of incomplete values

Categories