I had this and everything worked fine (I had a generic table builder, but now I am having to stray from that):
while ($x = mysqli_fetch_assoc($result))
{
$fields[] = $x['Field'];
}
Now I have something similar to this:
$result = mysqli_query($con, 'SELECT r.id AS ID, CONCAT(g.fname, g.lname) AS Name, r.apple AS Apple,
r.dog AS Dog, DATEDIFF(r.Dog, r.Apple) AS Days,
r.total_price AS "Total Price", u.name AS Name, r.in AS "In",
r.out AS "Out", r.time_in AS "Time In", r.time_out AS "Time Out",
CONCAT(c.fname,c.lname) AS Charlie, r.here AS "Apple",
r.leave AS "Dog"
FROM really r, georgia g, unit u, charlie c
WHERE g.id = r.georgia AND r.unit = u.id AND r.charlie = c.id
HAVING r.in = TRUE AND r.out = FALSE');
//fill fields array with fields from table in database
while ($x = mysqli_fetch_assoc($result))
{
$fields[] = $x['Field'];
}
I am now getting an error for the line $fields[] = $x['Field']; because of the word Field. Why? Because I now have a full query? How can I fix this without referencing each field name?
Because there is not a field named Field in you query result:
'SELECT r.id AS ID, CONCAT(g.fname, g.lname) AS Name, r.apple AS Apple,
r.dog AS Dog, DATEDIFF(r.Dog, r.Apple) AS Days,
r.total_price AS "Total Price", u.name AS Name, r.in AS "In",
r.out AS "Out", r.time_in AS "Time In", r.time_out AS "Time Out",
CONCAT(c.fname,c.lname) AS Charlie, r.here AS "Apple",
r.leave AS "Dog"
FROM really r, georgia g, unit u, charlie c
WHERE g.id = r.georgia AND r.unit = u.id AND r.charlie = c.id
HAVING r.in = TRUE AND r.out = FALSE'
There are some fields in your query result: ID, Name, Apple, etc.. You can try to fetch the these field as below, or change your query command.
while ($x = mysqli_fetch_assoc($result))
{
$fields[] = $x['ID'];
}
Related
subjects.id is overriding users.id in the JSON response whenever i add subjects.idto the select in the query.
How can i show my both users.id and subject.id in the response
$sql = "SELECT users.id,users.name,users.date,subjects.id FROM tb_user AS users INNER JOIN
tb_subjects AS subjects ON users.id = subjects.userid WHERE users.id = '$userid'";
try {
$db = new db();
$db = $db->connect();
$stmt = $db->prepare($sql);
$stmt->execute();
$user = $stmt->fetch(PDO::FETCH_OBJ);
$db = null;
if(empty($user)) {
$response->getBody()->write
('
{
"error":
{
"message":"Invalid"
}
}');
} else {
$response->getBody()->write(json_encode($user));
}
} catch(PDOException $e) {}
current output
{
"id": "1",
"name": "joe",
"date": "2017-07-22 18:37:37"
}
expected output
{
"id": "1",
"name": "joe",
"subjectid": "4",
"date": "2017-07-22 18:37:37"
}
To get around the problem of a result set with two id columns, give the subject id column an alias of subjectid:
SELECT
users.id,
users.name,
users.date,
subjects.id AS subjectid
FROM tb_user AS users
INNER JOIN tb_subjects AS subjects
ON users.id = subjects.userid
WHERE users.id = '$userid'
Most databases seem to tolerate a result set which has two columns by the same name. But this would fail if it were to happen in a subquery in which you tried to also select that duplicate column. It looks like PHP is just deciding to choose one of the id columns though the best thing to do here is to fix the duplicate name problem in the query.
Edit:
If you wanted to get the latest subject, as indicated by its time column, you could slightly modify your query to use another join:
SELECT
users.id,
users.name,
users.date,
s1.id AS subjectid
FROM tb_user AS users
INNER JOIN tb_subjects s1
ON users.id = s1.userid
INNER JOIN
(
SELECT userid, MAX(time) AS max_time
FROM tb_subjects
GROUP BY userid
) s2
ON s1.userid = s2.userid AND
s1.time = s2.max_time
WHERE users.id = '$userid'
The subquery in the new join finds the latest time for each user. But this still does not give us the subject id which we actually want. To get this, we can access the first tb_subjects table, which however has been reduced after this new join to only records having the most recent message time. One caveat here: if you had a tie for most recent message my query would return all such ties. We could workaround this, but it would be more work.
$champions = $conn->prepare("SELECT Champion, Q, Q2, W, W2, E, E2, R, R2
FROM champions
Where Patch_No = ?");
$champions->bind_param('s', $Patch_No);
$champions->execute();
$champions_result = $champions->get_result();
$spells = $conn ->prepare("
SELECT Champion, Spell_Change, Spell_Change_Icon, Spell_Type
FROM spells
WHERE Patch_No= ?
");
$spells->bind_param('s', $Patch_No);
$spells->execute();
$spells_result = $spells->get_result();
while($row = $champions_result->fetch_assoc()){
echo $row['Champion'].'<br>';
foreach ($row as $column_name => $column) {
if ($column_name == 'Champion') {
continue; // These fields were already displayed above
}
if (!empty($column)) {
echo "$column_name $column<br>";
}
}
}
This is how the spell table looks like http://i.imgur.com/c5fkt1n.png
and here is champions table: http://i.imgur.com/rDXxgLJ.png
Champions table right now displays
Name of the Champion
-Spells of that champion e.g. Q W E R - name of that spell
*And here I want all the changes from Spell table that happened to those spells
Here is how it looks like right now http://i.imgur.com/1tR1o9q.png
And here is an example of how it should look like after displaying both tables at once: http://imgur.com/9mxnZFy
I have two tables one called area and one called area covered.
Table area contains the fields postcode and region.
e.g:
area table contains postcode - AB10 region - Aberdeen
area covered table contains id - 1 postcode - AB10 date - 1364989057
Now I have a form which searches for either the postcode or the region. I'm using JQuery's autocomplete and can get either postcode or the region but not both.
at the moment I have:
$result = $db->query("SELECT DISTINCT `postcode` FROM `areaCovered` WHERE `postcode` LIKE '%$search%' ORDER BY `postcode` ASC") or die('Something went wrong');
Then I use the data retrieved from the database result and put into JSON:
$json = '[';
$first = true;
while ($row = $result->fetch_assoc())
{
if (!$first) { $json .= ','; } else { $first = false; }
$json .= '{"value":"'.$row['postcode'].'"}';
}
$json .= ']';
echo $json;
How can I firstly join the two tables to search for either postcode or region that exists only in the area covered table and then output the result whether it is region or the postcode.
I hope that makes sense to you,
thanks
Instead of distinct you should use group by, and join them.
Something in the lines of:
select
a.`postcode` as postcode,
a.`region` as region,
from
`area` as a
inner join
`areaCovered` as ac
on
a.`postcode`=ac.`postcode`
where
a.`postcode` like '%$search%'
or
a.`region` like '%$search%'
group by
a.`postcode`
order by
a.`postcode` asc
Preferably I would just json_encode() the whole result set and parse it client side, but it looks like you may need to have a special JSON structure for a jQuery plugin?
$list = array();
while ($row = $result->fetch_assoc()) {
array_push(
$list,
array('value' => $row['postcode'] . ', ' . $row['region'])
);
}
echo json_encode($list);
This will create a JSON structure that looks like;
[
{
"value": "123 45, Region 1"
},
{
"value": "678 90, Region 2"
},
...
]
Database:
xx_users (id, name, user_id, email, location)
xx_questions (id, question, description, user_id)
Original code:
$friends = $facebook->api('/me/friends');
$arr= $friends['data'];
$friend_ids_arr = array();
foreach($arr as $friend) {
$friend_ids_arr[] = $friend['id'];
}
$sql = "SELECT * FROM xx_questions WHERE user_id IN (" . implode(',', $friend_ids_arr) . ") OR user_id = '$user' ORDER BY time DESC";
New code:
$friends = $facebook->api('/me/friends');
$arr= $friends['data'];
$friend_ids_arr = array();
foreach($arr as $friend) {
$friend_ids_arr[] = $friend['id'];
}
$sql = "SELECT *
FROM xx_questions q JOIN xx_users u ON
q.user_id = u.user_id
WHERE q.user_id IN (implode(',', $friend_ids_arr)) OR // STEP 1
q.user_id = '$user' OR // STEP 2
u.location = (SELECT location FROM xx_users WHERE user_id = $user) // STEP 3
ORDER BY q .time DESC";
$data = mysql_query($sql) or die(mysql_error());
while ($row = mysql_fetch_assoc($data)) {
echo $row[id];
}
I am trying to select questions from xx_questions (that have been posted by users) should any of three situations arise:
Those values where the poster's user_id matches that of one of the current user's friends (i.e. the poster and the user are friends)
Those values where the poster's user_id matches that of the user (i.e. the poster is the user)
Those values where the poster's location matches that of the current user (i.e. the poster and user are currently in the same city)
I had originally achieved steps 1 and 2, but when I add step 3, two things happen:
Step 1 stops working (i.e. only posts from the current user and people in the same city are returned)
The $row[id] echoed in the while loop is that of xx_users, not xx_questions. I've tried $row[q.id] but to no avail.
Any idea what's gone wrong?
In your seconds query your implode statement isnt outside the string.
"WHERE q.user_id IN (implode(',', $friend_ids_arr)) OR" // STEP 1
While php can add variable to a double quoted string ($x = "test $test test" $test will be changed to the value of $test) it can't escape functions. So this would return in
"WHERE q.user_id IN (implode(',', Array)) OR" // STEP 1
You should use:
"WHERE q.user_id IN (".implode(',', $friend_ids_arr).") OR" // STEP 1
And in the end you are using SELECT * and if both tables have an Id column, only one is returned. Its better to use SELECT q.* to get only the questions row or perhaps SELECT q.*, u.location to get the entire question row and the location from the user table.
I also checked your query and it should do what you want
$sql = "SELECT q.*, u.location
FROM xx_questions q
JOIN xx_users u
ON q.user_id = u.user_id
WHERE q.user_id IN (".implode(',', $friend_ids_arr).") OR // STEP 1
q.user_id = $user OR // STEP 2
u.location = (SELECT location FROM xx_users WHERE user_id = $user) // STEP 3
ORDER BY q.time DESC";
The only thing I changed is the implode and remove the '' around $user. That is incase the $user isnt actualy an integer but a string containing a number, but has some extra spaces appended (eg '1 ' instead of '1');
Well I have gotten this query:
$characterinfoquery = "
SELECT
c.Name,
c.Level,
c.Sex,
c.Playtime,
c.KillCount,
c.DeathCount,
cl.Name AS clanName
FROM
Character AS c,
Account AS a,
ClanMember AS cm,
Clan AS cl
WHERE
c.AccountID = a.AccountID AND
c.CharacterID = cm.CharacterID AND
cm.ClanID = cl.ClanID AND
a.UserID='".mssql_real_escape_string($_SESSION['username'])."'
";
But I want the members who do not have a clan to be showed too but instead of the clan name it would say "-" at where the clan name is supposed to be.
This is my while statement:
if(mssql_num_rows($characterinforesult) != 0){
$content = str_replace("%content%", file_get_contents("tpl/contents/characterinfo.html"), $content);
//Get character information
$search = array("%Name%", "%Level%", "%Sex%", "%Playtime%", "%KillDeath%", "%Clan%");
$rows = file_get_contents("tpl/contents/characterinfo_tr.html");
while($row = mssql_fetch_assoc($characterinforesult)){
if($row['KillCount'] != 0){
$KillDeath = round($row['KillCount']/$row['DeathCount'], 2);
}
else{
$KillDeath = "-";
}
$Playtime = $row['Playtime']/60;
$replace = array($row['Name'], $row['Level'], gender($row['Sex']), round($Playtime), $KillDeath, $row['clanName']);
$tr .= str_replace($search, $replace, $rows);
}
}
Could someone help me with this?
Output with innerjoins:
Name Level Sex Playtime K/D Ratio Clan
DragonDex 97 Male 375 min 0.22 Test
It shows 1 row while there are 2 characters in that account, 1 has a clan the other doesn't.
Do you need a left outer join:
SELECT
c.Name,
c.Level,
c.Sex,
c.Playtime,
c.KillCount,
c.DeathCount,
coalesce( cl.Name, ' - ' ) AS clanName
FROM
Character AS c
inner join
Account AS a
on c.AccountID = a.AccountID
left outer join
ClanMember AS cm
on c.CharacterID = cm.CharacterID
left outer join
Clan AS cl
on cm.ClanID = cl.ClanID
WHERE
a.UserID='".mssq ...