I have this table:
+---------+----------+
+ Items + Person +
+---------+----------+
+ 2,99,75 + Jack +
+ 4,9,63 + Rose +
+---------+----------+
Now I do a simple
LIKE :items
and binding it using
$stmt->bindParam(':items',$item,PDO::PARAM_STR);
where
$item = "%9%".
The result contains both Jack and Rose, which is wrong because I expected to have Rose only as my result. It seems that LIKE sees both 99 and 9. How can I restrict my LIKE to have only 9 because that was the value of $items?
The other answers are good to do. However, I pose this alternative based on the fact that Items appears to be ID's.
If you need to query off comma separated values I would recommend a separate table. Using LIKE to query in a single field will never truly be fool-proof and could be a security concern. Try this.
Table 1: Person
+---------+----------+
+ ID + Person +
+---------+----------+
+ <int> + <string> +
+---------+----------+
Table 2: Item
+---------+----------+
+ PersonID+ ItemID +
+---------+----------+
+ <int> + <int> +
+---------+----------+
Then use joins to query both tables as needed.
SELECT * FROM Person INNER JOIN Items ON Items.PersonID = Person.ID
WHERE Items.ItemID = '9';
This should provide you with every record in Person that has ItemID "9" associated with them.
Perhaps this might help: http://www.codinghorror.com/blog/2007/10/a-visual-explanation-of-sql-joins.html
Its because % represent one or more character (anything). So 99 will match the "%9%"
If you want only 9, you can try with
"%,9,%"
I believe the main issue on this is what #interrobang said, the way you are representing the data.
If this table X that you show is the list itens for each person, you should have a column with the person id and another column with the item id, and multiple lines to represent multiple itens for each person. Doing like this your search would be much faster and easier to use and mantain in the future.
SQL Fiddle
MySQL 5.5.30 Schema Setup:
CREATE TABLE person (
id int auto_increment primary key,
name varchar(20)
);
CREATE TABLE item (
id int auto_increment primary key,
name varchar(20)
);
CREATE TABLE person_item (
id int auto_increment primary key,
person_id int,
item_id int
);
ALTER TABLE person_item ADD UNIQUE (person_id,item_id);
INSERT INTO person(id,name) VALUES
(1, 'John'),
(2, 'Mary'),
(3, 'Oliver');
INSERT INTO item (id,name) VALUES
(1,'Pen'),
(2,'Pencil'),
(3,'Book');
INSERT INTO person_item (person_id,item_id) VALUES
(1,1),
(1,3),
(2,2),
(3,1);
Query 1:
select p.name from person_item pi, person p, item i
where pi.person_id = p.id
and pi.item_id = i.id
and i.name LIKE 'Book%'
Results:
| NAME |
--------
| John |
Related
How to run query in php for sum of two or more column in horizintally.
suppose i have table like
srno name english maths science TotalMarks
1 rohit 52 52 52 ?
so how to get sum of all marks. and show in total marks field. by php code.
The correct approach would be somewhat as follows:
DROP TABLE IF EXISTS my_table;
CREATE TABLE my_table
(id SERIAL PRIMARY KEY
,srno INT NOT NULL
,subject VARCHAR(20) NOT NULL
,mark INT NOT NULL
);
INSERT INTO my_table VALUES
(1,1,'english',52),
(2,1,'maths',52),
(3,1,'science',52);
SELECT srno
, SUM(mark) total
FROM my_table
GROUP
BY srno;
+------+-------+
| srno | total |
+------+-------+
| 1 | 156 |
+------+-------+
Try something like this:
SELECT srno, name, english, maths, science, (english+maths+science) As TotalMarks FROM `table_name`
Check also this topic:
How to SUM two fields within an SQL query
Well You can try these two methods:
select * from Your_Table_Name;
and when you display your result, you can add all these values like:
srno name english maths science TotalMarks
$id $name $english $maths $science ($english+$maths+$science)
OR
select id, name, english, math, science, (english+maths+science) as Total from Your_Table_Name;
Try this :
SELECT *, (english + maths + science) AS Total FROM table;
In my data table I have a column reference, data of this column is composed of categorie + idproduct + idmaker example:
reference | categorie + idproduct + idmaker
---------------|--------------------
cat48934547814 | [cat48][934][547814]
cat55548451412 | [cat55][548][451412]
cat48548547814 | [cat48][548][547814]
I want search all product having the reference that starts with cat48 and ends by 547814.
thanks
you could use a pair of like
select *
from my_table
where reference like 'cat48%'
and reference like '%547814'
or with substring
select *
from my_table
where left(reference, 5) = 'cat48'
and right(reference ,6) = '547814'
I don’t know how to make this with mysql, I only know how to do basic queries, I want to show a list of result based on matches, Results will be shown based on the same value of the answers…answers may have a value from 1-10
+++++++++++++++TABLE++++++++++++
id | userName | answer1 | answer2 | answer3 | answer4….
10 Jhon 1 1 3 8
11 Anne 1 2 4 8
12 Mike 7 4 5 7
etc…
++++++++++++++++++++++++++++++++++++++++
If I send the values in the query I want that check the answers and show the result sorted my matches,
more matches first…no matches last
So if i send the results:
answer1=1 answer2=1 answer3=7 answer4=2...
the result should be(give back the id)
10 11 12
Your table design is not fine, you should separate it into users and questions table.
If you cannot change the table design you can solve you problem using this query:
select
id,
username,
if(answer1 = :an1, 1, 0) + if(answer2 = :an2, 1, 0) + if(answer3 = :an3, 1, 0) + if(answer4 = :an4, 1, 0) as total
from
table
order by total desc
UPDATE:
Better design for this problem:
Check the SQLFiddle: http://sqlfiddle.com/#!9/6c145/2 with a live demo.
Create Users Table
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL
);
Create Questions Table
CREATE TABLE questions (
id INT PRIMARY KEY,
correct_answer INT NOT NULL
);
Create User Answers Table
CREATE TABLE user_answers (
user_id INT,
question_id INT,
user_answer TINYINT,
PRIMARY KEY (user_id, question_id),
FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE NO ACTION ON UPDATE NO ACTION,
FOREIGN KEY (question_id) REFERENCES questions (id) ON DELETE NO ACTION ON UPDATE NO ACTION
);
Than to retrieve the data you can use the query:
SELECT
tmp.id,
tmp.username,
sum(tmp.is_correct) as total
FROM (
SELECT
users.id,
users.username,
IF (questions.correct_answer = user_answers.user_answer, 1, 0) as is_correct
FROM
users
INNER JOIN user_answers on users.id = user_answers.user_id
INNER JOIN questions on user_answers.question_id = questions.id
) tmp
GROUP BY tmp.id, tmp.username
ORDER BY total desc;
Well, I've a table called keywords and there are 2 columns.
1) kid
2) keywords (keyword value)
and I've another table called contact_details where there a column called keyword. In this keyword column I'm inserting many keyword from keywordstable. So 2 tables is look like this...
Keywords table:
kid keyword
1 php
1 mysql
1 html
1 css
1 css3
1 wp
1 photoshop
1 3d
contact_details table:
cid name phone keyword
1 alex 123 php, mysql, hmtl
2 alex1 124 php, html, css3
3 alex2 125 wp, html, css
4 alex3 126 photoshop, 3d
5 alex4 127 html, 3d, php
6 alex5 128 mysql, wp, html
Now I've a search box which is searching people (name From contact_details table) by using keyword value. In search box, Search value could be few keywords. I mean it's could be php, mysql, html or could be php, 3d, photoshop.
So My question is : how can I write a Sql query to get the result ? I want to get all name which match the search keyword/s from contact_details table ?
Is there any field need to add in keywords table ? Can not get an IDEA :(
Select name from contact_details where keyword like '%<search keywords>%'
Like search keyword key php then you need pass php in query and will get list of all name which having keywords as php'
Select name from contact_details where keyword like '%php%'
hope this will resolve your issue.
Proper approach,
Make kid as primary key in Keyword table
Keywords table:
kid keyword
1 php
2 mysql
3 html
Remove keywords column from contact_details table.
contact_details table:
cid name phone
1 alex 123
2 alex1 124
3 alex2 125
Make one more table which having many to many relationship and you need insert the relationship here so that no need touch again keywords and contact_details table again.
keyword_contact_mapping
kcid kid_fk cid_fk
1 1 1
2 1 2
3 1 3
4 2 1
5 2 1
6 2 2
7 2 3
Sql query (Not tested you can also use alias)
select name from contact_details join keyword_contact_mapping on kid_fk =(select kid from Keywords where keyword='php')
Assuming you have the ID when the name is selected, you can use:
SELECT Keyword from Keywords_Table
WHERE ID = <ID>
USE AdventureWorksDW2008R2
GO
IF OBJECT_ID('Keywords') IS NOT NULL
BEGIN
DROP TABLE Keywords
END
IF OBJECT_ID('Contact_Details') IS NOT NULL
BEGIN
DROP TABLE Contact_Details
END
IF OBJECT_ID('Keyword_ContactDetails') IS NOT NULL
BEGIN
DROP TABLE Keyword_ContactDetails
END
/* automate id's with identity. Or, do you want to specify the the keyword id manually?
*/
CREATE TABLE Keywords(
Keywords_ID INT IDENTITY(1,1) NOT NULL
,Keyword NVARCHAR(100)
CONSTRAINT PK_Keywords PRIMARY KEY
(
Keywords_ID
)
)
/* You must plan each column data type by careful consideration
I am using the phone example here to demonstrate different business requirements
the lenghts and datatype may need to change for localization
*/
CREATE TABLE Contact_Details
(
Contact_Details_ID INT IDENTITY(1,1) NOT NULL
,First_Name VARCHAR(100)
,Last_Name VARCHAR(100)
,Phone VARCHAR(10)
,Phone_EXT VARCHAR(3)
,Phone_International NVARCHAR(15)
CONSTRAINT PK_Contact_Details PRIMARY KEY
(
Contact_Details_ID
)
)
CREATE TABLE Keyword_ContactDetails
(
Keyword_ID INT
,Contact_Details_ID INT
,DateTime_Created DATETIME
CONSTRAINT PK_KeywordContact PRIMARY KEY
(
Keyword_ID
,Contact_Details_ID
)
/*Enforce referential integrity,
prevents adding keywords that don't exist
prevents deleting a keyword if it is referenced
*/
FOREIGN KEY (Keyword_ID) REFERENCES Keywords(Keywords_ID),
FOREIGN KEY (Contact_Details_ID) REFERENCES Contact_Details(Contact_Details_ID)
)
/* Populate keywords
*/
INSERT INTO Keywords(Keyword) VALUES ('PHP')
INSERT INTO Keywords(Keyword) VALUES ('MYSQL')
INSERT INTO Keywords(Keyword) VALUES ('HTML')
INSERT INTO Keywords(Keyword) VALUES ('CSS')
/* Add contact details
*/
INSERT INTO Contact_Details(
First_Name
,Last_Name
,Phone
,Phone_EXT
,Phone_International)
VALUES(
'Abe'
,'Lincoln'
,'2129996677'
,'123'
,'na')
/* Assign PHP Keyword to Abe Lincoln
*/
DECLARE #keywordID int = 0
,#contactDetails int = 0
set #keywordID = (select Keywords_ID from Keywords where Keyword = 'PHP')
set #contactDetails = (select Contact_Details_ID from Contact_Details where Last_Name = 'Lincoln')
INSERT INTO Keyword_ContactDetails(
Keyword_ID
,Contact_Details_ID
,DateTime_Created)
VALUES(
#keywordID
,#contactDetails
,CURRENT_TIMESTAMP)
SELECT * FROM Contact_Details C
JOIN Keyword_ContactDetails KC
ON KC.Contact_Details_ID = C.Contact_Details_ID
JOIN Keywords K
ON K.Keywords_ID = KC.Keyword_ID
I need to sum the totals of a row except the first column.
Something similar too:
SELECT SUM( col2 + col3 + col4 +colN)
FROM numbers
WHERE user_name = 'person';
My table will continuously have columns added to it. So I want it to automatically pick up the sum of the new columns too without it needing to be hard coded into the query?
user_name | Col | col2 | Col3 | Col4 + other columns.
person1 | 2 | 3 | 76 | 56 etc. ---------> sum of row
person2 | 6 | 72 | 200 | 13 etc. ---------> sum of row
Thanks in advance for any help!
Not wishing to 'avoid' the question, but it looks like you could do with having a different data structure.
You should consider having a 'users' table with columns for id and user_name, and a new table (e.g. properties) with a row for each of the other columns in your current table (Col1, Col2 ... ColN). The new table would then have a column for user_name to link it to the users table.
That way you'd be able to do something like:
SELECT SUM(property_column) FROM properties WHERE user_name = <RequiredUserName>
I'd also recommend selecting users by ID (i.e. have the properties table with a user_id column, rather than a user_name column), unless you're confident that a user_name is never going to change (and even then...).
Maybe the easiest solution is to do it in PHP:
$res = mysql_query("select * from numbers where user = ...");
while ($row = mysql_fetch_assoc($res)) {
$row['Id'] = 0; // don't want to sum the Id
$sum = array_sum($row); // this is the required sum
....
}
As stated you would be better advised revisiting your database structure,
If you can't and
If you want to do it in PHP you can get the resultset back and then loop through the fields and exclude the fields you don't want then add up everything else, assuming it is of the right type, use mysql_field_type to find those of a specific type.