HAVING COUNT receiving other COUNT value - mysql

I'm working with a select in two different tables that should be match by group reference id, like:
Table 1 and table 2:
+-----+-----+------------+ +-----+------+
| gid | tid | created | | gid | nid |
+-----+-----+------------+ +-----+------+
| 0 | 816 | 1480002041 | | 0 | 1123 |
| 1 | 731 | 1480003932 | | 0 | 1124 |
| 1 | 736 | 1480003932 | | 1 | 1125 |
| 2 | 746 | 1480003932 | | 1 | 1126 |
+-----+-----+------------+ | 1 | 1123 |
| 2 | 1124 |
| 1 | 1129 |
+-----+------+
I need to get nid values from table 2 that have a exactly group match with the group on table 1. The reference to search in table 1 is tid.
I believe that the SQL would be something like that:
SELECT t1.nid
FROM table1 t1
INNER JOIN
(
SELECT gid
FROM table2
WHERE tid IN (731, 736, 746, 751)
GROUP BY gid
HAVING COUNT(DISTINCT tid) = 4
) t2 ON t1.gid = t2.gid;
But how can I get the exactly count to replace hard coded number 4?

SELECT t2.nid
FROM table1 t1
INNER JOIN
table2 t2
ON t1.gid = t2.gid;
WHERE t2.tid IN (731, 736, 746, 751)
GROUP BY t2.gid

Related

Having two MySQL tables, get the last result for each value of first table key

