is there a optimized/better way to write this query? - mysql

I have below query and wanted to know if this can be re-written in a better way?
SELECT COL1, COL2 FROM TABLE1 WHERE ID = 1 and COL4 = 1415 AND COL3 IN
(SELECT MAX(COL3) FROM TABLE1 WHERE PRI = ID = 1 and COL4 = 1415);
The question arises from the fact that filters ID and Col4 in where clause of subquery are same as the filters in the main query.

You can use:
SELECT COL1, COL2,MAX(COL3) as mx FROM TABLE1 WHERE ID = 1
and COL4 = 1415 having mx=MAX(COL3);
This will avoid the extra sub-query.

Related

How to select two columns together distinctly in no particular order?

I want to select two columns together distinctly in no particular order in MySQL.
For example, the given table is below -
col1 col2 col3
--------------
a b val1
a c val2
b a val1
b c val3
c a val2
c b val3
I need to distinctly select col1 and col2 in no particular order.
col1 = a AND col2 = b
is equivalent to
col1 = b AND col2 = a
in my case, as col3 value will be same for both combinations of col1 and col2.
Expected result is below -
col1 col2 col3
--------------
a b val1
a c val2
b c val3
I want to eliminate duplicates actually.
Any help you can give would be greatly appreciated.
Thank you in advance.
Use greatest and least functions to create groups:
SELECT col1, col2, col3
FROM (
SELECT *,
ROW_NUMBER() OVER(PARTITION BY least(col1, col2), greatest(col1, col2) ORDER BY least(col1, col2), greatest(col1, col2)) AS rn
FROM mytable
) t
WHERE rn = 1
See Demo.
Just to give you an alternative and probably better solution in terms of performance tuning, You may try below query without using window functions -
SELECT * FROM mytable M1
WHERE NOT EXISTS (SELECT 1 FROM mytable M2
WHERE M1.col1 = M2.col2
AND M1.col2 = M2.col1
AND M2.col1 < M2.col2)
Since it uses exists clause, It will perform faster than above query. Here is the demo for both the queries.

MySQL Counting the number of occurrences of a value from a column in another column and storing in new column

How do I structure my query so I can count how many occurrences of a value in column 1 appears in column 2 and then store that result in a new column in the same table? (If a value is duplicated in the first column I still want to store the same value in the new column) For example if I had a table like this:
COL1 COL2
1 2
1 4
2 1
3 1
4 1
4 2
The resulting table will look like this:
COL1 COL2 COL3
1 2 3
1 4 3
2 1 2
3 1 0
4 1 1
4 2 1
Any help is appreciated I am new to sql! Thanks in advance!
Select
col1,
col2,
COALESCE(col3,0) as col3
FROM
mytable
LEFT JOIN
( Select count(*) as col3, col2
from mytable
GROUP BY col2) as temp ON temp.col2 = mytable.col1
And if you want the update (thanks Thorsten Kettner ) :
UPDATE mytable
LEFT JOIN ( Select count(*) as col3, col2
from mytable
GROUP BY col2) as temp ON temp.col2 = mytable.col1
SET mytable.col3 = COALESCE(temp.col3,0)
You can easily count on-the-fly. Don't store this redundantly. This would only cause problems later.
select
col1,
col2,
(
select count(*)
from mytable match
where match.col2 = mytable.col1
) as col3
from mytable;
If you think you must do it; here is the according UPDATE statement:
update mytable
set col3 =
(
select count(*)
from mytable match
where match.col2 = mytable.col1
);
To do that, you can try :
SELECT COL1, COL2, (SELECT COUNT(COL1) FROM `tablename` AS t2
WHERE t2.COL1 = t1.COL1) AS COL3 FROM `tablename` AS t1
Enjoy :)

Selecting distinct 2 columns combination in mysql

