Count Distinct itesm from mySQL query - mysql

Attempting to get distinct count value back of the number "threads" in a query
SELECT COUNT( ft.thread_id ) AS num_items
FROM filter_thread ft
INNER JOIN filter f ON ft.filter_id = f.filter_id
WHERE f.tag LIKE '%foo%'
OR f.tag LIKE '%bar%'
The above works, but due to the way the tables are set up, counts duplicates. I've tried adding DISTINCT in many places. but had no luck.
For more information...this information is required to correctly list page numbers and associated posts for an AJAX comment section

Try this
SELECT COUNT( ft.thread_id ) AS num_items
FROM filter_thread ft
INNER JOIN filter f ON ft.filter_id = f.filter_id
WHERE f.tag LIKE '%foo%'
OR f.tag LIKE '%bar%'
GROUP BY ft.thread_id

Related

MySQL COUNT() not returning total number it is counting each rows separately

I am having some problem with my MySQL query and I need some guidance here. I am creating a search and I want to know how many item was found in my search with my query. But the problem is, my query returning count for each rows separately, It's not returning total count. Here what I have right now.
My query
SELECT
COUNT(t.id) AS total
FROM
trouble t
LEFT JOIN district d ON d.id = t.district
LEFT JOIN country c ON c.id = t.country
LEFT JOIN multi_category mc ON mc.t_id = t.id
LEFT JOIN category ct ON ct.id = mc.ct_id
LEFT JOIN state s ON s.id = t.state
WHERE
t.name LIKE '%keyword%' OR
t.title LIKE '%keyword%' OR
t.tags LIKE '%keyword%' OR
ct.category LIKE '%keyword%' OR
c.country LIKE '%keyword%' OR
s.state LIKE '%keyword%' OR
d.district LIKE '%keyword%'
GROUP BY
t.id
I have 14 rows in my database with the keyword I am searching with and this query returning 14 rows, here is a snap.
But it is counting each rows id's individually. I don't want that. What I want is, I want the total row count which is 14 and I want it in a single row. Can you please help me achieve this?
Thanks in advance.
First get the unique number of IDs and then return the total number of IDs.
SELECT count(*) AS Total
FROM
(
SELECT DISTINCT t.id
FROM trouble t
LEFT JOIN district d ON d.id = t.district
LEFT JOIN country c ON c.id = t.country
LEFT JOIN multi_category mc ON mc.t_id = t.id
LEFT JOIN category ct ON ct.id = mc.ct_id
LEFT JOIN state s ON s.id = t.state
WHERE
t.name LIKE '%keyword%' OR
t.title LIKE '%keyword%' OR
t.tags LIKE '%keyword%' OR
ct.category LIKE '%keyword%' OR
c.country LIKE '%keyword%' OR
s.state LIKE '%keyword%' OR
d.district LIKE '%keyword%'
GROUP BY t.id
) resultTable
Use exists instead of LEFT JOINs. The joins just multiply rows when there are multiple matches:
SELECT COUNT(*)
FROM trouble t
WHERE t.name LIKE '%keyword%' OR
t.title LIKE '%keyword%' OR
t.tags LIKE '%keyword%' OR
EXISTS (SELECT 1
FROM district d
WHERE d.id = t.district AND d.district LIKE '%keyword%'
) OR
EXISTS (SELECT 1
FROM country c
WHERE c.id = t.country AND c.country LIKE '%keyword%'
) OR
EXISTS (SELECT 1
FROM state s
WHERE s.id = t.state AND s.state LIKE '%keyword%'
) OR
EXISTS (SELECT 1
FROM multi_category mc JOIN
category ct
ON ct.id = mc.ct_id
WHERE mc.t_id = t.id AND
(ct.category LIKE '%keyword%' OR
c.country LIKE '%keyword%'
)
);
By eliminating the creation of multiple rows, this should also be faster.

Match all keywords using like in group MySQL

I have a table of keywords (ID,ean,keyword) and another table with product details. I want the search to return EANs where all keywords match at least once, however the closest I have got is the following, but this returns matches that have the first term in them 3 times for example.
To give an example, let's say I have a product called 'Generic headphones - iPhone, iPad, iPod' and I searched 'gen%' 'hea%' 'ip%' it would come back as a match, but it would also match 'Apple headphones - iPhone, iPad, iPod' due to the 3 ip words, which is not desired.
SQL Fiddle
I want EAN 1 to match only, so matches need to be at least 1 for each term.
Any help would be much appreciated.
SELECT Count(keywords.ean) AS cc,
products.*
FROM keywords
INNER JOIN products
ON products.ean = keywords.ean
WHERE (
keyword LIKE 'gen%'
|| keyword like 'ip%'
|| keyword LIKE 'hea%')
GROUP BY (keywords.ean)
HAVING cc>=3
ORDER BY `products`.`ean` ASC
UPDATE: This gets the desired results, but there must be more efficient ways to do this.
SELECT products.*
FROM products
INNER JOIN (SELECT ean, count(*) as tc1
FROM keywords
WHERE ( keyword like 'gen%' )
GROUP BY ean
HAVING tc1 > 0 ) as t1 ON t1.ean = products.ean
INNER JOIN (SELECT ean, count(*) as tc2
FROM keywords
WHERE ( keyword like 'ip%' )
GROUP BY ean
HAVING tc2 > 0 ) as t2 ON t2.ean = products.ean
INNER JOIN (SELECT ean, count(*) as tc3
FROM keywords
WHERE ( keyword like 'hea%' )
GROUP BY ean
HAVING tc3 > 0 ) as t3 ON t3.ean = products.ean
ORDER BY products.ean
Perhaps you're after something more like this...
SELECT p.ean
, p.description
FROM products p
JOIN keywords k
ON k.ean = p.ean
WHERE k.keyword LIKE 'iP%'
OR k.keyword LIKE 'hea%'
OR k.keyword LIKE 'gen%'
GROUP
BY p.ean
HAVING COUNT(DISTINCT CASE WHEN k.keyword LIKE 'iP%' THEN 'iP'
WHEN k.keyword LIKE 'hea%' THEN 'hea'
WHEN k.keyword LIKE 'gen%' THEN 'gen'
ELSE keyword END) = 3;
http://sqlfiddle.com/#!9/270f9/25
This is how I'd do it in PostgreSQL. MySQL may have a slightly different syntax.
SELECT kc.cc AS cc,
products.*
FROM products
INNER JOIN ( SELECT ean, count(*) AS cc
FROM keywords
WHERE ( keyword like 'ip%'
OR keyword like 'ai%'
OR keyword like 'bei%' )
GROUP BY ean
HAVING count(*) >= 3 ) AS kc
ON kc.ean = products.ean
ORDER BY Products.ean;

