Join table fields with different ID in PHP - php

How to join many fields with different ID's in only one?
I have this MySQL table:
--------------------------------
| *UDH* | *Text* |
--------------------------------
| 050003B90301 | Hi my name is A|
--------------------------------
| 050003B90302 | rmin and I wan |
--------------------------------
| 050003B90303 | t be your frien |
--------------------------------
The UDH field is different but I need join the text field to copy to other table, the result must to be like this:
______________________________________________________________
| UDH | Text |
--------------------------------------------------------------
| 1 | Hi my name is Armin and I want be your frien |
---------------------------------------------------------------
Do you know a PHP sentence or other method to make something like this?

Use GROUP_CONCAT(). Like this:
select '1' as UDH, group_concat(`Text` separator '') as `Text` from myTable;
If you need to order by the UDH column, you can do that within the group_concat() call like this:
select '1' as UDH, group_concat(`Text` order by UDH separator '') as `Text` from myTable;
I just validated this query with the following test code based on your example:
mysql> create table myTable (UDH varchar(32), `Text` text) engine=innodb;
Query OK, 0 rows affected (0.05 sec)
mysql> insert into myTable (UDH, `Text`) values ('050003B90301', 'Hi my name is A'), ('050003B90302', 'rmin and I wan'), ('050003B90303', 't be your frien');
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> select * from myTable;
+--------------+-----------------+
| UDH | Text |
+--------------+-----------------+
| 050003B90301 | Hi my name is A |
| 050003B90302 | rmin and I wan |
| 050003B90303 | t be your frien |
+--------------+-----------------+
3 rows in set (0.00 sec)
mysql> select '1' as UDH, group_concat(`Text` order by UDH separator '') as `Text` from myTable;
+-----+----------------------------------------------+
| UDH | Text |
+-----+----------------------------------------------+
| 1 | Hi my name is Armin and I want be your frien |
+-----+----------------------------------------------+
1 row in set (0.01 sec)

Related

PHP MySQL consolidate column where other column has duplicates

I have a MySQL table that has three columns, the first is a unique key (INT(11) AUTO_INCREMENT), the next is an indexed value (VARCHAR(255)) and the third is a description (TEXT). There are duplicate values in the second column, but each row has a different description. I want to remove all rows where the second column is duplicated but append each description of the same indexed value to the first instance the value, and breaking string with a semicolon and space.
For example, my table looks like this:
cid | word | description
------------------------------
1 | cat | an animal with wiskers
2 | cat | a house pet
3 | dog | a member of the canine family
4 | cat | a cool person
I want to change the table to look like this:
cid | word | description
------------------------------
1 | cat | an animal with wiskers; a house pet; a cool person
3 | dog | a member of the canine family
I'm not adverse to using a PHP script to do this, but would prefer MySQL. The table has over 170,000 rows and would take PHP a long time to loop over it.
SQL:
select `cid`,`word`,group_concat(`description` SEPARATOR '; ') as `description` from `test_table` group by `word`;
Ok.. you can copy all the data into another table, and rename it then..
insert into `test_new` (`cid`,`word`,`desc`) (select `cid`,`word`,group_concat(`desc` SEPARATOR '; ') as `description` from `test_table` group by `word`);
mysql> describe `test_new`;
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| word | char(10) | YES | | NULL | |
| desc | text | YES | | NULL | |
+-------+----------+------+-----+---------+-------+
3 rows in set (0.00 sec)
mysql> select * from `test_new`;
+------+------+---------------------+
| id | word | desc |
+------+------+---------------------+
| 1 | cat | desc1; desc2; desc4 |
| 3 | dog | desc3 |
+------+------+---------------------+
2 rows in set (0.00 sec)
As was mentioned before, you can create a new table and copy the info, you can also do it in two steps, but only if thereĀ“s no problem with modifying the old table:
UPDATE tableOld AS N1, tableOld AS N2
SET N1.description = concat(concat(N1.description,"; "),N2.decription))
WHERE N2.word = N1.word
insert into tableNew (cid,name,description)select * from tableOld group by word

SQL query to get row count

