Need to update missing info in mySQL table column - php

I'm back again. Been searching and trying this for hours... Haven't found an answer or even the right question.
I want to fix a crashed table that I recreated from memory (and the members list in Works) using an query in phpMyAdmin. I need to populate each members total posts.
forum_messages
member_id | message |
--------------------
1 | Hello |
3 | One, Two, Three |
1 | Howdy! |
2 | Here we are again! |
2 | To answer your question... |
forum_members
member_id | posts |
--------------------
1 | 0 |
2 | 0 |
From forum_messages, forum_members should end up looking like this:
forum_members
member_id | posts |
--------------------
1 | 2 |
2 | 2 |
3 | 1 |
Thanks!

Using an INSERT SELECT query, you should be able to rebuild the data you had lost in the forum_members table.
This would return the number of messages per member_id:
SELECT member_id, COUNT(*) FROM forum_messages GROUP BY member_id;
Collating it with an INSERT query puts it into the table instead of displaying the data as it normally would in an SELECT query.
INSERT INTO forum_members (member_id, posts) SELECT member_id, COUNT(*) FROM forum_messages GROUP BY member_id;

try this :
UPDATE forum_members SET posts = (SELECT COUNT(*) FROM forum_messages where forum_messages.member_id = forum_members.member_id GROUP BY forum_messages.member_id)

I think you need just to count messages by members, isn't it?
If so, use this SQL:
TRUNCATE TABLE forum_members;
INSERT INTO forum_members(member_id, posts)
SELECT member_id, COUNT(1) FROM forum_messages GROUP BY member_id;

This should fix it.. Please note that the code is NOT TESTED. You should echo the outcome of the update query to check if it's correct before executing the update query
$get_memberid = "SELECT distinct(member_id) as member_id FROM forum_members;";
$Rget_memberid = mysql_query($get_memberid) or die(mysql_error());
while($row_get_memberid = mysql_fetch_array($Rget_memberid)) {
$arr_get_memberid[] = array( "member_id" => $row_get_memberid['member_id'] );
}
for ($c = 0; $c < count($arr_get_memberid); $c++){
$update_count = "UPDATE forum_members set posts = (SELECT count(member_id) from forum_messages where member_id = '".$arr_get_memberid[$c]['member_id']."') where member_id = '".$arr_get_memberid[$c]['member_id']."';";
$Rupdate_count = mysql_query($update_count) or die(mysql_error());
}

Related

Using 1st SQL select statement results for 2nd select statement

I'd like some help combining Multiple SQL queries into one...
I have a search box for orderid or sampleref. An order may have up to 99 sampleref in it so I want the customer to be able to pull up a list of all sampleref associated with their order number regardless of if they search by orderid or one of their sampleref. Essentially what I want to do is,
SELECT `orderid` as OrderNumber FROM `results` WHERE `sampleref` = 'TEST12345';
SELECT * FROM `results` WHERE `orderid` = OrderNumber GROUP BY `sampleref`;
For clarity I'm putting this into a PHP script for a Maria DB mysql server
Here is a sample database
+----+---------+-----------+
| id | orderid | sampleref |
+----+---------+-----------+
| 1 | 101388 | TEST12345 |
| 2 | 101388 | TEST54321 |
| 3 | 333444 | ABC123 |
| 4 | 333444 | ABC321 |
+----+---------+-----------+
Thanks
Henry
Following will give you what you are looking for.
select r2.orderid, r2.sampleref
from result r
join result r2 on r.orderid = r2.orderid
where r.sampleref = 'TEST12345' or r.orderid = <orderid>
You can use or with a correlated subquery:
SELECT r.*
FROM results r
WHERE r.orderid = $orderid OR
EXISTS (SELECT 1
FROM results r2
WHERE r2.orderid = r.orderid AND r2.sampleref = $sampleref
);
Note: This takes two parameters -- either the order id or the sample ref. The first condition returns everything with the same order, if that is given. The second returns everything with the same order as the given sample ref.

SQL JOIN not working the way i need

