Mysql query help - count rows - php

I have two different tables trackingevent and link
Trackingevent looks like
eventName|eventStamp
SHARE_FACEBOOK|2011-01-20 14:05:40
SHARE_TWEET|2011-01-20 14:47:57
SHARE_FLICKR|2011-01-20 15:08:58
SHARE_STATION_LOGIN|2011-01-20 15:09:09
EMAIL_SHARE|2011-01-20 15:10:13
CONTEST_ENTRY:BLAH DATA|2011-01-20 15:10:13
CONTEST_ENTRY:BLAH DATA|2011-01-20 15:10:13
and link looks like
id|emailSub
6|1
7|0
8|1
9|0
And what I need to do is I need to count all the SHARE_FACEBOOK
and all the SHARE_TWEET
and all the SHARE_FLICKR
and all the SHARE_STATION_LOGIN
and all the COPNTEST_ENTRIES (Without the rest of the data after the :)
AND EMAIL_SHARE
and somehow combine those with the amount of emailSub (equals to 1)
and amount of id.
So I get a returned array sort of like
EMAIL_SHARE 77
SHARE_FLICKR 9
SHARE_FACEBOOK 105
SHARE_STATION_LOGIN 223
SHARE_TWEET 18
# of ID's
# of emailsub=1
CONTEST_ENTERIES 550
I can get the first part of it using
SELECT eventName, COUNT(*) FROM trackingevent GROUP BY eventName
But I am confused with how to get the # of ID's in the link the # of emailsubs=1 and the number of CONTEST_ENTRY:BLAH DATA (the blah data changes).
Would I have to do three different sql queries and combine the data? Or could I somehow combine them into a single one or?

This should give you the count of each type using the prefix
SELECT LEFT(eventName,INSTR(CONCAT(eventName,':'),':')) as prefix, count(*)
FROM trackingevent
GROUP BY LEFT(eventName,INSTR(CONCAT(eventName,':'),':'))
You'll have to answer the questions in the comments if this isn't what you were asking for

Related

Find JSON nth value using mysql query

I have this JSON values in MySQL database
Conditions
1- >
[{"offer_id":"158","offer_start":"2017-12-17 09:21:27","offer_ends":"2017-12-17 10:21:27"},{"offer_id":"167","offer_start":"2017-12-17 12:28:57","offer_ends":"2017-12-17 12:58:57"}]
2 ->
[{"offer_id":"170","offer_start":"2018-01-17 04:26:26","offer_ends":"2018-01-17 05:11:26"},{"offer_id":"167"}]
3 ->
[{"offer_id":"170","offer_start":"2017-12-11 20:49:12","offer_ends":"2017-12-11 20:49:12"}]
3 ->
[{"offer_id":"170"}]
So I need to get the nth offer_ends value like "2017-12-11 20:49:12" using mysql query
Considering that you need to find the data from table1 where the column name offers. You need to fetch data where the "offer_ends" has value 2017-12-11 20:49:12
SELECT JSON_CONTAINS(offers, '2017-12-11 20:49:12', '$.offer_ends')
FROM table1;
Get all the records:
SELECT offers, JSON_EXTRACT(offers, "$.offer_ends")
FROM table1
If you want then you can apply the order by on any column and then get the Top 1 record to get the last record.
Here i have one code which get all the offer_ends value by using MySQL -> SELECT REPLACE(REPLACE(JSON_EXTRACT('[{"offer_id":"23","offer_start":"2017-12-11 20:49:12","offer_ends":"2017-12-11 20:49:12"},{"offer_id":"23","offer_start":"2017-12-11 20:49:12","offer_ends":"2017-12-11 20:49:12"}]', '$[*].offer_ends'),'[',''),']','') as offer_dates
and the result is -> "2017-12-11 20:49:12", "2017-12-11 20:49:12" which shows all offer end dates
So i need to find the nth offer_ends value like this -> "2017-12-11 20:49:12"
Guys i found the solution
SELECT JSON_EXTRACT('[{"offer_id":"158","offer_start":"2018-02-21 13:03:15","offer_ends":"2018-02-21 14:03:15"},{"offer_id":"170","offer_start":"2018-02-21 15:03:15","offer_ends":"2018-02-21 16:03:15"}]',CONCAT("$[",JSON_LENGTH('[{"offer_id":"158","offer_start":"2018-02-21 13:03:15","offer_ends":"2018-02-21 14:03:15"},{"offer_id":"170","offer_start":"2018-02-21 15:03:15","offer_ends":"2018-02-21 16:03:15"}]')-1,"].offer_ends")) as offer
Thank you guys

Comparing 2 sets of words in MYSQL

