Mysql query with and conditions - mysql

I've two tables,
table 1
userid filter
thiru 1
thiru 2
thiru 3
raja 1
raja 2
table 2
headline filter1 filter2
test 1 3
test2 1 2
If I want to select the users applicable for filters.
when i select test - thiru is applicable ( filter1 and filter2 ) matching
when i select test2 - thiru and raja are applicable ( filter1 and filter2 ) matching.
Basically the filters are with and condition.
Here is the query that i tried:
select userid
from table1
where filter in (select filter1
from table2
where headline = 'test')
and filter in (select filter2
from table2
where headline = 'test');
Please give me the query for this.
Thanks in advance.

You can get the desired results for your both filters by using following approach
select a.userid
from table1 a
left join table2 b on a.filter = b.filter1
left join table2 b1 on a.filter = b1.filter2
group by a.userid
having sum(b.headline = 'test')
and sum(b1.headline = 'test')
demo(test) , demo(test2)

Essentially you're looking to join the two tables together on the filter in table1 being either = to filter1 or = filter2, and you only want usernames that appear twice in the joined list. This is what the group by does => afte rthe tables are joined together, it groups up the number of times the username appears. Then the HAVING COUNT(*) > 1 excludes all usernames that only appear once (i.e. only matched one of the filter1 or filter2)
SELECT
userid
FROM
table1 t1
INNER JOIN
table2 t2
ON
t1.filter=t2.filter1 OR
t1.filter=t2.filter2
WHERE
t2.headline = 'test'
GROUP BY
userid
HAVING COUNT(*) > 1
Your own query was actually almost working, but it has a fatal flaw:
You wrote WHERE filter in (something) AND filter in (somethingelse). A number 1 is never = to 1 AND 3 at the same time, so there is no one row whose filter can be 1 AND 3 simultaneously.. There are DIFFERENT rows that can match this, but for that your query would need to be:
select userid from table1
where
filter in (select filter1 from table2 where headline = 'test') OR
filter in (select filter2 from table2 where headline = 'test')
I only changed the AND to OR.. This would return two rows for THIRU and one row for RAJA, so we would still need to group it up and count them:
select userid from table1
where
filter in (select filter1 from table2 where headline = 'test') OR
filter in (select filter2 from table2 where headline = 'test')
GROUP BY username HAVING COUNT(*)>1
Soo.. you were close, you just need to think about things as row by row

You can use the below structure to get the result
select a.userid
from table1 a
join table2 b on (a.filter = b.filter1 or a.filter = b.filter2)
where b.headline = 'test'
group by a.userid

Found a solution and here is what worked:
SELECT userid FROM table1
WHERE (filter IN (SELECT filter1 FROM table2 WHERE headline = 'test')
OR filter IN (SELECT filter2 FROM table2 WHERE headline = 'test'));
Adding a 'OR' between two queries worked.

Related

MySQL: check if a column has values based on another column

I'm using PDO to handle my database and I have one table:
Table:
id sku category
1 XYZ Ballerinas
2 Ballerinas
3 Ballerinas
4 ABC Ballerinas
As you can see I have 4 rows that are in the same category Ballerinas, but two of them don't have an sku. How can I return those rows using a PDO query only if all Ballerinas have an sku?
Thank you! :D
One option to find matching categories is to aggregate by category and then assert the total count matches the count of sku values which are not empty string. If these two counts match, then retain that category.
SELECT t1.*
FROM yourTable t1
INNER JOIN
(
SELECT category
FROM yourTable
GROUP BY category
HAVING COUNT(*) = COUNT(CASE WHEN sku <> '' THEN 1 END)
) t2
ON t1.category = t2.category;
Demo
Or you can do it without a join:
SELECT *
FROM Table1 t1
WHERE NOT EXISTS (SELECT 1 FROM Table1 t2 WHERE t1.category = t2.category AND t2.sku IS NULL);
If you consider empty values ('') also as "not being a value" then the condition in the exists clause should be
where t2.category=t1.category and not t2.SKU>''

Use selected column in first query with IN clause in second query