Hi guys im have trouble with a SQL join statement. i cant seem to get it to work the way i want
ex.
TABLE1 TABLE 2
ID NAME ID INFO
1 JOE 1 YES
2 MIKE 1 NO
3 JESS 1 MAYBE
4 ROB 2 NO
2 NO
$stid = oci_parse($conn, "
SELECT * FROM TABLE1 TBL1 RIGHT JOIN TABLE2 TBL2
ON (TBL1.ID = TBL2.ID0 WHERE TBL1.ID = '1'
");
oci_execute($stid);
while (($row = oci_fetch_array($stid, OCI_BOTH+OCI_RETURN_NULLS)) != false) {
echo $row['NAME']."<br/ >";
echo $row['INFO']."<br/ >";
}
what i want to see is
RESULT
JOE
YES
NO
MAYBE
typically what i get (regardless of join type) is something like
JOE
YES
JOE
NO
JOE
MAYBE
any help would be great.
don't use rigth join, change it for left join
SELECT * FROM TABLE1 TBL1 LEFT JOIN TABLE2 TBL2
ON (TBL1.ID = TBL2.ID) WHERE TBL1.ID = '1'
First of all, you need to change the RIGHT JOIN to LEFT JOIN (or simple JOIN, check your requirements). Now for the main part of your problem: the JOIN works as expected, you need to use your favourite language to do something like that:
Pseudocode
var test_name = "";
var last_name = "";
while EXIST_MORE_RECORDS {
test_name = $row['NAME'];
if (test_name != last_name) {
last_name = test_name;
print last_name;
}
print $row['INFO']."<br/ >";
}
Look at the results of your query:
+----+------+----+-------+
| ID | NAME | ID | INFO |
+----+------+----+-------+
| 1 | JOE | 1 | MAYBE |
| 1 | JOE | 1 | NO |
| 1 | JOE | 1 | YES |
+----+------+----+-------+
Now look at your loop. You're outputting NAME and INFO for each row. You could alter your loop like #giorgos-altanis suggests.
You could also change your query to use UNION, and grab the NAME and INFO separately so that each is its own row.
select Name VALUE, 0 sortorder
from TABLE1
where ID = '1'
union
select Info VALUE, 1 sortorder
from TABLE2
where ID = '1'
order by sortorder
This would give you results like :
+-------+-----------+
| VALUE | sortorder |
+-------+-----------+
| JOE | 0 |
| MAYBE | 1 |
| NO | 1 |
| YES | 1 |
+-------+-----------+
Then you could use a simple loop. Hard to say whether this would be an appropriate solution to your actual code.
Note that the order of rows from Table2 cannot be guaranteed. If you want them to appear in order of YES, NO, MAYBE, you'll need an additional field in the table to define the sort order (or maybe a CASE statement).
UPDATE
If all you want is the count of the rows from Table2 (which is a completely different question), then you just need to join the tables and then group on the NAME:
select TBL1.ID, TBL1.NAME, COUNT(1) TBL2COUNT
from TABLE1 TBL1
join TABLE2 TBL2 on TBL1.ID = TBL2.ID
where TBL1.ID = '1'
group by tbl1.ID, TBL1.NAME

How do I get distinct rows by a column?

I have a huge number of rows that I'd like to get say, last 5 records inserted in that database from 10 different users. If the same user inserted the last 3 rows into database, we must get one row, skip the others two and move to get a row per user, until it count up to 5.
A database like that:
user_id | news_id | title
1 | 1 | foo-1
2 | 2 | foo-2
3 | 3 | foo-3
1 | 4 | baa
4 | 5 | baa0
5 | 6 | baa1
5 | 7 | baa2
6 | 8 | baa3
7 | 9 | baa4
Should return:
user_id | news_id | title
1 | 1 | foo-1
2 | 2 | foo-2
3 | 3 | foo-3
4 | 5 | baa0
5 | 6 | baa1
The current filter was done by PHP, like this:
$used = array();
while ($data = mysql_fetch_array($query)) {
$uid = $data['user_id'];
if(in_array($uid, $used))
continue;
array_push($used, $uid);
// do something with data
}
But I want to refactor it, and do the filter purely by mysql, if possible. I don't know much MySql and that's why I'm having problem to archive this...
Here's what I've tried
select DISTINCT(user_id), news_id, title from XXX
WHERE GROUP BY (news_id) DESC
LIMIT 0,5
How can I do that?
1 way you can do it is to generate a partitioned row number per user and then select 5 records where RowNumber = 1.
SELECT *
FROM
(
SELECT
d.user_id
,d.news_id
,d.title
,(#rn:= if(#uid = user_id, #rn + 1,
if(#uid:=user_id,1,1)
)
) as RowNumber
FROM
Data d
CROSS JOIN (SELECT #uid:=-1, #rn:=0) vars
ORDER BY
user_id
,news_id
) t
WHERE
t.RowNumber = 1
ORDER BY news_id
LIMIT 5;
http://rextester.com/JRIZI7402 - example to show it working
Note you can change the row order by simply changing the ORDER BY statement of the derived table so if you have a column that will signify the latest record e.g. an identity column or a datetime column you can use that, but user_id must be the first criteria to be partitioned correctly.
Do it from your query.
"SELECT * FROM table GROUP BY user_id ORDER BY news_id DESC LIMIT 5"
well, i think this will achieve what you are after.
select user_id, news_id, title from tableName
GROUP BY user_id
ORDER BY news_id DESC
LIMIT 0,5
Hope this helps!

MYSQL left join if then statement favorite table procedure

i have 2 tables
here is table 1 table name is
forexample
itemlist
+-----+----------+-----+
| uid | username | age |
+-----+----------+-----+
| 1 | doe | 17 |
| 2 | smith | 18 |
| 3 | john | 30 |
+-----+----------+-----+
and other one is
fav
+-----+------+---------+
| uid | user | itemuid |
+-----+------+---------+
| 1 | alex | 2 |
+-----+------+---------+
Here is my mysql query *NOT Working * any way to fix this problem when i run php file i got error in mysql syntax
SELECT c.uid, c.username, c.age,i.uid,i.user,i.itemuid
from itemlist c
left join fav i on c.uid = i.itemuid
if (i.user = 'alex') THEN
SET #fav = 1;
ELSE
SET #fav = 0;
END IF
this is sample php
while ($row = mysqli_fetch_array($res)){
if ($row['fav'] = '1'){
echo $row['username']." is exit in fav";
}else{
echo $row['username']." is not exit in fav";
}
}
i hope you understand my question right ?
To get a column named fav returned in the resultset, you would need to include an expression in the SELECT list, and give it an alias fav.
It's not at all clear why you would need a MySQL user-defined variable; if you don't know why you'd need one, then you probably don't need one.
Given that your PHP code is looking for a column named fav in the resultset, likely you want something like this:
SELECT c.uid
, c.username
, c.age
, i.uid AS i_uid
, i.user
, i.itemuid
, IF(i.user='alex',1,0) AS fav
FROM itemlist c
LEFT
JOIN fav i ON i.itemuid = c.uid
Note that the original query had two columns named uid; if you want to return both, and be able to reference both of those by column name, you need to have distinct names for each. In the query above, I've assigned an alias to the i.uid column so that both uid columns will be available by distinct column name.

Find the max value of a column, then group by another column in same table

I have a similar problem to the one solved here, but when I try the solution I think it fails because I have things set up differently..
I have a doc table with...
(unfortunately table cant be edited due to it being an old system)
+-------+--------+----------+--------+
| Docid | title | revision | linkid |
+-------+--------+----------+--------+
| 1 | docone | 1 | 1 |
| 2 | doctwo | 1 | 2 |
| 3 | docone | 2 | 1 |
|4 | docone | 3 | 1 |
+-------+--------+----------+--------+
On a page that lists all the documents I want to list only the latest revision of each document. Doc1 for example is on revision 3 so I want that one and not the other 2. Doc2 is only on revision 1 so show that one.
Based on the problem in the other post I have writen my query as follows......
$query_docs = "
SELECT `document`.*, doctype.*
FROM `document`
INNER JOIN doctype
ON `document`.iddoctypes = doctype.iddoctypes
WHERE `document`.revision = (
SELECT MAX(`document`.revision) AS revision
FROM `document`
)
GROUP BY `document`.linkid
ORDER BY `document`.doccreation DESC";
I have had to link to another table to get the document type (just to make the query harder).
Try this, I made a couple minor changes
SELECT document.*, doctype.*
FROM document
INNER JOIN doctype
ON document.iddoctypes = doctype.iddoctypes
WHERE document.revision = (
SELECT MAX(d1.revision)
FROM document d1
WHERE document.linkid = d1.linkid
)
ORDER BY document.doccreation DESC
Just a wild guess: I think you have to add group by title in your (select max(...) ...) subquery.
So the complete statement will be this:
$query_docs = "
SELECT `document`.*, doctype.*
FROM `document`
INNER JOIN doctype
ON `document`.iddoctypes = doctype.iddoctypes
WHERE `document`.revision = (
SELECT MAX(`document`.revision) AS revision
FROM `document`
--GROUP BY `document`.title
GROUP BY `document`.linkid
)
GROUP BY `document`.linkid
ORDER BY `document`.doccreation DESC";
Am I missing something? This seems completely straightforward...
SELECT x.*
FROM my_table x
JOIN (SELECT title,MAX(revision) max_revision FROM my_table GROUP BY title) y
ON y.title = x.title
AND y.max_revision = x.revision;

Categories