I have a query in my PHP where I'm searching for string:
select * from feed1 where PNAME like '%clothes%' limit 5;
I also want to get count of PNAME like cloth for which I'm using separate search query:
$qry=mysqli_query(select * from feed1 where PNAME like '%clothes%');
$rows=mysqli_num_rows($qry);
Rows query is taking too much time to load the page. Is there any way we can get total row count and limit of up to 5 products from one query? Thereby, the load time will decrease.
+-------+------------+----------+--------------+-------------+-----------+------
-------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardi
nality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+----------+--------------+-------------+-----------+------
-------+----------+--------+------+------------+---------+---------------+
| xml | 0 | PRIMARY | 1 | BOSID | A |
7233 | NULL | NULL | | BTREE | | |
+-------+------------+----------+--------------+-------------+-----------+------
-------+----------+--------+------+------------+---------+---------------+
1 row in set (0.00 sec)
You can't do this by one query, but for get count, use COUNT(*) instead of get all the data out.
To get the count:
select count(*) from feed1 where PNAME like '%clothes%'
then get first 5:
select * from feed1 where PNAME like '%clothes%' limit 5
There should be at least two queries for pagination.

MYSQL RANDOM SELECT UNIQUE ROWS - Excluding previously selected rows

I have a table of 16K entries
I want to extract random 44 entries
but I don't want to repeat the same entries more then once (ever)
so i have a per-user list that keeps the already used 'IDs' as a comma-separated string in a table.
and I use that list to SELECT ... NOT IN (used_IDs)
The issue is that this list is getting too big and the sql call fails because of size i believe
Any idea on how to do that more usefully?
Questions table:
+------+-------+-------+
| id | Qtext | Tags |
+------+-------+-------+
Test table:
+------+-------+
| id | QIDs |
+------+-------+
Results table:
+------+-------+-------+
| id | tID | uID |
+------+-------+-------+
I need to select unique random values from Questions table based on the results table. (which associates test ID with Question IDs)
Currently trying to use:
SELECT DISTINCT `questions`.`ID`
FROM `questions`, `tests`, `results`
WHERE
`questions`.`ID` NOT IN (`tests`.`qIDs`)
AND `results`.`uID` = 1 AND `tests`.`ID` = `results`.`tID`
AND 4 IN ( `questions`.`tags`)
AND "http://www.usmlestep2qna.com" = `provider`
ORDER BY RAND() LIMIT 27;
Any ideas?
Instead of placing the used user Id values in a comma-separated string in one column, you could create a tall table to store them. This should yield better preformance
Rather than using a single row with a (potentially huge) CSV, why not use a nicely indexed table and an outer join to pick unmatched records. I have an example from my test database:
mysql> select * from first;
+------+-------+
| id | title |
+------+-------+
| 1 | aaaa |
| 2 | bbbb |
| 3 | cccc |
| 4 | NULL |
| 6 | gggg |
+------+-------+
5 rows in set (0.00 sec)
mysql> select * from second;
+------+----------+------+------+-------+------+
| id | first_id | one | two | three | four |
+------+----------+------+------+-------+------+
| 1 | 1 | 3 | 0 | 4 | 6 |
| 1 | 2 | 4 | 4 | 1 | 2 |
| 3 | 3 | 1 | NULL | 3 | 4 |
+------+----------+------+------+-------+------+
3 rows in set (0.00 sec)
mysql> select a.id from first a join second b on a.id=b.first_id;
+------+
| id |
+------+
| 1 |
| 2 |
| 3 |
+------+
3 rows in set (0.00 sec)
mysql> select a.id from first a
left outer join second b on a.id=b.first_id where b.first_id is null;
+------+
| id |
+------+
| 4 |
| 6 |
+------+
2 rows in set (0.00 sec)
This should improve your performance rather nicely.

Simple UPDATE SQL Query

