Here is my table structure
comment_file_id comment_id attachement_id source created_by
33 203 42 IN 101
35 203 46 OUT 101
36 203 42 OUT 101
37 203 42 OUT 101
i want to get only 3 records only as records associated with attachment_id 42 are duplicates for source OUT , so oi have to exclude those ones.
select *
from comments
where comment_id = 203
GROUP
BY source
, created_by
, attachement_id ;
but getting errors
use min()
select min(comment_file_id) as comment_file_id,comment_id,attachement_id,source
,created_by from table
group by comment_id,attachement_id,source
,created_by
If you are using MySQL 8+, then ROW_NUMBER is helpful here. We can phrase your query as a union of all records not subject to duplicate constraints, along with the single record not deemed a duplicate:
WITH cte AS (
SELECT *, ROW_NUMBER() OVER (ORDER BY comment_file_id) rn
FROM comments
WHERE comment_id = 203 AND attachement_id = 42 AND source = 'OUT'
)
SELECT comment_file_id, comment_id, attachement_id, source, created_by
FROM comments
WHERE comment_id = 203 AND (attachement_id <> 42 OR source <> 'OUT')
UNION ALL
SELECT comment_file_id, comment_id, attachement_id, source, created_by
FROM cte
WHERE rn = 1;
Related
This is my table
id
c_id
number
3444
34
3377752
3446
35
3473747
3447
35
3532061
3454
37
3379243
3455
38
3464467
3456
38
3377493
I want to create a table which is show me not repeated value in a c_id column (repeat just 1 time). the result should be:
id
c_id
number
3444
34
3377752
3454
37
3379243
GROUP BY c_id, number
HAVING COUNT(cart_id) = 1
i tried this but it shows me repeated value again
SELECT ANY_VALUE(id) id,
c_id,
ANY_VALUE(`number`) `number`
FROM tablename
GROUP BY c_id
HAVING COUNT(*) = 1;
You can do it as follows :
select t.*
from _table t
inner join (
select c_id
from _table
group by c_id
having count(1) = 1
) as s on s.c_id = t.c_id;
Check it here : https://dbfiddle.uk/RlxxQ_05
I want to put COUNT(item_id) in this statement:
SELECT * FROM `notifications` WHERE `uid` = '3' AND `seen` = '0' AND id IN (
SELECT MAX(id), COUNT(item_id)
FROM `notifications`
GROUP BY item_id
) ORDER BY id DESC
But This error occurred: Operand should contain 1 column(s).
Table:
[id] [uid] [item_id] [seen]
1 3 69 0
2 3 69 0
3 3 70 0
4 3 69 0
5 3 70 0
6 3 69 0
Expected output: (Order BY id DESC) where 69 is the last record.
[item_id] [num]
69 4
70 2
Given your sample data and expected results, there's no need for a subquery:
select item_id, count(*)
from notifications
group by item_id
where uid = 3 and seen = 0
order by max(id) desc;
Sample Demo
An educated guess says that you want a JOIN:
SELECT n.*, nmax.cnt
FROM notifications n JOIN
(SELECT item_id, MAX(id) as max_id, COUNT(item_id) as cnt
FROM notifications
GROUP BY item_id
) nmax
ON n.item_id = nmax.item_id AND nmax.id = nmax.max_id
WHERE n.uid = 3 AND n.seen = 0 -- removed the single quotes because these are probably numbers
ORDER BY n.id DESC;
It is unclear whether you want the filtering conditions in the subquery as well.
Suppose I have a table
id value
------ ---------
10 123
10 422
11 441
11 986
12 674
13 648
I need a query which will return only those id's which have 2 or more values associated with them. So, in that case it will only return ID 10 & 11, but i need al the records.
so the result looks like:
id value
------ ---------
10 123
10 422
11 441
11 986
Thank you.
select a2.*
from MyTable a2
inner join
(
select a1.id
from MyTable a1
group by a1.id
having count(*) > 1
) a3
on a3.id = a2.id
Assuming a UNIQUE KEY can be formed on (id,value)...
SELECT DISTINCT x.*
FROM my_table x
JOIN my_table y
ON y.id = x.id
AND y.value <> x.value
If a UNIQUE KEY cannot be formed on (id,value), then this isn't really a table in a strict RDBMS sense.
You can use this query :
SELECT * from table where id in
( SELECT id FROM table group by id having count(id) > 1 )
With mysql 8+ or mariadb 10.2+, you would use the count window function:
select id, value
from (
select id, value, count(id) over (partition by id) as num_values
from sometable
) foo
where num_values > 1;
Is it possible to create a mySQL function that accepts as a parameter the result set from a query?
Basically I have a lot of queries that will return a result result set as follows:
id | score
70 | 25
71 | 7
72 | 215
74 | 32
75 | 710
76 | 34
78 | 998
79 | 103
80 | 3
I want to normalize the values such that they come to a range between 0 and 1.
The way I thought I'd do this was by applying calculation:
nscore = (score-min(score))/(max(score) - min(score))
to get following result
id | score
70 | 0.022
71 | 0.004
72 | 0.213
74 | 0.029
75 | 0.710
76 | 0.031
78 | 1.000
79 | 0.100
80 | 0.000
But I'm not able to come up with a query to get the min and max in this query along with results, hence thought of using a function (cannot use stored procedure) but couldn't documentation on how to pass a result set.
Any help appreciated!Thanks!
EDIT:
The score field in result is a computed field. Cannot select it directly.
For eg: Sample query that returns the above result -
select t.id as id, count(*) as score
from tbl t
inner join tbl2 t2 on t.idx = t2.idx
where t2.role in (.....)
just for demo purpose, not actual schema or query
No. MySQL doesn't support defining a function with a resultset as an argument.
Unfortunately, MySQL does not support Common Table Expression (CTE), and does not support Analytic functions.
To get this result from a MySQL query... one way to do that in MySQL would require the original query to be returned as an inline view, two times ...
As an example:
SELECT t.id
, (t.score-s.min_score)/(s.max_score-s.min_score) AS normalized_score
FROM (
-- original query here
SELECT id, score FROM ...
) t
CROSS
JOIN ( SELECT MIN(r.score) AS min_score
, MAX(r.score) AS max_score
FROM (
-- original query here
SELECT id, score FROM ...
) r
) s
ORDER BY t.id
EDIT
Based on the query added to the question ...
SELECT q.id
, (q.score-s.min_score)/(s.max_score-s.min_score) AS normalized_score
FROM ( -- original query goes here
-- ------------------------
select t.id as id, count(*) as score
from tbl t
inner join tbl2 t2 on t.idx = t2.idx
where t2.role in (.....)
-- ------------------------
) q
CROSS
JOIN ( SELECT MIN(r.score) AS min_score
, MAX(r.score) AS max_score
FROM ( -- original query goes here
-- ------------------------
select t.id as id, count(*) as score
from tbl t
inner join tbl2 t2 on t.idx = t2.idx
where t2.role in (.....)
-- ------------------------
) r
) s
ORDER BY q.id
I have a table with the following structure:
itemId | direction | uid | created
133 0 17 1268497139
432 1 140 1268497423
133 0 17 1268498130
133 1 17 1268501451
I need to select distinct values for two columns - itemId and direction, so the output would be like this:
itemId | direction | uid | created
432 1 140 1268497423
133 0 17 1268498130
133 1 17 1268501451
In the original table we have two rows with the itemId - 133 and direction - 0, but we need only one of this rows with the latest created time.
Thank you for any suggestions!
Use:
SELECT t.itemid,
t.direction,
t.uid,
t.created
FROM TABLE t
JOIN (SELECT a.itemid,
MAX(a.created) AS max_created
FROM TABLE a
GROUP BY a.itemid) b ON b.itemid = t.itemid
AND b.max_created = t.created
You have to use an aggregate (IE: MAX) to get the largest created value per itemid, and join that onto an unaltered copy of the table to get the values associated with the maximum created value for each itemid.
select t1.itemid, t1.direction, t1.uid, t1.created
from (select t2.itemid, t2.direction, t2.created as maxdate
from tbl t2
group by itemid, direction) x
inner join tbl t1
on t1.itemid = x.itemid
and t1.direction = x.direction
and t1.created = x.maxdate