I am creating a query where in i would need to compare 2 sets of words. I need to compare a.error_description with b.KE_TAGS which both contain sets of words.
Example of text:
a.error_description = "LockResource engine call failed in script GLB_LOCK..."
b.KE_TAGS = "LockResource, GLB_LOCKRESOURCE_100_PS"
Both columns contain the word "LockResource".
Here is my Query below:
The expected result should show the KE_ID based on the KE_TAG "LockResource, GLB_LOCKRESOURCE_100_PS" for the error_description which contains "LockResource engine call failed in script GLB_LOCK..."
Select a.error_id, a.job_ID, a.error, a.error_description,
CONCAT('%',b.KE_TAGS,'%'), b.KE_TAGS, b.KE_ID
from errors_input as a right join knowledge_entry as b
on a.error_Description like CONCAT('%',b.KE_TAGS,'%') -- issue is in this line
WHERE a.error like '%BB_RAISEERROR_100_PS%'***
Hope you can help. thanks!

SQL Query for closest match at the beginning of a string

Am currently using Mysql and PHP.
Looking for a query that will take a number and find the closet match for the begining of a set of digits, for example I have the number 019235678910, 026725678910, 026825678910 and my table looks like this.
Table - Destintation
Name Number
Watford 01923
Oxford 026
Romford 026
Crawford 0267
Topford 02672
So when I pass 019235678910 the result would be Watford, 026725678910 would be Topford and 026825678910 would be Oxford and Romford.
I'm also not sure if MYSQL can do this directly or would need to work in conjunction with PHP?
Here one way for getting all of them:
select d.*
from Destination d join
(select length(Number) as maxlen, number
from destination d
where YOURVALUE like concat(Number, '%')
order by maxlen desc
limit 1
) dsum
on d.Number = dsum.Number
Because you are looking for initial sequences, there is only one maximum match on the numbers (hence the limit 1 works).
By the way, the field called number is clearly a character field. Personally, I think it bad practice to call a character field "number" -- something called cognitive dissonance.
SELECT Name, Number
FROM Destintation
WHERE LEFT('026725678910', LENGTH(Number)) = Number
or perhaps
WHERE '026725678910' LIKE CONCAT(Number, '%')

MySQL COUNT showing it's working out

I would expect the following to output the number "5", since there are 5 rows in the database with with item 68 and user 1. But instead I'm getting this output "12345".
$resultb4 = mysql_query("SELECT COUNT(comparedRating) FROM recComparedRating WHERE user1='1' AND itemID='68' GROUP BY itemID AND user1");
while($rowb4 = mysql_fetch_array($resultb4)){
$countcomparedratings=$rowb4['COUNT(comparedRating)'];
}
echo $countcomparedratings;
What am I doing wrong?
The reason you are getting 12345 is because your query is returning 5 results and your code to output the count is simply outputting the concatenation of the returned array from the query.
Without understanding your database structure, I'm guessing that the reason you're getting the '12345' has something to do with your GROUP BY clause. Use a program like MySQLWOrkbench to connect to your database and test out your query before you include it into your code. It is a time saving technique to debug your queries.
Also, I would alias the COUNT value so that you simply refer to the alias when you refer to your column names.
SELECT COUNT(comparedRating) as ratingCount FROM recComparedRating WHERE user1='1' AND itemID='68' GROUP BY itemID AND user1");

PHP mysql search queries