I have a mysql table that looks like this:
1 value1 value2 3534
2 value1 value1 8456
3 value1 value2 3566
4 value1 value3 7345
5 value2 value3 6734
I need a query to select all the rows with distinct column 2 and 3, for example the output I want for this example will look like this:
1 value1 value2 3534
2 value1 value1 8456
4 value1 value3 7345
5 value2 value3 6734
i've found a few samples on how to do it but they all select distinct on each column individually.
Update 1
Better you use this against above.
SELECT id, col2, col3, col4
FROM yourtable
GROUP BY col2, col3;
Demo
The reason I am saying is because using CONCAT, I am not getting desired result in this case. First query is returning me 5 rows however CONCAT is returning me 4 rows which is INCORRECT.
Hope you got my point.
Assumed the columns in the table are (id, col2, col3, col4).
SELECT DISTINCT(CONCAT(col2, col3)) as "dummy column", id, col2, col3, col4
FROM yourtable
GROUP BY CONCAT(col2, col3);
OR
SELECT id, col2, col3, MIN(col4)
FROM yourtable
GROUP BY col2, col3;
live working example
Assuming that the first column is unique, you can do this:
SELECT id, col2, col3, col4
FROM yourtable
WHERE id IN
(
SELECT MIN(id)
FROM yourtable
GROUP BY col2, col3
)
See it working online: sqlfiddle
Assuming the columns in the table are (id, col1, col2, col3), you could:
SELECT *
FROM YourTable yt
JOIN (
SELECT MIN(id) as minid
FROM YourTable
GROUP BY
col1, col2
) filter
ON filter.minid = yt.id
This query makes sure that the combination of column1 and column2 is unique, while selecting the minimum value of column three
SELECT col1, col2, MIN(col3)
FROM yourTable
GROUP BY col1, col2
THe simplest query for this is
SELECT col1, col2, MIN(col3)
FROM myTable
GROUP BY col1, col2
Using the group by method is returning me extra rows, where as explicitly checking each field although longer returns the same no of records as count(Distinct ..)
SELECT id, col2, col3, col4
FROM yourtable yt
WHERE id =
(
SELECT MIN(id)
FROM yourtable yt1
WHERE yt.col2 = yt1.col2
AND yt.col3 = yt1.col3
)

MySQL Query Help - Using != with ANY

I have the following query (MySQL):
SELECT col1, col2 FROM database1.table
->WHERE col3 != ANY(SELECT col1 FROM database2.table)
->ORDER BY this, that;
And I had hoped this would allow me to select col1 and col2 from a table in database1 where col3 (still in database1) does not equal anything from col1 in a table in database2.
Naturally, this wont work because SELECT col1 FROM database2.table returns more than one row, so if is equal to row1, then it's not equal to row2 so it's still returned.
Any thoughts on how to do this the right way?
Use NOT IN
SELECT col1, col2 FROM database1.table
->WHERE col3 NOT IN(SELECT col1 FROM database2.table)
->ORDER BY this, that;
but keep in mind that subselects are not optimized in MySQL, and if there are a lot of records in database1.table this would be slow. Faster way is to use JOIN - there are a lot of examples at SO
WHERE col3 NOT IN (SELECT col1 FROM database2.table)
you can use NOT IN operator for this
SELECT col1, col2 FROM database1.table
->WHERE col3 NOT IN(SELECT col1 FROM database2.table)
->ORDER BY this, that;
Just use ALL instead of ANY:
SELECT col1, col2 FROM database1.table
WHERE col3 != ALL(SELECT col1 FROM database2.table)
ORDER BY this, that;

mysql ignore any distinct values

i am trying to run a sql query which will not show distinct/duplicate values.
For example if using distinct option it would display only one unique result, but i would like to skip all detected distinct values i.e dont display distinct values
is it possible?
select col1 d from tb_col where col1 = '123';
col1
------
123
123
(2 rows)
select distinct col1 d from tb_col where col1 = '123';
col1
------
123
(1 row)
SELECT col1
FROM tb_col
GROUP BY col1
HAVING count(*) = 1
Not showing duplicates at all:
SELECT col1 AS d
FROM tb_col
GROUP BY col1
HAVING COUNT(*) = 1 --- or perhaps HAVING COUNT(*) > 1
--- it's not clear what you want.
select col1
from tb_col
group by col1
having count(*) < 2
Try with DISTINCT it will works!
SELECT DISTINCT(col1) as d from tb_col where col1 = '123';