I have a column named software_hardware from the table activities which could have multiple product inputs separated by a pipeline like INVENTORY| POS | or GPOS | ACCOUNTING |.
I have this query:
SELECT a.id, a.ticket_number, a.client, a.software_hardware,
a.issues_concern, a.status, a.technical_programmer, a.date_added
FROM activities a
WHERE a.client = '".$_POST['client']."' AND a.software_hardware LIKE '%".$arr[$i]."%'
ORDER BY date_added DESC
$arr = explode("|", $_POST['Soft_hard']);
When I select a client and a product, related info would be displayed on a div. Now my problem is, if I have POS and GPOS, I realized I couldn't use LIKE '%[input product name here]%'as this would return results that contains both POS and GPOS if I selected POS.
How can I fix this query to not display GPOS if I selected POS?
PS. I am aware of the issues with MySQL. It's what the company I'm in uses so I have no choice at the moment.
You can use REGEXP:
a.software_hardware REGEXP '[[:<:]]" . $arr[$i] . "[[:>:]]'
the [[:<:]] and [[:>:]] markers stand for word boundaries. So POS cannot match GPOS as there would be no word boundary at the beginning.
Note you will need to trim($arr[$i]) if it has leading or trailing whitespace.
Try this:
SELECT a.id, a.ticket_number, a.client, a.software_hardware,
a.issues_concern, a.status, a.technical_programmer, a.date_added
FROM activities a
WHERE a.client = '".$_POST['client']."'
AND UPPER(a.software_hardware) LIKE '%".strtoupper($arr[$i])."%'
ORDER BY a.date_added DESC
Related
I have a database of comics with a table of comics, credits, and contributor details. I am trying to filter my table using this SQL query:
The select parameters have * to show all but don't seem to show here
SELECT
cc.*,
ct.*,
cpub.*,
c.*,
cs.*
FROM
comic_types AS ct,
comics_publisher AS cpub,
comics AS c,
comics_series AS cs,
comic_credits AS cc
WHERE
c.comic_indexkey = cc.comic_index_key
AND cpub.publisher_index_key = c.comic_publisher
AND c.comic_series = cs.comics_seriesindexkey
AND ct.comic_typeindexkey = c.comic_type
AND cpub.publisher_index_key = c.comic_publisher
ORDER BY
comic_title ASC,
comic_series ASC
LIMIT 0, 15
The Limit values are placed there for pagination.
Some comics have the same contributor with a different role (e.g. comic A has person B as author and illustrator). This means I have two results that are the same comic. I have used an array and continue statement to make the duplicate record not show.
$comics_in_table = array();
if (in_array($comic['comic_indexkey'], $comics_in_table)) {
continue;
}
The problem this has created is the pagination only shows 5 per page rather than 15, presumably because it detects that 10 of the results have been 'hidden'
Following the kind help so far, created this:
SELECT
cc.*,
ct.*,
cpub.*,
c.*,
cs.*
FROM
comic_types AS ct,
comics_publisher AS cpub,
comics AS c,
comics_series AS cs,
comic_credits AS cc
WHERE
c.comic_indexkey = cc.comic_index_key
AND cpub.publisher_index_key = c.comic_publisher
AND c.comic_series = cs.comics_seriesindexkey
AND ct.comic_typeindexkey = c.comic_type
AND cpub.publisher_index_key = c.comic_publisher
GROUP BY
cc.comic_index_key
ORDER BY
c.comic_title ASC,
c.comic_series ASC
LIMIT 0, 15
And SQL returns this issue:
#1055 - Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'sewters.cc.credit_index_key' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
Try either to use
SELECT DISTINCT cc.*, ct.* ...
or append a
GROUP BY fieldname
at the end of your SELECT query, where fieldname is the database column that you want grouped into one entry.
I am trying to get a result where a single column id is like a comma separated columns, my two table are as follows:
Room Location Table
Events Table
User Table
My query is
$sql=" SELECT users.*, events.*, room_location.*
FROM events
INNER JOIN room_location ON events.event_room = room_location.location
INNER JOIN users ON room_location.user_loc_id = users.userlocationaccess
WHERE room_location.user_loc_id LIKE '%1,2%'";
$result = $conn->query($sql);
The query above works if I use single id in in the users->userGroupLocID.
How do I amend my query to work so it find if the id is like my comma separated columns?
You can search a CSV field using FIND_IN_SET(str,strlist) function.
Example:
mysql> SELECT FIND_IN_SET('b','a,b,c,d');
-> 2
Documentation Says:
Returns a value in the range of 1 to N if the string str is in the
string list strlist consisting of N substrings. A string list is a
string composed of substrings separated by “,” characters.
You can pass users location id to find in the column userGroupLocID
select find_in_set( location_id_in_search, replace( userGroupLocID, ' ', '' ) )
from table_name;
I have a problem with data in MySQL.
I have a column "vacation_period" where I keep data with dates separated by commas eg. "02/10/2015,02/11/2015" and I want to explode commas, month and year. I want to make condition where I can compare month and year sent by POST with exploded data from MySQL field.
Example query:
SELECT *
FROM ag_vacations INNER JOIN
ag_employees
ON ag_vacations.user_id = ag_employees.e_id
where ag_vacations.user_id = 1 AND
ag_vacations.vacation_period = 2015 AND
ag_vacations.vacation_period = 02
order by date_added desc
So try this way:
SELECT *
FROM ag_vacations INNER JOIN
ag_employees
ON ag_vacations.user_id = ag_employees.e_id
where ag_vacations.user_id = 1 AND
((ag_vacations.vacation_period REGEXP '[0-9]{2}\/[0-9]{2}\/2015\,[0-9]{2}\/[0-9]{2}\/[0-9]{4}' AND
ag_vacations.vacation_period REGEXP '02\/[0-9]{2}\/[0-9]{4}\,[0-9]{2}\/[0-9]{2}\/[0-9]{4}')
OR (ag_vacations.vacation_period REGEXP '[0-9]{2}\/[0-9]{2}\/[0-9]{4}\,[0-9]{2}\/[0-9]{2}\/2015' AND
ag_vacations.vacation_period REGEXP '[0-9]{2}\/[0-9]{2}\/[0-9]{4}\,02\/[0-9]{2}\/[0-9]{4}'))
order by date_added desc
so if you need to check just first date in that string 02/10/2015,02/11/2015 - you could delete OR part:
OR (ag_vacations.vacation_period REGEXP '[0-9]{2}\/[0-9]{2}\/[0-9]{4}\,[0-9]{2}\/[0-9]{2}\/2015' AND
ag_vacations.vacation_period REGEXP '[0-9]{2}\/[0-9]{2}\/[0-9]{4}\,02\/[0-9]{2}\/[0-9]{4}')
While a string of dates is not ideal, we sometimes receive data this way. If you need to query this before you have the opportunity to clean up your schema, and if your date formats are consistent, you can query the string with like. In this query, we will concat commas to the beginning and end of the ag_vacations.vacation_period column to make sure we are getting the beginning of the date for month and the end of the date for year:
SELECT *
FROM ag_vacations INNER JOIN
ag_employees
ON ag_vacations.user_id = ag_employees.e_id
where ag_vacations.user_id = 1 AND
concat(ag_vacations.vacation_period,',') like '%/2015,%' AND
concat(',',ag_vacations.vacation_period like '%,02/%'
order by date_added desc
If you just want to find the row, you don't need to explode in php.You can use FIND_IN_SET
http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_find-in-set
I have a table with two fields candidate_id and keyword_id. I needs to list all the candidates/candidate_id having keyword_id 5 and 6. Somebody please help me to write a single mysql query for this please.
An option that is simple to adapt to more than just two keyword_id's would be...
SELECT
candidate_id
FROM
yourTable
WHERE
keyword_id IN (1,2)
GROUP BY
candidate_id
HAVING
COUNT(DISTINCT keyword_id) = 2
An alternative could be...
SELECT
k1.candidate_id
FROM
yourTable AS k1
INNER JOIN
yourTable AS k2
ON k1.candidate_id = k2.candidate_id
WHERE
k1.keyword_id = 1
AND k2.keyword_id = 2
It should be noted, however, that neither of these options scales very well (as you increase the number of candidates, keywords, and number of keywords that you search for.
How to deal with this poor scaling totally depends on your data, and your needs. It's too broad and subjective a topic to discuss in a SO answer.
It's quite unclear what you exactly want, but this query gives you all candidates which have at least one match with a given keyword (using LIKE searches for matches within a keyword. If a keyword 'php' is given and the keyword in your database is 'php programmer', this match will show up). Something like this should do the trick, if this is what you're after.
$sQueryExtension = '';
foreach($keywords as $keyword) {
$sQueryExtension .= " OR `keyword` LIKE '%$keyword%'";
}
$sQueryExtension = substr($sQueryExtension, 3); // skip first OR
$sQuery = "
SELECT candidate.*
FROM candidate, match_table
WHERE candidate.id = match_table.candidate_id
AND match_table.keyword_id IN (
SELECT * FROM keyword WHERE $sQueryExtension
);";
Do you need records having
1. Either 5 or 6 OR
2. Do you need candidates having both 5 and 6?
For case 1,
SELECT candidate_id
FROM <table>
WHERE keyword_id in (5,6);
For case 2,
SELECT candidate_id
FROM (SELECT candidate_id, count(distinct keyword_id)
FROM <table>
WHERE keyword_id in (5, 6)
GROUP BY candidate_id
HAVING COUNT(DISTINCT keyword_id) > 1);
i have two tables in my database one is A other one is B
A is having few fields in which three are id,name,group
B is having feilds like id,title,description, etc.
i have to search the id's of title and description that are having data similar to table A's name or group and then have to insert the id's in a field of table A.
For example,
if A is having 'Anna' in its name and 'girl' in its group then i have to search the title's and descriptions in table B that are containing this word 'Anna' or 'girl'.
I want to do this in one single query.
How can i do so?
Edit:
Iam explainng my tables here for a better understanding
table A
id name group matched_id
1 anna girl
2 sydney girl
3 max boy etc.
Table B
id title description
1 A good girl Anna is a very good girl
2 Max doesnt work hard Boys are always like that only
etc...
see i will first search for a match for 'anna' in the table B's title and description and if a match is found in either of them then i'll store that id in table A only in the field 'matched id'
I'll do the same procedure for 'girl' and then for 'sydney' and so on
This query should do the trick:
UPDATE a SET matched_id =
(SELECT b.id FROM b
WHERE b.title LIKE CONCAT(' % ',a.name,' % ')
OR b.description LIKE CONCAT('% ',a.name,' %')
OR b.title LIKE CONCAT('%',a.group,'%')
OR b.description LIKE CONCAT('%',a.group,'%')
LIMIT 1)
WHERE EXISTS
(SELECT a.id FROM b
WHERE b.title LIKE CONCAT('% ',a.name,' %')
OR b.description LIKE CONCAT('% ',a.name,' %')
OR b.title LIKE CONCAT('%',a.group,'%')
OR b.description LIKE CONCAT('%',a.group,'%')
LIMIT 1)
Some remarks to this:
LIMIT 1 was necessary, as each subquery can and will return more than 1 row
Not 100% sure if the order you want/need is used, you may need some further testing for that and use order by if needed
it may also be better to use an extra table for the groups (to reduce duplicate entries) and maybe one extra mapping table, so that you can map all results from B to A
EDIT:
if names need to match perfectly (unlike girl/girls), you can just add a space in front of the name: '% ',a.name,' %'. If it gets more complicated I would suggest using regular expressions (REGEX). I modified the query with the spaces (for names only), so feel free to try it again.
SELECT *
FROM A
JOIN B
ON b.title IN (a.name, a.group)
OR b.description IN (a.name, a.group)
WHERE a.name = 'Anna'
AND a.group = 'girl'
Since INDEX_UNION's are not very efficient in MySQL, it may be better to split the queries (especially if your tables are InnoDB):
SELECT *
FROM (
SELECT b.id
FROM A
JOIN B
ON b.title IN (a.name, a.group)
WHERE a.name = 'Anna'
AND a.group = 'girl'
UNION
SELECT b.id
FROM A
JOIN B
ON b.description IN (a.name, a.group)
WHERE a.name = 'Anna'
AND a.group = 'girl'
) bo
JOIN B
ON b.id = bo.id