PHP MYSQLI Count Row Correct - php

Table
Hello i try to finds all hashtags with name #c3 and mysqli query show me: 3 rows but correct is 2 rows with #c3 ??? where is problem ? I want to show me 2Rows !
$sql_query = mysqli_query($Connection, "SELECT * FROM my_table WHERE hashtag LIKE '%#c3%'");
echo mysqli_num_rows($sql_query);

To answer this and as left in comments (by myself)
Use '%#c3' by removing the last %
Using LIKE, the % wildcard does the following and a few examples:
%XXX% - Matches anything before and after XXX
%XXX - Matches anything before XXX
XXX% - Matches anything after XXX.
References:
http://dev.mysql.com/doc/refman/5.7/en/string-comparison-functions.html
http://dev.mysql.com/doc/refman/5.7/en/pattern-matching.html
http://www.tutorialspoint.com/mysql/mysql-like-clause.htm
Plus, should there be any user input, consider using a prepared statement:
https://en.wikipedia.org/wiki/Prepared_statement
It will help against a potential SQL injection.
https://en.wikipedia.org/wiki/SQL_injection

Hi Your query is wrong try to use this
SELECT * from my_table WHERE FIND_IN_SET('#c3', hashtag);
FIND_IN_SET returns the position of a string if it is present (as a substring) within a list of strings. The string list itself is a string contains substrings separated by ‘,’ (comma) character.
for more info read http://www.w3resource.com/mysql/string-functions/mysql-find_in_set-function.php

You can use FIND_IN_SET
SELECT * FROM my_table WHERE FIND_IN_SET('#c3',hashtag)
See docs here and example here

Split the table into 2 tables:
post: id | text | date
1
2
3
post_hashtag: post_id | hashtag
1 #c1
1 #c3
2 #c3
3 #c3blabla
Then your query becomes:
SELECT post.*,post_hashtag.hashtag FROM post JOIN post_hashtag ON post.id=post_hashtag.post_id WHERE hashtag='#c3#';
The act of splitting the table is called normalizing and you need to do this because your tables are not in any normal form which makes them not relational which defeats the purpose of storing them in a relational database. Check https://en.wikipedia.org/wiki/First_normal_form for more information.

Looking at your table, I would suggest that you break up your tables to have a many to many link for hashtag. That way you can search for all records that have a matching hashtag.
data table
+----+------+------+
| id | text | date |
+----+------+------+
hash table
+----+------+
| id | hash |
+----+------+
link table
+---------+---------+
| data_id | hash_id |
+---------+---------+
This would then allow you to use an SQL statement like:
SELECT * FROM data
INNER JOIN link ON data_id = data.id
INNER JOIN hash ON hash_id = hash.id
WHERE hash = '#3';

Related

mysql like query exclude numbers