I'm trying to create a search engine for an inventory based site. The issue is that I have information inside bbtags (like in [b]test[/b] sentence, the test should be valued at 3, whereas sentence should be valued at 1).
Here is an example of an index:
My test sentence, my my (has a SKU of TST-DFS)
The Database:
|Product| word |relevancy|
| 1 | my | 3 |
| 1 | test | 1 |
| 1 |sentence| 1 |
| 1 | TST-DFS| 10 |
But how would I match TST-DFS if the user typed in TST DFS? I would like that SKU to have a relevancy of say 8, instead of the full 10..
I have heard that the FULL TEXT search feature in MySQL would help, but I can't seem to find a good way to do it. I would like to avoid things like UNIONS, and to keep the query as optimized as possible.
Any help with coming up with a good system for this would be great.
Thanks,
Max
But how would I match TST-DFS if the user typed in TST DFS?
I would like that SKU to have a relevancy of say 8, instead of the full 10..
If I got the question right, the answer is actually easy.
Well, if you forge your query a little before sending it to mysql.
Ok, let's say we have $query and it contains TST-DFS.
Are we gonna focus on word spans?
I suppose we should, as most search engines do, so:
$ok=preg_match_all('#\w+#',$query,$m);
Now if that pattern matched... $m[0] contains the list of words in $query.
This can be fine-tuned to your SKU, but matching against full words in a AND fashion is pretty much what the user presumes is happening. (as it happens over google and yahoo)
Then we need to cook a $expr expression that will be injected into our final query.
if(!$ok) { // the search string is non-alphanumeric
$expr="false";
} else { // the search contains words that are no in $m[0]
$expr='';
foreach($m[0] as $word) {
if($expr)
$expr.=" AND "; // put an AND inbetween "LIKE" subexpressions
$s_word=addslashes($word); // I put a s_ to remind me the variable
// is safe to include in a SQL statement, that's me
$expr.="word LIKE '%$s_word%'";
}
}
Now $expr should look like "words LIKE '%TST%' AND words LIKE '%DFS%'"
With that value, we can build the final query:
$s_expr="($expr)";
$s_query=addslashes($query);
$s_fullquery=
"SELECT (Product,word,if((word LIKE '$s_query'),relevancy,relevancy-2) as relevancy) ".
"FROM some_index ".
"WHERE word LIKE '$s_query' OR $s_expr";
Which shall read, for "TST-DFS":
SELECT (Product,word,if((word LIKE 'TST-DFS'),relevancy,relevancy-2) as relevancy)
FROM some_index
WHERE word LIKE 'TST-DFS' OR (word LIKE '%TST%' AND word LIKE '%DFS%')
As you can see, in the first SELECT line, if the match is partial, mysql will return relevancy-2
In the third one, the WHERE clause, if the full match fails, $s_expr, the partial match query we cooked in advance, is tried instead.
I like to lower case everything and strip out special characters (like in a phone number or credit card I take everything out on both sides that isn't a number)
Rather than try to create your own FTS solution, you could try to fit the MySQL FTS engine to your requirements. What I've seen done is create a new table to store your FTS data. Create a column for each different piece of data that you want to have a different relevance. For your sku field you could store the raw sku, with spaces, underscores, hyphens and any other special character intact. Then store a stripped down version with all these things removed. You may also want to store a version with leading zeros removed, as people often leave things like that out. You can store all these variations in the same column. Store your product name in another column, and the product description in another column. Create a separate index on each column. Then when you do your search, you can search each column individually, and multiply the rank of the results based on how important you think that column is. So you could multiply sku results by 10, title by 5 and leave description results as is. You may have to do a little experimentation to get the results you want, but it may ultimately be simpler than creating your own index.
Create a keywords table. Something along the lines of:
integer keywordId (autoincrement) | varchar keyword | int pointValue
Assign all possible keywords, skus, etc, into this table. Create another table, a post-keywords bridge, (assuming postId is the id you've assigned in your original table) along the lines of:
integer keywordId | integer postId
Once you have this, you can easily add keywords to each post as it is interested. To calculate total point value for a given post, a query such as the following should do the trick:
SELECT sum(pointValue) FROM keywordPostsBridge kpb
JOIN keywords k ON k.keywordId = kpb.keywordId
WHERE kpb.postId = YOUR_INTENDED_POST
I think the solution is quite straightforward unless I missed something.
Basically run two search, one is exact match, the other is like match or regex match.
Join two resultsets together, like match left join exact match. Then for example:
final_relevancy = (IFNULL(like_relevancy, 0) + IFNULL(exact_relevancy, 0) * 3) / 4
I didn't try this myself though. Just an idea.
I would add a column that is stripped of all special character's, misspellings, and then upcased (or create a function that compares on text that has been stripped and upcased). That way your relevancy will be consistent.
/*
q and q1 - you table
this query takes too much resources,
make from it update-query ( scheduled task or call it on_save if you develop new system )
*/
SELECT
CASE
WHEN word NOT REGEXP "^[a-zA-Z]+$"
/*many replace with junk characters
or create custom function
or if you have full db access install his https://launchpad.net/mysql-udf-regexp
*/
THEN REPLACE(REPLACE( word, '-', ' ' ), '#', ' ')
ELSE word
END word ,
CASE
WHEN word NOT REGEXP "^[a-zA-Z]+$"
THEN 8
ELSE relevancy
END relevancy
FROM ( SELECT 'my' word,
3 relevancy
UNION
SELECT 'test' word,
1 relevancy
UNION
SELECT 'sentence' word,
1 relevancy
UNION
SELECT 'TST-DFS' word,
10 relevancy
)
q
UNION
SELECT *
FROM ( SELECT 'my' word,
3 relevancy
UNION
SELECT 'test' word,
1 relevancy
UNION
SELECT 'sentence' word,
1 relevancy
UNION
SELECT 'TST-DFS' word,
10 relevancy
)
q1
it is a page coading where query result shows
**i can not use functions by use them work are more easier**
<html>
<head>
</head>
<body>
<?php
//author S_A_KHAN
//date 10/02/2013
$dbcoonect=mysql_connect("127.0.0.1","root");
if (!$dbcoonect)
{
die ('unable to connect'.mysqli_error());
}
else
{
echo "connection successfully <br>";
}
$data_base=mysql_select_db("connect",$dbcoonect);
if ($data_base==FALSE){
die ('unable to connect'.mysqli_error($dbcoonect));
}
else
{
echo "connection successfully done<br>";
***$SQLString = "select * from user where id= " . $_GET["search"] . "";
$QueryResult=mysql_query($SQLString,$dbcoonect);***
echo "<table width='100%' border='1'>\n";
echo "<tr><th bgcolor=gray>Id</th><th bgcolor=gray>Name</th></tr>\n";
while (($Row = mysql_fetch_row($QueryResult)) !== FALSE) {
echo "<tr><td bgcolor=tan>{$Row[0]}</td>";
echo "<td bgcolor=tan>{$Row[1]}</td></tr>";
}
}
?>
</body>
</html>

Categories