Mysql subquery select all id

So, i need help doing a select inside a subquery, i know this is kinda basics but i can't manage to do it by myself yet.
(Reparacao=repairs and lojas=stores, from portuguese to english)
I want to get the number of repairs that each store has. However i can only do one store at a time, but i want a query that selects all the stores.
I'm using this query:
SELECT COUNT( DISTINCT id_reparacao ) , lojas.nome
FROM reparacoes
INNER JOIN lojas ON lojas.id = 1
WHERE id_loja = lojas.id
and i want something like:
SELECT COUNT( DISTINCT id_reparacao ) , lojas.nome
FROM reparacoes
INNER JOIN lojas ON lojas.id = (Select id from lojas) //i want the id of every store
WHERE id_loja = lojas.id
Try this:
There is no need to use sub query to fetch all repairs count by stores.
You can easily get the result using JOIN and GROUP BY.
SELECT COUNT(DISTINCT id_reparacao) repairCnt, lojas.nome
FROM reparacoes
INNER JOIN lojas ON lojas.id = id_loja
GROUP BY lojas.id
Why don't you try to join ON ids:
SELECT COUNT( DISTINCT r.id_reparacao ) , lojas.nome
FROM reparacoes r
INNER JOIN lojas l ON l.id = r.id_loja;

Sql Count on many to many

I have three tables
post
id | statement | date
features
id | feature
post_feature (many to many table between Post and Feature)
post_id | feature_id
I want to fire a query that will give me count of different distinct features and its respective features for the posts that are in given date period. I have just started learning SQL and I am not able to crack this one.
I tried the following one but not getting correct results.
SELECT f.feature, count(f.feature)
FROM post_feature l
JOIN features f ON (l.featureid = f.id AND l.featureid IN (
select post.id from post where post.date > 'some_date'))
GROUP BY f.feature
You can try like this:
SELECT f.feature, count(f.feature)
FROM post_feature l
JOIN features f ON l.featureid = f.id
JOIN post p ON l.post_id =p.id
WHERE p.date > 'some_date'
GROUP BY f.feature
select f.feature, count(*)
from post_feature l inner join features f on l.feature_id = f.id
inner join post p on l.post_id = p.id
where p.date > 'some_date'
group by f.feature
Your SQL is quite creative. However, your join in the IN clause is on the wrong columns. It should be on postid to postid.
Although that fixes the query, here is a better way to write it:
SELECT f.feature, count(f.feature)
FROM post p join
post_feature pf
on p.id = pf.postid join
feature f
on pf.featureid = f.id
where post.date > 'some_date'
GROUP BY f.feature
This joins all the tables, and then summarizes by the information you want to know.
Try
SELECT f.feature, count(DISTINCT f.feature)
FROM post_feature l
JOIN features f ON (l.featureid = f.id AND l.featureid IN (
select post.id from post where post.date > 'some_date'))
GROUP BY f.feature

mySQL inner join query - how do i combine these 2 queries?

This is my current query:
SELECT DISTINCT t.* FROM filter AS f
INNER JOIN filter_thread AS ft
ON ft.filter_id = f.filter_id
INNER JOIN thread AS t
ON ft.thread_id = t.thread_id
WHERE f.tag LIKE '%test%'
ORDER BY t.replystamp DESC
It returns a bunch of data including a "owner_id" column.
The 'user_table' contains a matching id, labeled, 'id'
I previously used this query to get the data:
SELECT username FROM users WHERE id='$user_id'"
I need these to occur in the same query! But adding an additional INNER JOIN is not working.
perhaps this:
SELECT DISTINCT t.*,u.username
FROM filter AS f
INNER JOIN filter_thread AS ft
ON ft.filter_id = f.filter_id
INNER JOIN thread AS t
ON ft.thread_id = t.thread_id
INNER JOIN users AS u
ON u.id = t.owner_id
WHERE f.tag LIKE '%test%'
ORDER BY t.replystamp DESC
Just a guess.
Try the following:
SELECT DISTINCT t.*, u.username FROM filter AS f
INNER JOIN filter_thread AS ft
ON ft.filter_id = f.filter_id
INNER JOIN thread AS t
ON ft.thread_id = t.thread_id
INNER JOIN users AS u
ON ft.owner_id = u.id
WHERE f.tag LIKE '%test%'
ORDER BY t.replystamp DESC