I have a small problem with a php mysql query, I am looking for help.
I have a family tree table, where I am storing for each person his/her ancestors id separated by a comma. like so
id ancestors
10 1,3,4,5
So the person of id 10 is fathered by id 5 who is fathered by id 4 who is fathered by 3 etc...
Now I wish to select all the people who have id x in their ancestors, so the query will be something like:
select * from people where ancestors like '%x%'
Now this would work fine except, if id x is lets say 2, and a record has an ancestor id 32, this like query will retrieve 32 because 32 contains 2. And if I use '%,x,%' (include commas) the query will ignore the records whose ancestor x is on either edge(left or right) of the column. It will also ignore the records whose x is the only ancestor since no commas are present.
So in short, I need a like query that looks up an expression that either is surrounded by commas or not surrounded by anything. Or a query that gets the regular expression provided that no numbers are around. And I need it as efficient as possible (I suck at writing regular expressions)
Thank you.
Edit: Okay guys, help me come up with a better schema.
You are not storing your data in a proper way. Anyway, if you still want to use this schema you should use FIND_IN_SET instead of LIKE to avoid undesired results.
SELECT *
FROM mytable
WHERE FIND_IN_SET(2, ancestors) <> 0
You should consider redesigning your database structure. Add new table "ancestors" to database with columns:
id id_person ancestor
1 10 1
2 10 3
3 10 4
After -- use JOIN query with "WHERE IN" to choose right rows.
You're having this issue because of wrong design of database.First DBMS based db's aren't meant for this kind of data,graph based db's are more likely to fit for this kind of solution.
if it contain small amount of data you could use mysql but still the design is still wrong,if you only care about their 'father' then just add a column to person (or what ever you call it) table. if its null - has no father/unknown otherwise - contains (int) of his parent.
In case you need more then just 'father' relationship you could use a pivot table to contain two persons relationship but thats not a simple task to do.
There are a few established ways of storing hierarchical data in RDBMS. I've found this slideshow to be very helpful in the past:
Models for Hierarchical Design
Since the data deals with ancestry - and therefore you wouldn't expect it to change that often - a closure table could fit the bill.
Whatever model you choose, be sure to look around and see if someone else has already implemented it.
You could store your values as a JSON Array
id | ancestors
10 | {"1","3","4","5"}
and then query as follows:
$query = 'select * from people where ancestors like \'%"x"%\'';
Better is of course using a mapping table for your many-to-many relation
You can do this with regexp:
SELECT * FROM mytable WHERE name REGEXP ',?(x),?'
where x is your searched value
DROP TABLE IF EXISTS my_table;
CREATE TABLE my_table
(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
,ancestors VARCHAR(250) NOT NULL
);
INSERT INTO my_table VALUES(10,',1,3,4,5');
SELECT *
FROM my_table
WHERE CONCAT(ancestors,',') LIKE '%,5,%';
+----+-----------+
| id | ancestors |
+----+-----------+
| 10 | ,1,3,4,5 |
+----+-----------+
SELECT *
FROM my_table
WHERE CONCAT(ancestors,',') LIKE '%,4,%';
+----+-----------+
| id | ancestors |
+----+-----------+
| 10 | ,1,3,4,5 |
+----+-----------+

how to use where condition from stored data in array

id | name | permission
1 | John | 1,4,3
2 | mike | 7,4,3
3 | sky | 3,2,1
this is my database
now i have fetch select query with where condition
e.g. select * from friend where permission='4'
but i m not able fetch any data so what to do ?
Please help
Select * from friend where FIND_IN_SET('4',permission);
It looks like you have multiple permissions stored together in a string.
To you, the query looks like:
select * from friend where permission='4'
That means anything containing 4.
To mysql, it sees:
select * from friend where permission= ONLY '4'
// Meaning the permissions column can ONLY CONTAIN 4.
// Also, ONLY is meant as a visual, don't use it in queries.
Try:
find_in_set('4',permission) <> 0
// This means It needs to find number 4 and can't return 0 results.
Check out these for more info:
MySQL query finding values in a comma separated string
http://www.w3resource.com/mysql/string-functions/mysql-find_in_set-function.php
It can be done by the following query :
select * from friend where permission like '%4%'

Use search results (Like %search%), to match id's in another table in the database

