Mysql fetch rows only contain a row with certain value - mysql

Lets say, my tables has the following rows:
id | prop1 | prop2
______________________
1 foo a
2 bar a
3 foo b
4 bar b
5 foo c
Now in this case, i want to get rows grouped by prop1 but ignore the groups that don't contain a row with prop2=c
So the intended result is:
1 foo a
3 foo b
5 foo c
Note, now there is only one group in the example but i want to be able to get all of them. How can i achieve this approach?

You can use exists clause to remove all the rows if it does not have prop2 = c using below query.
select *
from your_table t1
where
exists (select 1 from your_table t2 where t1.prop1 = t2.prop1
and t2.prop2 = 'c')
Explaination: Exists caluse will return true if it finds c for that group else false.

SELECT * FROM table WHERE prop2 != "c" GROUP BY prop1
This line is gonna delete att rows with C and the group everything else on prop1

Your expected result is not grouped by prop1. If it was grouped by prop1 then you would get only one record in the result.
To achieve the above, we can write a simple SELECT with sub-query, e.g.:
SELECT *
FROM table
WHERE prop1 IN (
SELECT prop1 FROM table WHERE prop2 = 'c'
);

The following query fetches all record with prop2 = 'c' (T1)
and joins them on all records (T2) that have an equal prop1:
select T2.*
from TABLE T1
join TABLE T2 ON T1.prop1=T2.prop1
WHERE T1.prop2 = 'c'
GROUP BY id

Related

How i can get all query in one field?

I've two tables like this:
First :
id
num
1
a
2
b
3
c
Second:
id
first_id
value
11
1
a1
12
1
a2
13
1
a3
And I need to get result like this:
id
value
1
a1-a2-a3
I've tried with query:
SELECT first.id, (SELECT second.value FROM second
WHERE second.first_id = first.id) AS value
FROM first
But I've got #1242 error. How I can do it?
You can use group_concat()
select first_id as id,
group_concat(`value` order by `value` separator '-') as combined_values
FROM second_table
group by first_id

Joining tables and getting a count of specific record

I am having two tables say table_a and table_b with following structure.
table_a : ID(primary key), value_one
table_b: ID, value_two
Note that id in table_b is not primary and contains multiple records to same id.
now i want a third table which displays a record for every id in table_a with columns being
id column_count
the column _count will display number of records (count) in table_b with value_two = 'c'. and i want to iterate this to all records of table_a.
For example lets say our table_a is like this:
id value_one
1 20
2 40
3 50
table_b
id value_two
1 10
1 20
1 10
2 40
2 10
3 40
3 10
I want records with value_two = 10 so my new table would look like
id count
1 2
2 1
3 1
Since id 1 has two records with value_two = 10 and id 2 and id 3 have one record each with value_two = 10
One way of doing this uses a correlated subquery:
select a.id,
(select count(*) from table_b b where b.id = a.id and b.value_two = 10) as cnt_10
from table_a a;
Another method uses a left join:
select a.id, count(b.id)
from table_a a left join
table_b b
on b.id = a.id and b.value_two = 10
group by a.id;
In your example data, this works:
select b.id, count(*)
from table_b b
where b.value_two = 10
group by b.id;
This is equivalent under the following circumstances:
All ids in a are in b.
All ids have at least one value of 10.
If these two conditions are true, then use this simpler query.
You can do conditional aggregation :
select id, sum(value_two = 10) as count
from table_b tb
group by id;
If you want matching ids then add INNER JOIN. This will show 0 count whereas value_two = 10 not found. You can add where clause to find only value_two = 10 count.

MySQL order once by field value from join then by non joined column

I have 2 tables - one contains meta data about a form and the other contains the fields themselves. In the metadata table there is an option to choose which field gets displayed first and then within the fields table there is an ordering column which displays the ordering for the remaining fields.
I need to be able to sort a query so it shows the value of the joined metadata field first and then by the ordering column.
For example:
forms
id sort_field
1 6
2 0
form_fields
id form_id name ordering
1 2 field1 1
2 2 field2 3
3 2 field3 2
4 1 fielda 3
5 1 fieldd 2
6 1 fieldc 4
7 1 fieldb 1
My current query is:
select ff.name
from form_fields ff
left join forms f on ff.form_id=f.id
order by f.sort_field DESC, ff.ordering ASC
This works for form 2 as it doesn't have any sorting in forms - it doesn't work for form 1 as, using the join, sorting_field is always 6 hence it sorts as if there was no value in sorting_field.
My desired output for form 1 would be:
fieldc
fieldb
fieldd
fielda
Is it possible to sort by sort_field once in effect if it is set and then by the remaining ordering fields as normal?
You can set a new_order field.
select name
from
(select ff.name
case when id = f.sort_field then 0 else ff.ordering end new_order
from form_fields ff
left join forms f on ff.form_id=f.id
) t
order by t.new_order
You can do it using a UNION query, e.g.:
(SELECT name, 0 as ordering
FROM form
WHERE id = (SELECT sort_field FROM form_fields where id = 1)
AND form_id = 1)
UNION
(SELECT name, ordering
FROM form
WHERE form_id = 1
AND id != (SELECT sort_field FROM form_fields where id = 1))
ORDER BY ordering
Here's the SQL Fiddle.

MySql , How to select the not repeated rows only

I have a table with 100 000 record, I want to select only the none repeated.
In another word, if the row are duplicated did not show it at all
ID Name Reslut
1 Adam 10
2 Mark 10
3 Mark 10
result
ID Name Reslut
1 Adam 10
any ideas ?
You could join a query on the table with a query that groups by the name only returns the unique names:
SELECT *
FROM mytable t
JOIN (SELECT name
FROM mytable
GROUP BY name
HAVING COUNT(*) = 1) s ON t.name = s.name
Using the same set :
ID Name Result
1 Adam 10
2 Mark 10
3 Mark 10
4 Mark 20
I'm guessing the final solution would be:
ID Name Result
1 Adam 10
4 Mark 20
Using the above query previously suggested I modified it to take the result into consideration:
SELECT t1.*
FROM myTable t1
JOIN
(
SELECT name, result
FROM myTable
GROUP BY name, result
HAVING COUNT(*) = 1
) t2
WHERE
t1.name=t2.name and
t1.result = t2.result;

how do i eliminate a particular value when an id has more than one value in mysql

I have a mysql query which returns more than one row for few ID's with different values. In such a case i need to eliminate the ID's with certain data.
Example
I need to elimate A1 for all those ID's which has more than one name and else if it has only one value A1 then i should be able to display it.
Result Should look like:
ID Name Value
1 A1 AA
1 B1 AB
2 C1 CC
3 A1 AA
4 A1 AA
4 E1 AD
4 B1 AB
Please a solution for this
This is probably very ugly, but at least gets the job done:
select id, name, value from (
select f.*, c.count
from <TABLE> f, (select *, count(*) as 'count' from <TABLE> group by id) c
where f.id = c.id
) c
where (name = 'A1' and count = 1) or name != 'A1'
group by id
you will get the 'first' row for remaining (not random) for id = 4