MySQL count complex query results - mysql

I'm looking for a query to know how many times the value of a field is repeated in a select?
I prove with:
$queryIds ="select id,idpol,count(idpol) as qid from table WHERE id IN($idafectades) group by idpol";
But I'm looking for something like:
id, idpol, count_idpol (number of times that each idpol's value appears in the group of rows)
1, 1000, 3
2, 1000, 3
3, 1002, 1
4, 1003, 2
5, 1003, 2
6, 1000, 3
Thanks

This is one way without using a windowed set. Generate a set of data containing the counts grouped by the IDPOL, then join it back to the base set of each ID and IDpol.
SELECT foo.id, foo.idpol, B.cnt
FROM foo
INNER JOIN (SELECT count(*) cnt, IdPOL FROM Foo GROUP BY IDPOL) B
on Foo.IDPOL = B.IDPOL
SQL Fiddle

Related

How to count the number of entries in the list when requesting Select?

I apologize for the possible incorrectness in the presentation, I use a translator. Let's say there is a users table in which there is an id field. And there is a list that lists the id numbers and some of them are repeated. My query
select id, count(*)
from users
where id in (3, 10, 10, 10)
group by id;
returns the following 3 - 1, 10 - 1. And I would like to get 3 - 1, 10 - 3, and so on. Is it possible to get it somehow?
UPD.
The data in the list (3, 10, 10, 10) is just an example, the exact number of digits is not known because they are returned from another question.
You would need to use a join. You can put the values in a derived table for this:
select id, count(*)
from users u join
(select 3 as id union all
select 10 as id union all
select 10 as id union all
select 10 as id union all
) i
using(id)
group by id;

Finding records that occur most commonly together in SQL

I have a table of ingredients:
ing_id, ing_name
1 , ing1
...
a table of recipes:
rec_id, rec_name
1 , rec1
...
and a table showing the connection between the two:
id, ing_id, rec_id
1, 1, 1
2, 1, 2
3, 2, 1
4, 3, 3
...
How can I find the ingredients that most commonly appear in the same recipe?
You can use a self join and group by:
select c1.ing_id, c2.ing_id, count(*)
from connections c1 join
connections c2
on c1.rec_id = c2.rec_id and c1.ing_id < c2.ing_id
group by c1.ing_id, c2.ing_id
order by count(*) desc;
If you actually want the names instead of the ids, you'll need two more joins to bring them in.

Sum Of column against id.in (1:6:3) this format

my Ui return id in this format 1:6:3 so i want to sum the value corresponding to that id. example if id return is = 1:6:3
then output will= 100+50+140=290
How about SELECT SUM(value) FROM table WHERE ID IN (1,6,3) ?
Took some time to figure out what's the question. I think I got it now - it is about Apex and its "capability" to allow multiple selection from, for example, a select list or shuttle item. When you do that, those multiple values are represented as a colon-separated string.
If we suppose that it was a select list item, it requires two values: display and return. The resulting string contains those return values, which means that you selected several items whose return values were 1, 6 and 3 and - as described above - stored as 1:6:3.
In order to do something with them - in your example, sum values from the table - you'll have to first parse that string into rows and join the result with the "real" table (the one whose image you posted). Let's call it the TEST table; here it is:
SQL> create table test (id number, value number, name varchar2(2));
Table created.
SQL> insert into test
2 select 1, 100, 'a' from dual union
3 select 2, 110, 'b' from dual union
4 select 3, 140, 'c' from dual union
5 select 4, 203, 'd' from dual union
6 select 5, 230, 'e' from dual union
7 select 6, 50 , 'f' from dual;
6 rows created.
In Apex, you'd do it as follows: P1_ITEM is a Page 1 item that contains the '1:6:3' string:
select sum(t.value) result
from test t join (select regexp_substr(:P1_ITEM, '[^:]+', 1, level) id
from dual
connect by level <= regexp_count(:P1_ITEM, ':') + 1
) a on a.id = t.id;
Just to demonstrate it in SQL*Plus, this is the result:
SQL> select sum(t.value) result
2 from test t join (select regexp_substr('&&P1_ITEM', '[^:]+', 1, level) id
3 from dual
4 connect by level <= regexp_count('&&P1_ITEM', ':') + 1
5 ) a on a.id = t.id;
Enter value for p1_item: 1:6:3
RESULT
----------
290
SQL>

Find rows with same value of a column

I need to perform a query that find values based on 1 field if the 2nd field is same
Example table:
id, what, why
1, 2, 2
2, 3, 4
3, 3, 2
So I want the results to return what 2 and 3 because they both have why of 2.
But the why (2) is unknown so I only what to know if the combination of what (2 and 3) have the same why value. Makes sense? Any help is appreciated thanks.
Another example maybe clearer
id, building, color
1, house, white
2, garage, red
3, garage, white
I query where building = house and building = garage and results are only given if they have matching color.
SELECT what
FROM YourTable A
WHERE EXISTS(SELECT 1 FROM YourTable
WHERE what <> A.what
AND why = A.why)
Here is a demo of this.
You can do it like this:
select *
from test
where why in (
select why
from test
group by why
having count(*) > 1 -- Use = 2 if you want exactly two items
)
Demo on sqlfiddle.
The inner query finds all such whys that have duplicates, and uses their values to filter the rows of the outer query.
Use a self-join.
SELECT t1.what
FROM Table t1
JOIN Table t2
ON t1.why = t2.why and t1.what != t2.what
Would something like this work:
SELECT GROUP_CONCAT(what) as what, why
FROM YourTable
GROUP BY why
HAVING COUNT(*) > 1
DEMO: http://sqlfiddle.com/#!2/62da8/5

Get list of IDs not present in table

Say I have a list of ids, e.g. (1, 3, 9, 2, 4, 86), and a table with a column id. I want to find all of the numbers in my list where there is not a matching row.
i.e. if the mysql table was like this:
id letter
1 a
2 b
3 c
4 d
5 e
6 f
7 g
And I have the list (1, 3, 9, 2, 4, 86), I want a query that will return (9, 86).
The only thing I can think of, is to build a really big virtual table, like:
select 1 as n union select 3 as n union select 9 as n union ....
Which I can then join against. Is there a better way? I would like to be able to do this all within mysql. As a side note (although I don't expect it to be relevant), my table has around 10,000 rows, and the list I'm using has ~100 numbers in it.
You have to first create a table that will contain the elements of the LIST
i.e (1, 3, 9, 2, 4, 86)
create table t
(
num int
)
insert into t
values
(1),(3),(9),(2),(4),(86)
Now you can use NOT IN
SELECT num
FROM t
WHERE num not in (select id from letter_table);
SQL Fiddle
From Comments.
Edit:
There is a way in which you don't have to create a table
select N from
(select 1 as N
union all
select 3 as N
union all
select 9 as N
union all
select 2 as N
union all
select 4 as N
union all
select 86 as N)t1
where t1.N
not in (select id from letter_table)
Please refer the New SQL Fiddle.
I think OP want's the Edited Part.
P.S. Make Sure table t1 doesn't exists in your DB
Create a table which contains IDs and than you can do it eaasily. See a demonstration here
SELECT
S.id,
'' AS `letter`
FROM sequence S
WHERE S.id NOT IN(SELECT
id
FROM mytable)
SQL Fiddle Demo
Assuming you use the temp table or the UNION method in #Luv's answer, consider replacing the NOT IN with an outer join as it'll likely perform better (test with your actual environment & data, of course):
SELECT num
FROM t
LEFT OUTER JOIN letter_table
ON t.num = letter_table.id
WHERE letter_table.id IS NULL;
If you use the UNION method, replace FROM t with FROM ([big UNION here]) t.