Problem has been recreated below:
/* query - 1 */
Select id, title from table1;
/* returns */
id | title
-----------
1 | data-1
2 | data-2
3 | data-3
4 | data-4
5 | data-5
I want use this column id's data with IN clause in second query along with join.
Something like this:
Select id, title from table1
JOIN
Select anotherColumn from table2 where table2.id IN (1,2,3,4,5) on table1.id = table2.id
Instead of manually writing 1,2,3,4,5, how can I use the column data selected from first query in second query?
EDIT:
Actual query :
SELECT *
FROM
(
SELECT R.id, U.ic_id as rider, U.name, DP.department_name, R.location,
(R.distance - 1) + 10 as cost , R.timestamp, R.status
FROM requests AS R, iconnect.users AS U, iconnect.departments AS DP
WHERE R.pool = '125' AND R.rider = U.ic_id AND U.department = DP.id
) requestDetails
JOIN
(
SELECT AVG(rider_rating) AS rider_rating,rider
FROM
(
SELECT rider_rating, R.rider
FROM journeys AS J, requests AS R
WHERE J.req_id = R.id AND R.rider IN (12,13) LIMIT 999999
) AS allRatings
GROUP BY rider
) ratingsTable
ON requestDetails.rider = ratingsTable.rider
/* instead of (12,13) I want to use requestDetails.rider selected from the first derived table */
One option would be to use an EXISTS clause:
SELECT id, title
FROM table1 t1
WHERE EXISTS (SELECT 1 FROM table2 t2 WHERE t1.id = t2.id);
Actually, a plain inner join between the two tables would also work. But, you might want to use SELECT DISTINCT in case a given record in table1 could match more than one record in table2. That would leave us with this:
SELECT DISTINCT t1.id, t1.title
FROM table1 t1
INNER JOIN table2 t2
ON t1.id = t2.id;

need help on join query condtion

I am not much in db queries and I require some help on following .
I have two table structures as follow as
table1 :
Name Id1 Id2
Jack 1 1
Jack 1 1
Jack 1 1
table2 :
Name Id1 Id2
Jack 1 1
I used basic join query :
select *
from table1 tb1
join table2 tb2 on tb1.id1 = tb2.id1
and tb2.id2 = tb2.id2
output I get :
Jack 1 1
Jack 1 1
Jack 1 1
But I required following output:
Jack 1 1
Note: I like to show what records is available in table 2 when it combined together!!.. I would like to fetch data with respect table2 only
Thanks in advance.
Please try the following (does not uses aliases) ...
SELECT table2.Name,
table2.Id1,
table2.Id2
FROM table1
JOIN table2 ON table1.id1 = table2.id1 AND
table1.id2 = table2.id2
GROUP BY table2.id1,
table2.id2;
Or try the following (does use aliases)...
SELECT tb2.Name,
tb2.Id1,
tb2.Id2
FROM table1 tb1
JOIN table2 tb2 ON tb1.id1 = tb2.id1 AND
tb1.id2 = tb2.id2
GROUP BY tb2.id1,
tb2.id2;
By performing an INNER JOIN on table2 with table1 on those key fields you are limiting the output to only those rows from table1 that match Id1 and Id2 in table2 (Note : Where JOIN is not preceded by a JOIN type an INNER JOIN is performed). Since multiple rows in table1 meet this criteria you can limit your results to just one row for each matching set of criteria using GROUP BY
This should change the supplied actual query to...
SELECT delta.input_name,
delta.mtcn,
delta.at‌​tempt_id
FROM compliance.rtra_transactions rtra_txn
JOIN compliance.GNR_TEST_RUNS delta ON rtra_txn.mtcn_nr = delta.mtcn
AND rtra_txn.attemptid = delta.attempt_id
WHERE rtra_txn.year = 2017
AND rtra_txn.month = 2
AND rtra_txn.day = 17
AND rtra_txn.trns_ts BETWEEN '2017-02-17 00:00:00' AND '2017-02-17 23:59:00'
AND delta.MATCH_OUTCOME = 'MATCH'
AND delta.job_name = 'Feb17_Run_1'
AND rtra_txn.txn_map[ 'TRANSACTIONTYPE' ] IN ( '10', '7' )
GROUP BY delta.mtcn,
delta.attempt_id;
If you have any questions or comments, then please feel free to post a Comment accordingly.
Following query should work :
SELECT * FROM TBL2 T2
UNION
SELECT * FROM TBL1 T1;
You need to use LEFT JOIN as you mentioned in Biswabid answer comment I like to show what records is available in table 2 alone
select DISTINCT tb2.*
from table2 tb2
left join table1 tb1 on tb1.id1 = tb2.id1
and tb1.id2 = tb2.id2
WHERE tb1.id1 IS NULL