I have two tables:
TABLE_01
-------------------------------
| ID | Key1 | Key2 |
-------------------------------
| 1 | 504 | 101 |
| 2 | 504 | 102 |
| 3 | 505 | 101 |
| 4 | 505 | 103 |
| 5 | 508 | 101 |
| 6 | 510 | 104 |
| 7 | 509 | 101 |
-------------------------------
TABLE_02
----------------------------------------
| ID | T_01 | timestamp | data |
----------------------------------------
| 1 | 1 | ts_01 | ..abc.. |
| 2 | 1 | ts_02 | ..dfg.. |
| 3 | 2 | ts_03 | ..hij.. |
| 4 | 3 | ts_04 | ..klm.. |
| 5 | 1 | ts_05 | ..nop.. |
| 6 | 4 | ts_06 | ..qrs.. |
| 7 | 3 | ts_07 | ..tuv.. |
| 8 | 5 | ts_08 | ..wxy.. |
| 9 | 2 | ts_09 | ..z.... |
| 10 | 4 | ts_10 | ..abc.. |
----------------------------------------
On both table, ID is the Primary Incremental Key
In TABLE_01, the columns key1 + key2 are Unique Key (Can't be more than one Key1 Key2 couple)
In TABLE_02, the column T_01 makes reference on TABLE_01.ID
My goal is that given a key1 value, be able to get the last entry of TABLE_02 for each TABLE_01.ID with the correspondent timestamp on DESC ORDER.
For example, if I give 505, the output should be:
KEY1 | KEY2 | TIMESTAMP
---------------------------
505 | 103 | ts_10 ---> FROM TABLE_01.Id = 4
505 | 101 | ts_07 ---> FROM TABLE_01.Id = 3
As you can see, It only shows the last entry on the case of TABLE_01.ID = 4 (which is 505 | 103)
I have tried to do something like this:
SELECT `t1`.`Key1`, `t1`.`key2`, `t2`.`timestamp`
FROM `TABLE_02` AS t2
INNER JOIN `TABLE_01` AS t1
WHERE `t1`.`key1` = '505'
ORDER BY `t2`.`ID`
DESC LIMIT 100
The problem with this query is that since I am using t2.timestamp, I am receiving all the results instead of only ONE for EACH. Also, I'm not using correctly the TABLE_01.ID on TABLE_02.
If you just want the latest timestamp in the second table per combination of keys in the first table, you can join and aggregate:
select t1.key1, t1.key2, max(t2.timestamp) max_t2_timestamp
from table_01 t1
inner join table_02 t2 on t2.t_01 = t1.id
group by t1.key1, t1.key2
If you want the entire row of the second table, then I would recommend window functions:
select *
from (
select t1.key1, t1.key2, t2.*,
row_number() over(partition by t1.key1, t1.key2 order by t2.timestamp desc) rn
from table_01 t1
inner join table_02 t2 on t2.t_01 = t1.id
group by t1.key1, t1.key2
) t
where rn = 1

MySQL find duplicates based on another column value

I have the following table
+----+------+-------+
| id | user | value |
+----+------+-------+
| 1 | 10 | A |
| 2 | 12 | B |
| 3 | 24 | A |
| 4 | 33 | C |
+----+------+-------+
I want to retreive all the duplicates users that have the same key
+----+------+-------+
| id | user | value |
+----+------+-------+
| 1 | 10 | A |
| 3 | 24 | A |
+----+------+-------+
I've tried that with no luck
SELECT DISTINCT A.user, A.value
FROM table as A
INNER JOIN ( SELECT value FROM table GROUP BY value HAVING COUNT(value) > 1 ) AS B
ON A.value = B.value
You may try below query -
SELECT id, user, value
FROM YUOR_TABLE T1
WHERE EXISTS (SELECT 1
FROM YOUR_TABLE T2
WHERE T1.value = T2.value
AND T1.user <> T2.user)

SQL query to get minimal sum value and associated column from table

I have following tables:
t1 - Items
| Id | Item |
| 1 | I1 |
| 2 | I2 |
t2 - Item_elements
| Id | Item_id | Element | Our_quantity | Client_quantity |
| 1 | 1 | E11 | 100 | 0 |
| 2 | 1 | E12 | 20 | 300 |
| 3 | 2 | E21 | 300 | 100 |
| 4 | 2 | E22 | 5 | 300 |
t3 - Element_operations
| Id | Element_id | Operations_number |
| 1 | 1 | 100 |
| 2 | 1 | 50 |
| 3 | 2 | 50 |
| 4 | 2 | 50 |
| 5 | 3 | 50 |
| 6 | 3 | 50 |
| 7 | 3 | 50 |
| 8 | 3 | 50 |
| 9 | 4 | 10 |
I need SQL query which return table witch items (t1) AND element row associated with item table which has minimum operations number
Desired Output:
Table should look like
| Id|Item| Id_el |Our_quantity| Client_quantity | Count Operations_number|
| 1| I1 | 2 | 20 | 300 | 100 |
| 2| I2 | 4 | 5 | 300 | 10 |
result
I tried that query
SELECT t2.Id,Item_id,Our_Quantity,Client_Quantity,SUM(Operations_number)
FROM t2 LEFT JOIN t3 ON t2.Id=t3.Id_el GROUP BY t2.Id)
Tried Result:
| Id | Item_id | Our_quantity | Client_quantity |SUM(Operations_number)
| 1 | 1 | 100 | 0 | 150
| 2 | 1 | 20 | 300 | 100
| 3 | 2 | 300 | 100 | 200
| 4 | 2 | 5 | 300 | 10
What should I do next?
Now I have 2 table:
| Element Id | Item_id |Sum operations_number for element |
| 1 | 1 | 150 |
| 2 | 1 | 100 |
| 3 | 2 | 200 |
| 4 | 2 | 10 |
| Item Id | Item |
| 1 | I1 |
| 2 | I2 |
How can I join them to get this table?
Item Element who has minimal sum operations number.
| Item Id | Item | Element_Id | Sum operations_number for element |
| 1 | I1 | 2 | 100 |
| 2 | I2 | 4 | 10 |
You could get desired output using this..
SELECT
t.*,
MIN(t.opsum) AS `Count Operations_number`
FROM
(SELECT
a.*,
b.Id AS `Id_el`,
b.`Our_quantity`,
b.`Client_quantity`,
SUM(c.`Operations_number`) AS opsum
FROM
`t1` AS a
LEFT JOIN `t2` AS b
ON a.`Id` = b.`Item_id`
LEFT JOIN `t3` AS c
ON b.`Id` = c.`Element_id`
GROUP BY a.Id,
b.Id
ORDER BY a.`Id` ASC,
opsum ASC) AS t
GROUP BY t.Id ;
FIDDLE HERE
Maybe if you use the MIN() method in the desired column, as example:
SQL
SELECT t2.Id,Item_id, MIN(Our_Quantity), Client_Quantity, SUM(Operations_number)
FROM t2 LEFT JOIN t3
ON t2.Id=t3.Id_el
GROUP BY t2.Id
You may try this..
For mysql 8+
with cte as (
SELECT t1.id as Item_id, t1.item, t2.id as Ele_Id, t2.Element , t2.Our_quantity , t2.Client_quantity , t3.Operations_number
from Items as t1
inner join Item_elements as t2 on t1.id=t2.Item_id
inner join Item_elements as t3 on t2.id = t3.Element_id
)
, ct as (
select row_number() over ( partition by t1.id order by t2.Our_quantity ) as Slno, * from cte
)
select c.item_id, c.item, c.Ele_id, c.Element, c.our_quantity, c.client_quantity, t.Count_Operations_number
from ct as c
inner join
(
select distinct Element_id , sum(Operation_number) as Count_Operations_number
from Element_operations group by Element_id
) as t
on c.Ele_id=t.Element_id
where c.slno=1
Try the below query, hope this is what you are asking
select t1.Id as 'Id',t1.Item as 'Item',
t.Id as 'Id_el', t.Our_quantity as 'Our_quantity',t.Client_quantity as 'Client_quantity',
sum(t3.Operations_number) as 'Count Operations_number'
from t1 join (select *
from t2 where (Item_id,Our_quantity) in
( select Item_id, min(Our_quantity) from t2 group by Item_id)) t on t1.Id=t.Item_id
join t3 on t.Id=t3.Element_id
group by t1.Id;
Do you want it in the minimum order of SUM(Operations_number)?
Try this
I have updated the answer so this will get the first table also.
SELECT t1.id,
t1.item,
id_el,
our_quantity,
client_quantity,
sum
FROM t1
JOIN (SELECT t2.id AS Id_el,
t2.item_id,
t2.our_quantity AS our_quantity,
t2.client_quantity AS client_quantity,
sum
FROM t2
JOIN (SELECT t3.element_id,
Sum(operations_number) AS sum
FROM t3
GROUP BY element_id) AS b
ON t2.id = b.element_id) AS c
ON t1.id = c.item_id
ORDER BY sum ASC
Output would be:

How to fetch data from two tables using mysql query with some conditions applied to the second table?

I want to generate a result from a MySql query with below requirement.
Table 1 :
---------------
| nid | type |
---------------
| 1 | forum |
| 2 | forum |
| 3 | forum |
| 4 | forum |
---------------
Table 2
-----------------------
| nid | cid | created |
-----------------------
| 1 | 32 | 123456 |
| 2 | 65 | 123457 |
| 4 | 67 | 123458 |
| 1 | 61 | 123491 |
| 1 | 78 | 123497 |
| 2 | 23 | 123498 |
| 1 | 12 | 123698 |
| 4 | 54 | 132365 |
| 4 | 81 | 135698 |
| 1 | 30 | 168965 |
-----------------------
Now i require result like below. (Condition : I need the nid from first table, smallest cid for the corresponding nid in second table WHERE type = 'forum')
--------------
| nid | cid |
--------------
| 1 | 12 |
| 2 | 23 |
| 4 | 67 |
--------------
You can try this
SELECT tbl1.nid,
min(tbl2.cid) as cid
FROM table1 tbl1
INNER JOIN table2 tbl2 ON tbl1.nid=tbl2.nid
GROUP BY tbl2.nid;
SQL Fiddle
Try this
SELECT t1.nid,
min(t2.cid) as cid
FROM table1 t1
INNER JOIN table2 t2 ON t1.nid=t2.nid
GROUP BY t2.nid;
This could also work
select nid, min(cid) cid
from table2
group by nid
The above queries are have issues in group by clause. Kindly check this query.
SELECT t1.NID, MIN(t2.CID) AS cis from
TAB1 t1 inner join TAB2 t2 on t1.nid = t2.nid
group by t1.nid

MySQL - How to update atable based on an internal ordering of the table

If I make a selection from my MySQL table like:
SELECT * FROM mytable ORDER BY country_id, category
I get the following table:
+------------+----------+-------+
| country_id | category | order |
+------------+----------+-------+
| 1 | A | 0 |
| 1 | B | 0 |
| 1 | F | 0 |
| 3 | A | 0 |
| 3 | C | 0 |
| 5 | B | 0 |
| 5 | L | 0 |
| 5 | P | 0 |
+------------+----------+-------+
What I would like to do is update the order column so that the value of that column is the order of that row for it's country_id. In other words the final table should look like this:
+------------+----------+-------+
| country_id | category | order |
+------------+----------+-------+
| 1 | A | 1 |
| 1 | B | 2 |
| 1 | F | 3 |
| 3 | A | 1 |
| 3 | C | 2 |
| 5 | B | 1 |
| 5 | L | 2 |
| 5 | P | 3 |
+------------+----------+-------+
If I use the original query given at the top in a subquery, that would give me the correct order but I can't figure out how to iterate through the table and suspect I thinking about it wrongly.
How can I get this result?
Many thanks
Try to use this query -
UPDATE mytable t1
JOIN (
SELECT t1.country_id, t1.category, COUNT(*) `order`
FROM mytable t1
LEFT JOIN mytable t2
ON t2.country_id = t1.country_id AND t2.category <= t1.category
GROUP BY
t1.country_id, t1.category
) t2
ON t1.country_id = t2.country_id AND t1.category = t2.category
SET t1.`order` = t2.`order`
As an aside note, you can remove order field from the table because this can calculated this on the fly.