I'm doing a work for a client but since I haven't been using PHP/MySQL for a while I forgot some simple things, hope you can help me out.
I have the following SQL table:
ID (non-null, autoincrement) | credit (int)
My query should put the whole "credit" column to 0 except for the row that has the higher ID.
So I would do:
UPDATE $table SET credit = 0 WHERE... ?
Thanks in advance for any help :)
UPDATE $table SET credit = 0 WHERE ID > $ID
Will update any rows that have and ID greater than the variable $ID
If you only want to update the row with the maximum ID then use:
UPDATE $table SET credit = 0 WHERE ID = (select max(id) from $table)
Edit: As Eggyal correctly points out MySQL doesn't like a subquery on the same table as an update - but you can get around it nicely:
UPDATE $table
SET credit = 0
WHERE
credit='$credit'
AND statid='$statid'
AND userid='$userid'
AND ID = (select ID from (SELECT MAX(ID)as ID from $table) a)
And examples from my console:
mysql> select * from first;
+------+-------+
| id | title |
+------+-------+
| 1 | aaaa |
| 2 | bbbb |
| 3 | cccc |
| 4 | NULL |
| 6 | eeee |
+------+-------+
5 rows in set (0.00 sec)
mysql> update first set title='ffff' where id=(select max(id) from first);
ERROR 1093 (HY000): You can't specify target table 'first' for update in FROM clause
mysql> update first set title='ffff' where id=(select ID from (select max(id) as ID from first) a);
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from first;
+------+-------+
| id | title |
+------+-------+
| 1 | aaaa |
| 2 | bbbb |
| 3 | cccc |
| 4 | NULL |
| 6 | ffff |
+------+-------+
5 rows in set (0.00 sec)
Note: As the subquery within a subquery trick unlocks the original table, it is a good idea to run this within a transaction - if the table is unlocked from a query, it might have changed by the time it is updated - so it will be a good idea to use this type of query within a transaction.

concat() how to query search a string?

I have a table setup with the following rows:
orderfrom | Name
-------------------------------------------------------
ClearVision, Oakley, I-Deal Optics | ClearVision
ClearVision | I-Deal Optics
ClearVision | Oakley
I want a query that will select rows where the "Name" value is not found in the "orderfrom" column. In this case, it would return the 2nd and 3rd rows, but not the first row (since "ClearVision" is in the orderfrom column).
Here is what I've tried:
SELECT * FROM `dist`
JOIN `patientacct`
ON `patientacct`.dist LIKE CONCAT('%', `dist`.name ,'%')
INNER JOIN `treasure`
ON `treasure`.`id` = `patientacct`.`id`
WHERE (status = 'To Order' AND ****** ORDER BY `name` ASC);
The ** part is where I need help. I have tried this:
(( `dist`.name NOT LIKE CONCAT('%',`patientacct`.orderfrom,'%')) ))
INNER JOIN treasure
ON treasure.id = patientacct.id
WHERE
status = 'To Order'
AND dist.name NOT LIKE CONCAT('%',patientacct.orderfrom,'%')
I am not sure, but wouldn't this much simpler code work just fine?
mysql> select * from stringComp;
+------------------------------------+---------------+
| value1 | value2 |
+------------------------------------+---------------+
| ClearVision, Oakley, I-Deal Optics | ClearVision
|
| ClearVision | I-Deal Optics |
| ClearVision | Oakley |
| ClearVision, Oakley, I-Deal Optics | ClearVision |
+------------------------------------+---------------+
4 rows in set (0.00 sec)
Note the row 1 value 2 has extra whitespace around it.
mysql> select * from stringComp where value1 not like concat('%',value2,'%');
+------------------------------------+---------------+
| value1 | value2 |
+------------------------------------+---------------+
| ClearVision, Oakley, I-Deal Optics | ClearVision
|
| ClearVision | I-Deal Optics |
| ClearVision | Oakley |
+------------------------------------+---------------+
3 rows in set (0.00 sec)
This simple SQL compares the contents of column value2 to see if they are in column value1 and returns the rows where they are not.
So, to answer your question, I think this little snippet in the where clause shold get you the right results: value1 not like concat('%',value2,'%')
Edit: I just saw the extra line in your query: I think there is an extra bracket in
(( `dist`.name NOT LIKE CONCAT('%',`patientacct`.orderfrom,'%')) ))
Should be:
(( `dist`.name NOT LIKE CONCAT('%',`patientacct`.orderfrom,'%')))
Edit 2: Why do you have all those brackets in there anyhow?
SELECT
*
FROM
`dist`
JOIN `patientacct`
ON `patientacct`.dist LIKE CONCAT('%', `dist`.name ,'%')
INNER JOIN `treasure`
ON `treasure`.`id` = `patientacct`.`id`
WHERE
status = 'To Order'
AND `dist`.name NOT LIKE CONCAT('%',`patientacct`.orderfrom,'%')
ORDER BY
`name` ASC;

Categories