SELECT with a COUNT of another SELECT

I have a table in SQL that is a list of users checking in to a website. It looks much like this:
id | date | status
------------------
Status can be 0 for not checking in, 1 for checked in, 2 for covered, and 3 for absent.
I'm trying to build one single query that lists all rows with status = 0, but also has a COUNT on how many rows have status = 3 on each particular id.
Is this possible?
MySQL VERSION
just join a count that is joined by id.
SELECT t.*, COALESCE(t1.status_3_count, 0) as status_3_count
FROM yourtable t
LEFT JOIN
( SELECT id, SUM(status=3) as status_3_count
FROM yourtable
GROUP BY id
) t1 ON t1.id = t.id
WHERE t.status = 0
note: this is doing the boolean sum (aka count)..
the expression returns either true or false a 1 or a 0. so I sum those up to return the count of status = 3 for each id
SQL SERVER VERSION
SELECT id, SUM(CASE WHEN status = 3 THEN 1 ELSE 0 END) as status_3_count
FROM yourtable
GROUP BY id
or just use a WHERE status = 3 and a COUNT(id)
Try a dependent subquery:
SELECT t1.*,
( SELECT count(*)
FROM sometable t2
WHERE t2.id = t1.id
AND t2.status = 3
) As somecolumnname
FROM sometable t1
WHERE t1.status=0
You can use a join for this. Write one query that will get all rows with a status zero:
SELECT *
FROM myTable
WHERE status = 0;
Then, write a subquery to get counts for the status of 3 for each id, by grouping by id:
SELECT COUNT(*)
FROM myTable
WHERE status = 3
GROUP BY id;
Since you want all the rows from the first table (at least that's what I am picturing), you can use a LEFT JOIN with the second table like this:
SELECT m.id, m.status, IFNULL(t.numStatus3, 0)
FROM myTable m
LEFT JOIN (SELECT id, COUNT(*) AS numStatus3
FROM myTable
WHERE status = 3
GROUP BY id) t ON m.id = t.id
WHERE m.status = 0;
The above will only show the count for rows containing an id that has status 0. Hopefully this is what you are looking for. If it is not, please post some sample data and expected results and I will help you try to reach it. Here is an SQL Fiddle example.

Select distinct records in mysql

My table
ANONYMOUS
ONE TWO
1 2
2 1
1 2
3 1
Now i want to select distinct set of one and two.
My selected list should be
ANONYMOUS
ONE TWO
1 2
3 1
Your question isn't very clear, but I guess you mean this:
SELECT DISTINCT one, two
FROM yourtable AS T1
WHERE one <= two
OR NOT EXISTS
(
SELECT *
FROM yourtable AS T2
WHERE T1.one = T2.two
AND T1.two = T2.one
)
It finds rows with (one, two) where the reversed pair (two, one) does not exist. If both exist, it chooses the pair such that one < two. It also selects rows where the values are equal.
See it working online: sqlfiddle
If you would prefer to use a JOIN instead of NOT EXISTS you can do that:
SELECT DISTINCT T1.one, T1.two
FROM yourtable AS T1
LEFT JOIN yourtable AS T2
ON T1.one = T2.two
AND T1.two = T2.one
WHERE T1.one <= T1.two
OR T2.one IS NULL
See it working online: sqlfiddle
SELECT DISTINCT a.*
FROM `ANONYMOUS` a
LEFT JOIN `ANONYMOUS` b ON (a.one=b.two and a.two=b.one)
WHERE b.one is null or a.one<b.one
ORDER BY 1,2