I have two tables in the database, parts, and products.
I have a column in the products table with strings of ids (comma separated). Those ids match ids of the parts table.
**parts**
ID | description (I'm searching this part)
-------------------------------
1 | some text here
2 | some different text here
3 | ect...
**products**
ID | parts-list
--------------------------------
1 | 1,2,3
2 | 2,3
3 | 1,2
I'm really struggling with the SQL query on this one.
I've done the 1st part, got the id's from the parts table
SELECT * FROM parts WHERE description LIKE '%{$search}%'
The biggest problem is the comma separated structure of the the description column.
Obviously, I could do it in PHP, create an array of the the results from the parts table, use that to search the products table for id's, and then use those results to grab the row data from the parts table (again). Not very efficient.
I also tried this, but I'm obviously trying to compare two arrays here, not sure how this should be done.
SELECT * FROM `products` WHERE
CONCAT(',', description, ',')
IN (SELECT `id` FROM `parts` WHERE `description` LIKE '%{$search}%')
Can anybody help?
I would perhaps try a combination of LOCATE() and SUBSTR(). I work mainly in MSSQL which has CHARINDEX() that I think works like MySQL's LOCATE(). It is bound to be messy. Are there a variable number of elements in the parts-list field?

searching strings in SQL

I'm building a simple shopping cart. I need to allow for related products. My initial thought was to have a db field in the product table called tags which will have a comma delimited list of tags in it:
tag1,tag2,tag3
When I grab the product from the db I could also grab the tags and explode the string on the comma.
Problem is i'm having trouble thinking of a good way to then call to the db for all other products that have a matching tag. Is there way to search a string in SQL?
can anyone think of a good way to achieve this
You can use FIND_IN_SET() for that purpose:
SELECT * FROM tableName WHERE FIND_IN_SET('tag1', tags) > 0
However, I would strongly suggest to read on database normalization and joins instead.
Pleaso do not use any of the answers mentioning the LIKE syntax. For example WHERE tags LIKE %tag1% would match tag1 but also tag12 which is just wrong.
I would not go down the route of storing comma separated strings in fields, its not very scalable (or normalized) . I would split this up into 3 different tables:
products:
-------------
id | name
-------------
1 | product 1
2 | product 2
tags:
---------------
id | tag
---------------
1 | tag 1
2 | tag 2
product_tags:
----------------------
product_id | tag_id
----------------------
1 | 1
1 | 2
When you want to find products with related tags you would just do
SELECT product_id FROM product_tags WHERE tag_id = TAG_ID
You could then use more advanced joining statements to return the records from the products table (instead of just product_id's from the tags table):
SELECT products.* FROM products
INNER JOIN product_tags ON product_tags.product_id = products.id
WHERE product_tags.tag_id = TAG_ID
Its a bit more work but it will save you headaches in the future.
Consider using MySQL LIKE clause (check out this guide: http://www.tutorialspoint.com/mysql/mysql-like-clause.htm). You may use it on each tag, something like this:
SELECT * FROM `product` WHERE `tags` LIKE '%tag1%' OR `tags` LIKE '%tag2%' OR `tags` lIKE '%tag3'
To search for a string in SQL you can use the LIKE operator. Here is an example:
mysql_query("SELECT * FROM table_name WHERE value LIKE '%str%' ");

Select random row per distinct field value?

I have a MySQL query that results in something like this:
person | some_info
==================
bob | pphsmbf24
bob | rz72nixdy
bob | rbqqarywk
john | kif9adxxn
john | 77tp431p4
john | hx4t0e76j
john | 4yiomqv4i
alex | n25pz8z83
alex | orq9w7c24
alex | beuz1p133
etc...
(This is just a simplified example. In reality there are about 5000 rows in my results).
What I need to do is go through each person in the list (bob, john, alex, etc...) and pull out a row from their set of results. The row I pull out is sort of random but sort of also based on a loose set of conditions. It's not really important to specify the conditions here so I'll just say it's a random row for the example.
Anyways, using PHP, this solution is pretty simple. I make my query and get 5000 rows back and iterate through them pulling out my random row for each person. Easy.
However, I'm wondering if it's possible to get what I would from only a MySQL query so that I don't have to use PHP to iterate through the results and pull out my random rows.
I have a feeling it might involve a BUNCH of subselects, like one for each person, in which case that solution would be more time, resource and bandwidth intensive than my current solution.
Is there a clever query that can accomplish this all in one command?
Here is an SQLFiddle that you can play with.
To get a random value for a distinct name use
SELECT r.name,
(SELECT r1.some_info FROM test AS r1 WHERE r.name=r1.name ORDER BY rand() LIMIT 1) AS 'some_info'
FROM test AS r
GROUP BY r.name ;
Put this query as it stands in your sqlfiddle and it will work
Im using r and r1 as table alias names. This will also use a subquery to select a random some_info for the name
SQL Fiddle is here
My first response would be to use php to generate a random number:
$randId = rand($min, $max);
Then run a SQL query that only gets the record where your index equals $randID.
Here is the solution:
select person, acting from personel where id in (
select lim from
(select count(person) c, min(id) i, cast(rand()*(count(person)-1) +min(id)
as unsigned) lim from personel group by person order by i) t1
)
The table used in the example is below:
create table personel (
id int(11) not null auto_increment,
person char(16),
acting char(19),
primary key(id)
);
insert into personel (person,acting) values
('john','abd'),('john','aabd'),('john','adbd'),('john','abfd'),
('alex','ab2d'),('alex','abd3'),('alex','ab4d'),('alex','a6bd'),
('max','ab2d'),('max','abd3'),('max','ab4d'),('max','a6bd'),
('jimmy','ab2d'),('jimmy','abd3'),('jimmy','ab4d'),('jimmy','a6bd');
You can limit the number of queries, and order by "rand()" to get your desired result.
Perhaps if you tried something like this:
SELECT name, some_info
FROM test
WHERE name = 'tara'
ORDER BY rand()
LIMIT 1

Categories