Select ID That has multiple attributes and values - mysql

i have table1 :
+----+-------+
| id | name |
+----+-------+
| 1 | name1 |
| 2 | name2 |
| 3 | name3 |
| 4 | name4 |
+----+-------+
i have table2 :
+------+---------+----------+
| id | attribut| value |
+------+---------+----------+
| 1 | 1 | 1 |
| 1 | 3 | 3 |
| 2 | 1 | 1 |
| 2 | 3 | 4 |
+------+---------+--------- +
i want to select the distinct id(s) and name(s) in table1 that have ( attribut 1 and value 1) and (attribut 3 and value 3) in table 2
the result will be 1/name1 in this case
thanks for help !!

select * from table1
where id in(select id
from table2
where (attribut, value) in ( (1,1), (3,3) )
group by id
having count(*)=2
)

Related

How to fetch one row inside a group in mysql according to a criteria in MySQL

I have a table like this with 8 rows
+----+------+------+--------+
| id | type | attr1 | attr2 |
+----+------+-------+-------+
| 1 | a | abcd | qwer |
| 2 | a | efgh | tyui |
| 2 | b | ijkl | opas |
| 3 | a | mnop | dfgh |
| 4 | a | qrst | jklz |
| 5 | a | uvwx | xcvb |
| 5 | b | yzab | nmqw |
| 6 | b | cdef | erty |
+----+------+-------+-------+
It is known than type can be either 'a' or 'b'.
I need to select the rows in such a way that if there are more than one rows with same id, then select the one with type 'a'. Else select the row with whatever type is present.
So my desired result should be like
+----+------+------+--------+
| id | type | attr1 | attr2 |
+----+------+-------+-------+
| 1 | a | abcd | qwer |
| 2 | a | efgh | tyui |
| 3 | a | mnop | dfgh |
| 4 | a | qrst | jklz |
| 5 | a | uvwx | xcvb |
| 6 | b | cdef | erty |
+----+------+-------+-------+
I have a MySQL query
SELECT t.id,
CASE
WHEN count(t.id) > 1 THEN 'a'
ELSE t.type
END `type`
FROM table1 t
GROUP BY t.id
ORDER BY t.type ASC
which gives this result
+----+------+
| id | type |
+----+------+
| 1 | a |
| 2 | a |
| 3 | a |
| 4 | a |
| 5 | a |
| 6 | b |
+----+------+
But I need the respective row with all columns.
How to do that?
Note that the MySQL version that I have is 5.7.12.
You don't mention if multiple a's with the same id are possible or what to do in that case. I'm going to assume you want all a rows included. To do that, you just need to exclude b rows when there is a corresponding a row:
select t.*
from table1 t
left join table1 t2 on t2.id=t.id and t.type='b' and t2.type='a'
where t2.id is null;
you also can do it using window function:
select * from
(
select * , row_number() over (partition by id order by case when type = 'a' then 0 else 1 end) rn
) t
where rn = 1;
Hmmm . . . I would be inclined to use not exists:
select t.*
from t
where t.type = 'a' or
not exists (select 1
from t t2
where t2.id = t.id and t2.type = 'a'
);

MySQL how to get first n groups?

For the follow table TestTable:
| Id | Name | Flags |
|----|-------|-------|
| 1 | name1 | 1 |
| 2 | name2 | 1 |
| 3 | name3 | 2 |
| 4 | name4 | 2 |
| 5 | name5 | 3 |
how to group by Flags and return the first 2 groups. That is to say I should return rows:
| 1 | name1 | 1 |
| 2 | name2 | 1 |
| 3 | name3 | 2 |
| 4 | name4 | 2 |
I tried this:
select *
from TestTable
group by Flags
order by Flags
limit 0,2
However the query returned 2 rows only.
You could use a sub query to take only the first two flags, and join that:
select t.id, t.name, t.flags
from testtable t
inner join (select distinct flags
from testtable
order by 1
limit 2) filter
on filter.flags = t.flags;
See it run on regtester.com

How to join ON IN ALL relations

tag table
| id | label |
| 1 | test1 |
| 2 | test2 |
| 3 | test3 |
image table
| id | data |
| 1 | data1 |
| 2 | data2 |
| 3 | data3 |
mapping table
| id | tagId | imageId |
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 2 | 2 |
| 4 | 3 | 2 |
| 5 | 3 | 3 |
I'm trying to find the image that has all tags in common (image.id = 2).
How do I query for it when tag ids 1, 2 and 3 are provided?
(Sorry for the bad question title)
Here is one method:
select m.imageId
from mapping m
where tagId in (1, 2, 3)
group by m.imageId
having count(*) = 3; -- needs to match the number of tags in the `where` clause
One way to do it grouping on imageid and checking for the required count of tagid's.
select imageid
from mapping_table
group by imageid
having count(distinct case when tagid in (1,2,3) then tagid end) = 3

Combine records from two tables in one query

I have the following tables,
select * from tbl1;
+------+------------+---------+----------+
| id | userId | part_id | url |
+------+------------+---------+----------+
| 1 | 155 | 1 | "http:/" |
+------+------------+---------+----------+
select * from tbl2;
+------+------------+---------+-------------+------------+-----------+
| id | userId | part_id | tbl2_id1 | tbl2_id2 | notes |
+------+------------+---------+-------------+------------+-----------+
| 1 | 155 | 1 | 12 | 1 | note 1 |
| 2 | 155 | 1 | 12 | 2 | note 2 |
+------+------------+---------+-------------+------------+-----------+
As you can see tbl2 has two FK (userId and part_id), tbl2_id1 and tbl2_id2 are the PK of tbl2.
My question is how can I get the three records from both tables in one query?
Something like this
1 | 155 | 1 |"http:/" | from tbl1
1 | 155 | 1 | note 1 | from tbl2
2 | 155 | 1 | note 2 | from tbl2
You want to use union all:
select id, userId, part_id, url, 'from tbl1' as which
from tbl1
union all
select id, userId, part_id, notes, 'from tbl2'
from tbl2;

Extend Mysql table for same id

My table structure is:
id | type | attribute | customer_id | value
1 | 2 | 1 | 1 | some
2 | 2 | 2 | 1 | this
3 | 2 | 3 | 1 | that
4 | 2 | 1 | 2 | cool
5 | 2 | 2 | 2 | just
etc
I want to add value='mine' as attribute 4 to each customer_id.
INSERT INTO mytable
SET type='2', attribute='4, value='mine'
The question is how to bind it on customer_id and only once per customer?
INSERT INTO myTable(type, attribute, customer_id, value)
SELECT 2 type,
4 attribute,
s.customer_id,
'mine' `value`
FROM (SELECT DISTINCT customer_id FROM myTable) s