I'm using this query:
SELECT sender_userid,receiver_userid,message,message_read,`datetime`,sender_userid + receiver_userid AS message_token FROM messages
WHERE (receiver_userid='1000000172' OR sender_userid='1000000172') AND friendship_status=1 AND receiver_history=1
GROUP BY message_token;
The results are:
If I drop the Group By I get this result:
You will see in the second image there are 2 different 'message_token' results.
Why when I Group By this do I only get one result? Shouldn't it show both?
Is there a way to get both unique 'mesage_token' results?
After doing a bit of research i found out that this is a bug for the following MySQL versions: 5.1, 5.5, 5.6, 5.7.
Here's the bug report page where the develelopers recognize it's now working as it should.
From the same page, the code to reproduce it:
CREATE TABLE t1 (a INT, b VARCHAR(1), INDEX(b,a)) ENGINE=MyISAM;
INSERT INTO t1 VALUES (2,'s'),(5,'h'),(3,'q'),(1,'a'),(3,'v'),
(6,'u'),(7,'s'),(5,'y'),(1,'z'),(5,'i'),(2,'y');
SELECT b, max(a) FROM t1 WHERE b = 'i' OR a = 2 GROUP BY b;
Related
I've accidentally managed to add duplicate entries into my database. The database contains a list of telephone numbers and they are routed via the information contained in the value field. The id field is unique per entry, and the UUID and username fields should be identical but shouldn't exist in the table more than once.
Data has been blanked in the screenshot for data protection.
The following command allowed me to identify I had duplicate entries which can be seen in the screenshot above.
select * uuid, count(*) from usr_preferences group by uuid having count(*) > 1;
I'm after some help on how I could delete entries where the UUID count is more than one but one entry must remain. deleting the duplicate UUID with the highest id number would be preferred.
Is there a way to display the results before deleting them?
MySQL version - mysql Ver 14.14 Distrib 5.7.38-41, for Linux (x86_64) using 6.2
Thanks
Could you give the following bit of code a go? Please make sure you have the database backed up before running this.
DELETE b FROM `test` a, `test` b where b.uuid = a.uuid and b.id > a.id;
I've expanded on your text data to make sure it will remove both duplicates and triplicates leaving the lowest ID. You can find my testing at this DB Fiddle.
https://www.db-fiddle.com/f/sUr6V6UP9tZ1Ya8eESid33/0
Hope this sorts you issue.
Try the following for MySQL v5.7:
set #rn=0;
set #uuid=null;
delete from usr_preferences where id in
(
select D.id
from
(
select id, uuid,
case
when #uuid <> uuid then
#rn:=1
else
#rn:=#rn+1
end as rn,
#uuid:=uuid
from usr_preferences order by id,uuid
) D
where D.rn>1
);
Select * From usr_preferences;
See a demo from db-fiddle.
Important Note:
Test the query before using it on your table, and take a backup of your table before running this query on it.
For MySQL v8.0 and above you may try the following:
with cte as
(
select id, row_number() over (partition by uuid order by id) as rn
from usr_preferences
)
delete U From
usr_preferences U join cte C
On U.id = C.id
where C.rn > 1;
With MySql vers 8.0:
CREATE TABLE cnacs(cid VARCHAR(20), PRIMARY KEY(cid));
Then,
INSERT INTO cnacs VALUES('1');
The first two statements execute successfully. The next statement does not, however. My goal is to return a list of unused cid's from the input table [1, 2]:
SELECT * FROM (VALUES ('1'),('2')) as T(cid) EXCEPT SELECT cid FROM cnacs;
In theory, I'd like the output to be '2', since it has not yet been added. The aforementioned query was inspired by Remus's answer on https://dba.stackexchange.com/questions/37627/identifying-which-values-do-not-match-a-table-row
This is at least the correct syntax for what you are trying to do.
If this query is anything more than a learning exercise though I'd rethink the approach, storing these '1' and '2' values (or however many there ends up being) in their own table
SELECT Column_0
FROM (SELECT * FROM (VALUES ROW('1'), ROW('2')) TMP) VALS
LEFT
JOIN cnacs
ON VALS.Column_0 = cnacs.cid
WHERE cnacs.cid IS NULL
I've got 2 mysql 5.7 databases hosted on the same server (we're migrating from 1 structure to another)
I want to delete all the rows from database1.table_x where the there is a corresponding row in database2.table_y
The column which contains the data to match on is called code
I'm able to do a SELECT which returns everything that is expected - this is effectively the set of data I want to delete.
An example select would be:
SELECT *
FROM `database1`.`table_x`
WHERE `code` NOT IN (SELECT `code`
FROM `database2`.`table_y`);
This works and it returns 5 rows within 138ms.
--
However, If I change the SELECT to a DELETE e.g.
DELETE
FROM `database1`.`table_x`
WHERE `code` NOT IN (SELECT `code`
FROM `database2`.`table_y`);
The query seems to hang - there are no errors returned, so I have to manually cancel the query after about 3 minutes.
--
Could anyone advise the most efficient/fastest way to achieve this?
try like below it will work
DELETE FROM table_a WHERE `code` NOT IN (
select * from
(
SELECT `code` FROM `second_database`.`table_b`
) as t
);
Try the following query:
DELETE a
FROM first_database.table_a AS a
LEFT JOIN second_database.table_b AS b ON b.code = a.code
WHERE b.code IS NULL;
I've got one col (state_not_allowed) in TABLE vendor_product where I'm trying to insert values from product_catalog_varchar.value - but only if there's a sku in vendor_product that matches a sku in product_catalog where product_catalog's id equals product_catalog_varchar's id and product_catalog_varchar's attribute id = 523.
I'm basically trying to do the MySQL equivalent of an Excel VLOOPUP. I need the result of the following query:
SELECT product_catalog_varchar.value
FROM product_catalog_varchar
JOIN product_catalog
ON product_catalog.id = product_catalog_varchar.id
JOIN vendor_product
ON vendor_product.sku = product_catalog.sku
AND product_catalog_varchar.attribute_id = 523
To be inserted in to column state_not_allowed, where the sku in vendor_product = the sku in product_catalog.
I've done some research on INSERT INTO, here and on Google in general. Looks like a lot of the instruction out there is on simplier queries so I haven't been able to find a decent model to figure out what to do. I can tell you that this query doesn't work:
INSERT INTO vendor_product(`state_not_allowed`)
SELECT product_catalog_varchar.value
FROM product_catalog_varchar
JOIN product_catalog
ON product_catalog.id = product_catalog_varchar.id
JOIN vendor_product
ON vendor_product.sku = product_catalog.sku
AND product_catalog_varchar.attribute_id = 523
It throws the following error: #1062 - Duplicate entry '' for key 2
And if I got to vendor_product and look, instead of simply inserting values in to state_not_allowed, it's creating a whole new row (with no data). Clearly, I'm misunderstanding in a fundamental sense here. Help me out? Thanks folks.
This query shows the general idea of what you want to do.
insert into table2
(field1)
select distinct field1
from table1
where field1 in
(select field1
from table1
except
select field1
from table2)
The details vary from RDBMS to RDBMS. For example, Oracle uses the keyword minus instead of except. Your MySql documentation will help you with the details.
Note that while it's tempting to simplify this by using "not in" that construct tends to be slow.
A table contains four columns "server", "directory", "usage" and "datetime". All servers has got 10 dirs in common. I need to get the data for a server and it's any dir the usage for the latest datetime in a day.
Say for example if there is a server A with directory B there will be Usage at multiple time for few days. I need the data to be reported by the query for all servers it's all corresponding directory's usage for the latest entry on each day.
If I understood your question correctly, you want to see the last usage for every server and directory. Given a table named "usagestats" with the given columns that would be:
SELECT a.server, a.directory, a.`usage`, a.datetime
FROM usagestats as a INNER JOIN (
SELECT server, directory, max(datetime) datetime
FROM usagestats
GROUP BY server, directory
) AS b ON (
a.server = b.server
and a.directory = b.directory
and a.datetime = b.datetime
)
ORDER BY a.server, a.directory, a.datetime
Im not sure that i understand correctly your question.
MySQL has IF() function, that returns one of statements according to condition in first parameter.
If you want to select data from column where number is bigger and there are only 2 columns - use IF statement like this:
SELECT
if(columnA > columnB, columnA , columnB) as grtColumn,
if(columnA > columnB,'columnA is bigger', 'columnB is bigger') as whichColumnWasGrt
from yourtable;
Help: mysql reference - if() function (there are IF statement and IF() function - diffrent thigs!