I got table of links between goods and filters, like this:
id, good_id, filter_id.
When user notes checkboxes i have to show him all goods, that got link with all of those filters.
My vision of the query is:
(if user checked filters: 1,2 and 3)
SELECT DISTINCT(t0.gid)
FROM links as t0, links as t1, links as t2
WHERE t0.filter_id=1 AND
t1.good_id=t0.good_id AND t1.filter_id=2 AND
t2.good_id=t1.good_id AND t2.filter_id=3
But in this way, we'll got a trouble, if there are a lot of checked filters..
So, how would you solve the task?
If you need GID's which have at least one of filters
SELECT DISTINCT `gid` FROM `links` WHERE `filter_id` IN (1,2,3)
If you need GID's which have ALL filters 1,2,3
SELECT `gid` FROM `links` WHERE `filter_id` IN (1,2,3)
GROUP BY `gid` HAVING COUNT( DISTINCT `filter_id`)=3
where COUNT( DISTINCTfilter_id)=3 means that all 3 filters are on.
SELECT gid
FROM links
WHERE filter_id IN (1, 2, 3)
GROUP BY
gid
HAVING COUNT(DISTINCT filter_id) = 3
Related
I have a table T. We have multiple records for a particular user_id with match type = "Red Card". I just wanted that user_Id and match_id which has never received a "Red Card" in a entire match.
As per the table Image which is attached I would be getting output :
match_id : 3036 and 3090 and user_id 4 and 6 respectively
If you want to select all fields Use subquery
SELECT DISTINCT user_id, match_id from tbl where match_id NOT IN (
SELECT match_id from tbl where type = 'Red Card'
)
I'd do something like this:
SELECT * FROM T WHERE type <>'Red Card' GROUP BY match_id, user_id
This will select all records from the table where there is not "Red Card" and the group by will give you just one record from each couple match/user
SELECT * FROM `T` where not exists (SELECT * FROM `T` where `type`="Red card")
SELECT MATCH_ID AND USER_ID FROM TABLENAME WHERE TYPE NOT IN('RED CARD')
This Query may help you
Hope this will help.
SELECT DISTINCT user_id, match_id FROM T WHERE type <> 'Red Card' GROUP BY match_id
Because there are duplicate user_id and match_id-s in the table, I've used DISTINCT to select unique ids from the table.
Select match_id,user_id from T where user_id Not IN (Select user_id from T where type = 'Red Card') as k Group By user_id
The above query will remove all the users having red cards by first selecting user_id from T who have red cards in the nested query and then selecting users who are not in the nested statement using "NOT IN" and then grouping by user_id to remove duplicate records.
The three statement (a little contrived for simplicity) are:
SELECT `user_id` WHERE `movie_id` = 1
SELECT `user_id` WHERE `movie_id` = 2
SELECT `user_id` WHERE `movie_id` = 3
What I would like to do is twofold:
Join the three of the above into a single table of ID's that match all three of the movie_id
Make all of this one query to reduce MySQL reads to speed up performance
I am sure there is a simple way to do it, but I am not the strongest SQL user, so thanks for all of the help!
Select count(distinct movie_ID), user_ID
from table where move_Id in (1,2,3)
group by user_ID
Having count(distinct Movie_ID) = 3
What this does is obtain a distinct count of movies per user_ID. it then limits the results to only those users having a count of 3.
The simplest way to me seems:
SELECT user_id FROM table_name WHERE movie_id IN (1,2,3);
Alternatively you could use the UNION method suggested by xQbert, but I would run an EXPLAIN query to see what SQL statement provided the most efficient result.
I currently use the following query which works perfectly:
SELECT * FROM `items` WHERE `id` IN
(SELECT `item_id` FROM `categories_items`
WHERE `category_id` IN (1, 2) GROUP BY `item_id`
HAVING COUNT(`item_id`) = 2);
It selects all the items that are in all the selected (checkboxes) categories.
The problem is that most items are in many categories and a few items are only in two categories and when I only check those two, I still get a list of hundreds of items, making it nearly impossible to find the items that are in few categories.
My first idea was to add an ORDER BY "number_of_total_categories_that_the_selected_item_is_in" ASC somewhere in the query, but since I even got help with the current one and there would probably be a lot of calculations/subqueries for it to work, I thought of an extra column in the items table that would hold the number of categories it's in!
Is it possible to add an effective ORDER BY clause to the query and if so, what would it look like?
Do you have any other ideas? Would "an inverted" foreign key solution work here? Not a chance, right? :p
If not, all I can think of is to manually update a category_count column in items whenever it's needed.
Edit: Table field that holds row count from another table looks interesting, but I have no idea whether it would work in MySQL.
You want to use join rather than in. The following query filters for items that only have the two categories you want. It also counts the total number of categories, which can be used for the order by:
SELECT i.*
FROM `items` i JOIN
(SELECT `item_id`, COUNT(*) as cnt
FROM `categories_items`
WHERE `category_id` IN (1, 2)
GROUP BY `item_id`
HAVING COUNT(DISTINCT CASE WHEN category_id IN (1, 2) THEN category_id END) = 2
) c
ON i.id = c.item_id
ORDER BY cnt ASC;
EDIT:
If you want to count all the categories, then get rid of the where. It is not really doing anything:
SELECT i.*
FROM `items` i JOIN
(SELECT `item_id`, COUNT(*) as cnt
FROM `categories_items`
GROUP BY `item_id`
HAVING COUNT(DISTINCT CASE WHEN category_id IN (1, 2) THEN category_id END) = 2
) c
ON i.id = c.item_id
ORDER BY cnt ASC;
I have a query like this, to select the most recent time someone was contacted:
SELECT `user_id`, `last_contact`
FROM `emails_sent`
group by `user_id`
order by `last_contact` desc
The above code gives a table with the last contact time for each user. Now, I have another table with contacts to users, a table with columns user_id and last_contact, among others.
How can I make my select use both tables and select the last contact time for each user from the two tables?
Summarize the union of two summary queries, something like this.
SELECT user_id,
MAX(user_date) user_date
FROM
(
SELECT user_id,
MAX(last_contact) user_date
FROM emails_sent
GROUP BY user_id
UNION ALL
SELECT whatever_user_id_column user_id,
MAX(whatever_date_column) user_date
FROM whatever_table
GROUP BY user_id
)a
GROUP BY user_id
I got a mysterious behaviour using DISTINCT on a MySQL table and can't figure it out:
SELECT DISTINCT `deal_hash`,`city_name`
FROM `a`
WHERE `city_name` = 'b'
...will show me the desired output with DISTINCT on deal_hash. I can also add any other column to the select and it will work only in two cases DISTINCT will fail
SELECT DISTINCT `deal_hash`,`deal_link`
FROM `a`
WHERE `city_name` = 'b'
AND
SELECT DISTINCT `deal_hash`,`loaded_at`
FROM `a`
WHERE `city_name` = 'b'
deal_link is a varchar(255) and loaded_at a INT(20).
DISTINCT shows distinct rows (of column values).
PostgreSQL is the only DB I know of that supports DISTINCT ON, applied to a particular column.
select distinct selects distinct rows. It is not specific to the following column.
Try using group by instead:
select deal_hash, min(deal_link)
from a
where city_name = 'b'
group by deal_hash
or
select deal_hash, max(loaded_at)
from a
where city_name = 'b'
group by deal_hash