I have array of columns and their values selected by user. I need to perform search based on these columns and values.
For instance, a user choose:
morning(column) => Thurs,Sun(values)
afternoon(column) => Sat(values)
Now, how do I search for records that match the columns and the values? I'm using PDO.
the arrays:
//columns
var_dump($cols);
array (size=3)
0 => string 'morning' (length=7)
1 => string 'morning' (length=7)
2 => string 'afternoon' (length=9)
var_dump($days);
//values
array (size=3)
0 => string 'Thrs' (length=4)
1 => string 'Sun' (length=3)
2 => string 'Sat' (length=3)
Sample Columns and values stored in the database,for a record.So , I want to use the above days and columns as search criteria.
In the following record, this user has
'morning' => string 'Thrs'
'afternoon' => string 'Fri,Sat'
'evening' => ''
My search criteria for morning is, Thurs and Sun. But this user only available on Thurs in the morning. SO 1 criteria is met.
Next for afternoon, this user available on Fri, Sat. Bu my search needs only Sat. Since either one is met so this criteria is met.
But let say my search criteria is evening only instead of morning and afternoon. Then this user will not selected as he/she not available on evenings.
Hope you understand how it goes..If not feel free to ask. Thank you.
array (size=1)
0 =>
array (size=25)
'postUUID' => string '5623853773026' (length=13)
'subid' => string '36' (length=2)
'subname' => string 'Muay Thai' (length=9)
'catID' => string '4' (length=1)
'catname' => string 'Martial Arts' (length=12)
'pricing' => string '200' (length=3)
'post_status' => string '0' (length=1)
'UUID' => string '562385374bddf' (length=13)
'Name' => string 'Kalaivani Nair' (length=14)
'Phone' => string '012345666' (length=9)
'Email' => string 'kalaivaninair#ymail.com' (length=23)
'location' => string 'kajang' (length=6)
'lat' => string '2.993518' (length=8)
'lon' => string '101.7874058' (length=11)
'DateReg' => string '2015-10-18 19:40:39' (length=19)
'Reputation' => string '0' (length=1)
'ReviewPlus' => string '' (length=0)
'ReviewNeg' => string '' (length=0)
'Sex' => string 'f' (length=1)
'centre' => string '0' (length=1)
'morning' => string 'Thrs' (length=4)
'afternoon' => string 'Fri,Sat' (length=7)
'evening' => string '' (length=0)
'catid' => string '4' (length=1)
'distance' => string '0' (length=1)
EDITED based on steve's answer
"avail":["Wed-2","Wed-3"]//JSON string
$data = json_decode($return, true);//decoded
$avail = $data['avail'];//stored into database
if($avail != ""){
foreach($avail as $k=>$v)
{
echo $v;
$array = explode('-', $v);
$day =$array[0]; // Languages
$column = $array[1]; // English
echo"<br/>";
if($column == 1)
{
$col = "morning";
}
if($column == 2)
{
$col = "afternoon";
}
if($column == 3)
{
$col = "evening";
}
echo $col ."=>". $day;
echo $sql=" SELECT * , (3956 * 2 * ASIN(SQRT( POWER(SIN(('$lat' - lat) * pi()/180 / 2), 2) +COS('$lat' * pi()/180) * COS(lat * pi()/180) * POWER(SIN(('$lon' - lon) * pi()/180 / 2), 2) ))) as distance
from posts,subjects WHERE ('posts.".$col."' LIKE '%".$day."%') AND posts.catID = '$catid' AND posts.subname LIKE '%$subject%' AND posts.subid = subjects.subid AND posts.catID = subjects.catid AND posts.pricing <= '$rate' having distance <= '$distance' order by distance ";
echo"<br/>";
// array_push($cols,$col);
// array_push($days,$day);
}
}
$stmt =connection::$pdo->prepare($sql);
$stmt->execute();
$place=array();
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$place[] = $row;
}
Use the LIKE function in MySQL to search for strings within your columns.
In your first example ,so search for either a Thursday or Sunday morning:
SELECT * FROM `tableName` WHERE (`morning` LIKE '%Thrs%' OR `morning` LIKE '%Sun%');
To search for either a Friday or Saturday afternoon:
SELECT * FROM `tableName` WHERE (`afternoon` LIKE '%Fri%' OR `afternoon` LIKE '%Sat%');
This would be sufficient for your scenario where the list of potential values is short. However in conventional relational databases it is often good practice to move columns with multiple values to a separate table rather than using comma seperated values within a single column. This scales better through the use of indexing and offers more flexibility in terms or the queries you can run.
Related
I want this code to accept more than one WHERE parameter at the bottom, but when the added text comes into play, it returns nothing. It returns what it should without the filter.
What I'm trying to do is filter the results I get from the inner query from user inputted data that gets posted into the PHP code.
Any advice would be helpful at this point.
$OgrenciNo= " AND OgrenciNo LIKE %1005%";
$sth = $conn->prepare('SELECT t.* FROM (SELECT ogrenciler.OgrenciNo, ogrenciler.adsoyad as adsoyad1,
dersler.Ders, dersler.DersKodu, tarih.Tarih, ogretmenler.isim,
login.adsoyad, onayturu.Onay, mazeretturu.tur,
mazeretaciklama.Aciklama, mazeretaciklama.LogTarihi
FROM ogrenciler, tarih, aratablo, ogretmenler,
mazeretaciklama, login, dersler, mazeretturu, onayturu
WHERE aratablo.AciklamaID = mazeretaciklama.AciklamaID
AND aratablo.TarihID = tarih.TarihID
AND aratablo.DersID = dersler.DersID
AND aratablo.OnaylayanID = login.OnaylayanID
AND aratablo.OnayID = onayturu.OnayID
AND aratablo.Mazturu = mazeretturu.Mazturu
AND dersler.OgrGorID = ogretmenler.OgrGorID
AND mazeretaciklama.OgrenciNo = ogrenciler.OgrenciNo) t
WHERE LogTarihi > "1900-01-01"
'.$OgrenciNo
);
$sth->execute();
Normal results are as follows:
array (size=2)
0 =>
array (size=11)
'OgrenciNo' => string '1005.02021' (length=10)
'adsoyad1' => string 'Örnek Öğrenci' (length=13)
'Ders' => string 'Ders Adı' (length=8)
'DersKodu' => string 'KOD000' (length=6)
'Tarih' => string '2016-02-01' (length=10)
'isim' => string 'Öğretim Elemanı İsmi' (length=20)
'adsoyad' => string 'ROOT' (length=4)
'Onay' => string 'Onaylandı' (length=9)
'tur' => string 'Sınav' (length=5)
'Aciklama' => string 'hastalık hastası' (length=16)
'LogTarihi' => string '2016-02-09 09:14:52' (length=19)
1 =>
array (size=11)
'OgrenciNo' => string '1035.02021' (length=10)
'adsoyad1' => string 'ahmet mehmet' (length=12)
'Ders' => string 'E-Ticaret Sistem Tasarımı' (length=25)
'DersKodu' => string 'BIL446' (length=6)
'Tarih' => string '2016-02-07' (length=10)
'isim' => string 'Yrd. Doç. Dr. Mustafa Cem Kasapbaşı' (length=35)
'adsoyad' => string 'Araş. Gör. Erdem Yavuz' (length=22)
'Onay' => string 'Onaylanmadı' (length=11)
'tur' => string 'Ders' (length=4)
'Aciklama' => string 'cenaze vardı' (length=12)
'LogTarihi' => string '2016-02-11 13:33:53' (length=19)
I'm trying to filter out the second result but the LIKE argument doesn't seem to work.
By popular demand here's the whole query after I print it out in the page (P.S. the only thing different from the top one is that it contains "AND OgrenciNo LIKE %1005%" at the end):
SELECT t.* FROM (SELECT ogrenciler.OgrenciNo, ogrenciler.adsoyad as adsoyad1, dersler.Ders, dersler.DersKodu, tarih.Tarih, ogretmenler.isim, login.adsoyad, onayturu.Onay, mazeretturu.tur, mazeretaciklama.Aciklama, mazeretaciklama.LogTarihi FROM ogrenciler, tarih, aratablo, ogretmenler, mazeretaciklama, login, dersler, mazeretturu, onayturu WHERE aratablo.AciklamaID = mazeretaciklama.AciklamaID AND aratablo.TarihID = tarih.TarihID AND aratablo.DersID = dersler.DersID AND aratablo.OnaylayanID = login.OnaylayanID AND aratablo.OnayID = onayturu.OnayID AND aratablo.Mazturu = mazeretturu.Mazturu AND dersler.OgrGorID = ogretmenler.OgrGorID AND mazeretaciklama.OgrenciNo = ogrenciler.OgrenciNo) t WHERE LogTarihi > "1900-01-01" AND OgrenciNo LIKE %1005%
Your like condition should be like this. Just add ' in it. :
$OgrenciNo= " AND OgrenciNo LIKE '%1005%'";
i'm working on a small text based web game for a few friends to play (for nostalgia) but i'm having trouble with the very core of the game, the attacking/defending.
Each player has x amount of each troop type (more can be purchased and will be lost on atk/def)
so far I have a table with troop types and stats and a table with troop qty linked with user id and troop id.
I'm using the user id to get the troop id and qty using;
// Get attacker troop quantities.
$i = 0;
$attacker_deets = $conn->prepare("SELECT * FROM troop_qty WHERE user_id= :attacker_id");
$attacker_deets->bindParam(':attacker_id', $attacker_id);
$attacker_deets->execute();
$attacker_deets_results = $attacker_deets->fetchAll(PDO::FETCH_ASSOC);
foreach($attacker_deets_results as $atk_key=>$atk_result) {
echo "<pre>"; var_dump($atk_result); echo "</pre>";
}
which outputs;
array (size=4)
'troop_qty_id' => string '1' (length=1)
'user_id' => string '2' (length=1)
'troop_id' => string '1' (length=1)
'qty' => string '100' (length=3)
array (size=4)
'troop_qty_id' => string '2' (length=1)
'user_id' => string '2' (length=1)
'troop_id' => string '2' (length=1)
'qty' => string '100' (length=3)
I'm then using the troop id to get the troop details;
// get attacker troop details.
$attacker_troop_deets = $conn->prepare("SELECT * FROM troops WHERE troop_id= :atk_troop_id");
$attacker_troop_deets->bindParam(':atk_troop_id', $attacker_deets_results[$i]['troop_id']);
$attacker_troop_deets->execute();
$returned_results = $attacker_troop_deets->fetchAll(PDO::FETCH_ASSOC);
foreach($returned_results as $key=>$result) {
echo "<pre>"; var_dump($result); echo "</pre>";
}
++$i;
which in total gives me;
array (size=4)
'troop_qty_id' => string '1' (length=1)
'user_id' => string '2' (length=1)
'troop_id' => string '1' (length=1)
'qty' => string '100' (length=3)
array (size=4)
'troop_id' => string '1' (length=1)
'troop_name' => string 'Fist Puncher' (length=12)
'troop_atk' => string '1' (length=1)
'troop_def' => string '1' (length=1)
array (size=4)
'troop_qty_id' => string '2' (length=1)
'user_id' => string '2' (length=1)
'troop_id' => string '2' (length=1)
'qty' => string '100' (length=3)
array (size=4)
'troop_id' => string '2' (length=1)
'troop_name' => string 'Stick Waver' (length=11)
'troop_atk' => string '2' (length=1)
'troop_def' => string '1' (length=1)
Now where i'm stuck is I need to be able to compare the troop_atk of First Puncher with the defence of Stick Waver which is gotten from a different set of duplicate query's getting the defenders details, i also need to be able to multiply and divide the atk and def variables.
so how would i go about achieving this? i would assume i would need to give each field in the array their own variable, but how? i have tried using ${"troop_name" . $i} = $attacker_deets_results[$i]['troop_name']; but it only ever outputs the last entered name.
any help would be amazing. thanks.
Edit: To clear things up a little, my goal is to get the troop qty and multipy it by both atk and def then use these numbers to do some other math with the same fields from the defending player which I'll use to decrease the qty field.
Maybe you could modify your code a little and do the following.
Fetch the data about the user's troops in one query:
$results = $conn->query("SELECT troop_qty.user_id as uid, troop.troop_id, troop.troop_name, troop_qty.qty, troop.troop_atk, troop.troop_def FROM troop_qty join troop on troop.troop_id=troop_qty.troop_qty_id WHERE troop_qty.user_id=:attacker_id
Create a new array which contains information about all user's troops:
$userData = array(
'id' => $attacker_id,
'troops' => array());
while (($res = $results->fetch_assoc()) != null) {
$troopData = array(
'name' => $res['troop_name'],
'qty' => $res['qty'],
'atk' => $res['troop_atk'],
'def' => $res['troop_def']);
$userData['troops'][$res['troop_id']] = $troopData;
}
As result you would have something like this (vardump($userData)):
array (size=2)
'id' => int 2
'troops' =>
array (size=2)
1 =>
array (size=4)
'name' => string 'Fist Puncher' (length=12)
'qty' => string '100' (length=3)
'atk' => string '1' (length=1)
'def' => string '1' (length=1)
2 =>
array (size=4)
'name' => string 'Stick Waver' (length=11)
'qty' => string '100' (length=3)
'atk' => string '2' (length=1)
'def' => string '1' (length=1)
I don't know how exactly you want to manipulate the data later on in the game but I think this would ease the work.
Btw. I've thrown away fetchAll() function because I personaly think it is not a good practice to fetch all data into memory and then modify it or do whatever with it. It's a waste of the memory and when you would deal with a big amount of data, at some point that could cause you some troubles.
I have three tables.
Candidates
Skills
CandidateToSkillMap
Candidate and Skill tables are mapped in CandidateToSkillMap table. In that candidate_id and skill_id are foreign keys.
How can i get following output with them ?
Assume i need to display Computer Skills of candidate_id = 1
Computer Skills -
MS Word (x)
MS Excel (x)
MS Paint ()
It should display distinct list of all available computer skills and there should be a check-box in-front. It will be checked if specific candidate has that skill.
EDIT -
I have query database and loaded data into arrays -
$candidate_profile_computer_skills
this array gives all the computer skills
array (size=3)
0 =>
object(Candidate\Model\CandidateProfileSkill)[317]
public 'id' => string '1' (length=1)
public 'skill_name' => string 'MS Word' (length=7)
public 'candidate_id' => null
public 'candidateprofileskill_id' => null
1 =>
object(Candidate\Model\CandidateProfileSkill)[223]
public 'id' => string '3' (length=1)
public 'skill_name' => string 'MS Excel' (length=8)
public 'candidate_id' => null
public 'candidateprofileskill_id' => null
2 =>
object(Candidate\Model\CandidateProfileSkill)[316]
public 'id' => string '6' (length=1)
public 'skill_name' => string 'MS Paint' (length=8)
public 'candidate_id' => null
public 'candidateprofileskill_id' => null
$candidate_profile_skills_map
this array returns Skills and CandidateToSkillMap with LEFT JOIN for specific candidate (candidate_id = 1)
array (size=5)
0 =>
object(Candidate\Model\CandidateProfileSkill)[321]
public 'id' => string '1' (length=1)
public 'skill_name' => string 'MS Word' (length=7)
public 'candidate_id' => string '1' (length=1)
public 'candidateprofileskill_id' => string '1' (length=1)
1 =>
object(Candidate\Model\CandidateProfileSkill)[322]
public 'id' => string '2' (length=1)
public 'skill_name' => string 'Sinhala Reading' (length=15)
public 'candidate_id' => string '1' (length=1)
public 'candidateprofileskill_id' => string '2' (length=1)
2 =>
object(Candidate\Model\CandidateProfileSkill)[323]
public 'id' => string '3' (length=1)
public 'skill_name' => string 'MS Excel' (length=8)
public 'candidate_id' => string '1' (length=1)
public 'candidateprofileskill_id' => string '3' (length=1)
3 =>
object(Candidate\Model\CandidateProfileSkill)[324]
public 'id' => string '4' (length=1)
public 'skill_name' => string 'English Reading' (length=15)
public 'candidate_id' => string '1' (length=1)
public 'candidateprofileskill_id' => string '4' (length=1)
4 =>
object(Candidate\Model\CandidateProfileSkill)[325]
public 'id' => string '4' (length=1)
public 'skill_name' => string 'English Reading' (length=15)
public 'candidate_id' => string '1' (length=1)
public 'candidateprofileskill_id' => string '4' (length=1)
A join will do:
SELECT
s.skill_name,
CASE WHEN c.candidate_id IS NOT NULL THEN '(X)' ELSE '()' END has_skill
FROM
skills s
LEFT JOIN CandidateToSkillMap c ON s.skill_id = c.skill_id
WHERE
c.candidate_id = 1
If it joins the right side successfully and thus c.candidate_id will be not null, then it means the person has that skill and you mark it else - don't.
You can just use this
Select S.SkillName, count(*) from CandidateToSkillMap CTS, Skills S where S.Id = CTS.CandidateProfileSkillId group by CV.Id having CTS.CandidateId = 1
SELECT * FROM [Skills] s
LEFT JOIN [CandidateToSkillMap] csm ON csm.candidateprofileskill_id = s.id
WHERE csm.candidate_id = 1
This will return all rows from the skills table, and you can do a null-check on the column "candidate_id" to ascertain whether or not the candidate in question has the skill on that row.
Here's some pseudo:
for($row in $result) {
Skill name: $row["skill_name"]
Has skill?: $row["candidate_id"] != null ? "Yes" : "No"
}
you can try this
select S.skill_name from CandidateToSkillMap CSM, Skills s where S.id=CSM.candidatesprofileskill_id and CSM.candidate_id=1
Try something like
SELECT s.skill_name, (cm.Candidate_id IS NOT NULL) AS HasSkill
FROM Skills AS s
LEFT OUTER JOIN candidateToSkillMap AS cm
ON s.id = cm.candidateprofileskill_id
WHERE s.skill_type = 'Computer Literacy'
AND (Candidate_id = 1 OR Candidate_id IS NULL)
The above query uses LEFT OUTER JOIN to join the skills and candidatestoskillmap include all the rows from skills tables. This will ensure that any rows not matched in the candidatestoskillmap table are included as null values.
The select section then looks for these values and assigns a true/false for it.
The Where section filters for the skill type and the candidate's id.
lets say we have an array like this
from a mysql function like
function getGroups($limit = 10) {
$data = $this->fetchAll ( 'SELECT gid, `group`, information, tag FROM groups
GROUP BY tag LIMIT ' . $limit );
return $data;
}
Resulting
array
0 =>
array
'gid' => string '6' (length=1)
'group' => string 'Media' (length=5)
'tag' => string 'advertising' (length=11)
1 =>
array
'gid' => string '8' (length=1)
'group' => string 'Fashion' (length=10)
'tag' => string 'shorts' (length=7)
2 =>
array
'gid' => string '7' (length=1)
'group' => string 'Automotive' (length=8)
'tag' => string 'cars' (length=5)
3 =>
array
'gid' => string '1' (length=1)
'group' => string 'Fashion' (length=7)
'tag' => string 'tshirt' (length=6)
i need to display somehow to this ( something like )
array
0 =>
array
'group' => string 'Media'
'tags'
array
0 => string 'advertising'
1 =>
array
'group' => string 'Fashion'
'tags'
array
0 => string 'short'
1 => string 'tshirt'
2 =>
array
'group' => string 'Automotive'
'tags'
array
0 => 'cars'
simpler
group tag
media advertising
fashion short
fashion tshirt
automotive cars
to
media
advertising
fashion
short
tshirt
automotive
cars
what is the best way to do this? from php array? or from the mysql ?
Are you trying to get a list of groups, plus all the tags for each group? GROUP_CONCAT() is the right way to get the tag list but you want to be grouping by group, not by tag:
function getGroups($limit = 10) {
$data = (array) $this->fetchAll (
'SELECT `group`,
GROUP_CONCAT(DISTINCT `tag` ORDER BY `tag`) AS `tags`
FROM `groups`
GROUP BY `group` LIMIT ' . $limit
);
foreach ($data as $i => $row) {
$data[$i]['tags'] = explode(',', $row['tags']);
}
return $data;
}
I would add
ORDER BY group,tag
so the result set has all rows of the same group together.
Starting a new can then be done in php by comparing to the previous group and close/starting the new group when it has changed.
actually using hashes makes more sense...
$names = array();
$query = ''SELECT gid, `group`, information, tag FROM groups GROUP BY tag LIMIT ' . $limit';
$result = mysql_query($query);
$num_rows = mysql_num_rows($result);
if ($num_rows) {
while ($row = mysql_fetch_array($result)) {
array_push($names[$row['group']], $row['tag']);
}
}
Try this
function getGroups($limit = 10) {
$data = $this->fetchAll ( 'SELECT gid, `group`, information, tag FROM groups
GROUP BY group LIMIT ' . $limit );
return $data;
}
This will group you data with group, or you can use group_concat but then you will get short, tshirt something like this.
I have a var dump of my sql query which return the following
I wanna to count in the array below that how many rows of myID = 5 are there. How would I do that. I am using php. Thanks in advance
array
0 =>
object(stdClass)[17]
public 'myID' => string '5' (length=1)
public 'data' => string '123' (length=3)
1 =>
object(stdClass)[18]
public 'myID' => string '5' (length=1)
public 'data' => string '123' (length=3)
2 =>
object(stdClass)[19]
public 'relativeTypeID' => string '2' (length=1)
public 'data' => string '256' (length=3)
3 =>
object(stdClass)[20]
public 'myID' => string '4' (length=1)
public 'data' => string '786' (length=3)
object(stdClass)[21]
public 'myID' => string '4' (length=1)
public 'data' => string '786' (length=3)
Do you always have the same value of data for the same myID? In other words, is data functionally dependant on myID?
If so, you can get the database to do this for you:
SELECT myID, data, COUNT(*) AS cnt
FROM (your query here)
GROUP BY myID, data
This would give you results like the following:
myID data cnt
'5' '123' 3
'2' '256' 1
'4' '786' 2
Or, you can use a foreach statement, like:
$count = 0;
foreach($arr as $item)
{
// Given that your item is an stdClass Object you access its property with "->"
// if an array $item["myID"] instead
if ( $item->myID == '4' )
{
$count ++;
}
}