MySQL UPDATE | How to update filepath URI that saved in database - mysql

I have a table album that contains about 1000 rows. I want to update all rows.
Table album have a column named path. See full table structure below.
+---------------------------------------------------------------------------------------------+
| id | name | path |
+---------------------------------------------------------------------------------------------+
| 1 | Believe | Believe |
+---------+-----------+-----------------------------------------------------------------------+
| 2 | A Promise | A Promise |
+---------+----------+------------------------------------------------------------------------+
| 3 | Forever | Forever |
+---------------------------------------------------------------------------------------------+
I want to update path here. Want to add album in path for SEO friendly URLs. table should look like this for that goal.
+--------------------------------------------------------------------------------------------------+
| id | name | path |
+--------------------------------------------------------------------------------------------------+
| 1 | Believe | Believe |
+---------+-----------+----------------------------------------------------------------------------+
| 2 | A Promise | A Promise|
+---------+----------+-----------------------------------------------------------------------------+
| 3 | Forever | Forever |
+--------------------------------------------------------------------------------------------------+
I can't figure out how to use LIKE here, what to insert between % %. Please help me. Thanks in advance.

Related

How to select query for certain value in MySQL query?

I have problem with my SQL query. I wanted to display data that their file condition = no and status condition not equal to pending-update.
This is my current table
| name | file | status |
----------------------------------
| willy | no | pending |
| ash | no | |
| wiki | no | pending |
| Windy | no | pending-update|
| wilma | no | |
-----------------------------
I would like to create a query that will display only this output
| name | file | status |
-----------------------------
| willy | no | pending |
| ash | no | |
| wiki | no | pending |
| wilma | no | |
-----------------------------
As the output data for ash and wilma the value of the column status is is null meaning blank attribute. That is what I want to achieve for this query. But I have problem of fetching the is null value. When I run my query the row that has is null status value did not get displayed in my desired output.
This is what I have tried
SELECT name,file, status FROM tbl_geq where file = 'no' AND (status NOT LIKE 'pending-update');
When I run this query I got this output
| name | file | status |
-----------------------------
| willy | no | pending |
| wiki | no | pending |
-----------------------------
How can I fix my query and achieve this output?
| name | file | status |
-----------------------------
| willy | no | pending |
| ash | no | |
| wiki | no | pending |
| wilma | no | |
-----------------------------
You must handle the NULL values explicitly:
AND (status IS NULL OR status <> 'pending-update')
An alternate (but less readable imo) is:
AND NOT (status <=> 'pending-update')
Keep in mind that SQL uses three-valued logic... a condition could be true, false or unknown. All comparisons involving NULL result in "unknown" which is not the same as false.

Mysql table does not accept any update request

I am using Server version: 5.6.27-log MySQL Community Server (GPL) and I have a problem with a table.
I tried to update some fields with a GUI software, but when I came back to the command line, the lines I tried to update where not updated.
I tried to see if the table was locked using SHOW OPEN TABLES as stated in various other questions. But my table does not appear to be locked:
+--------------------+-------------------------------------------------+--------+-------------+
| Database | Table | In_use | Name_locked |
+--------------------+-------------------------------------------------+--------+-------------+
| arcdev | SCHEDULED_COMMAND | 0 | 0 |
And as soon as I try to make an update like:
UPDATE SCHEDULED_COMMAND SET field = 1;
The server just keeps loading and nothing happen. I tried on other tables and everything worked just fine.
I also tried some DELETE requests and even a DROP TABLE and nothing work so far...
What am I missing?
Thank you for your precious help!
EDIT: Here is the result of the SHOW PROCESSLIST command while a request is hanging:
+--------+----------+---------------------------------------+-----------+---------+------+----------+-------------------------------+
| Id | User | Host | db | Command | Time | State | Info |
+--------+----------+---------------------------------------+-----------+---------+------+----------+-------------------------------+
| 282588 | rdsadmin | localhost:17966 | mysql | Sleep | 2 | | NULL |
| 534575 | arc | XXXXXX:49376 | arcdev | Sleep | 17 | | NULL |
| 534579 | arc | XXXXXX:49443 | arcdev | Query | 0 | init | SHOW PROCESSLIST |
| 534659 | arc | XXXXXX:49836 | arcdev | Query | 14 | updating | DELETE FROM SCHEDULED_COMMAND |
+--------+----------+---------------------------------------+-----------+---------+------+----------+-------------------------------+

Performance issue MYSQL SELECT on view

I'm facing a problem of SELECT perfomance issue with MYSQL.
I have two tables "domain" and "email" which contain duplicates, theses tables are frequently updated (INSERT/DELETE) by different sources (every ten mins approximatively).
My primary objective was to make two views from thoses tables without any duplicates. I know a view is a stored query but this is my only way to keep it dynamic, creating a new table without duplicate every tens mins would be mad (maybe not?).
Both views are used by another thread (postfix) to check if the recipient is an allowed one. When i try to do a simple query
SELECT email FROM emailview WHERE email = 'john#google.com'`
the query takes 3-4seconds. On the contrary if I do my SELECT directly on the email table (with duplicates in) it takes 0,01sec.
How could i improve the SELECT performances on my system to obtain almost similar result with a view and not directly on the table ?
Here is the detail of the architecture (INNODB Engine, value 1 is random and doesn't really matter) :
Domain Table :
| field | type | null | key |
|--------------|--------------|------|------|
| domain | varchar(255) | NO | NULL |
| creationdate | datetime | NO | NULL |
| value 1 | varchar(255) | NO | NULL |
| source_fkey | varchar(255) | MUL | NULL |
| domain | creationdate | value 1 | source_fkey |
|------------|---------------------|-----------------------|
| google.com | 2013-05-28 15:35:01 | john | Y |
| google.com | 2013-04-30 12:10:10 | patrick | X |
| yahoo.com | 2011-04-02 13:10:10 | britney | Z |
| ebay.com | 2012-02-12 10:48:10 | harry | Y |
| ebay.com | 2013-04-15 07:15:23 | bill | X |
Domain View (duplicate domain are removed using the oldest creation date) :
CREATE VIEW domainview AS
SELECT domain.domain, creationdate, value1, source_fkey
FROM domain
WHERE (domain, creationdate) IN (SELECT domain, MIN(creationdate)
FROM domain GROUP BY domain);
| domain | creationdate | value 1 | source_fkey |
|------------|---------------------|-----------------------|
| google.com | 2013-04-30 12:10:10 | patrick | X |
| yahoo.com | 2011-04-02 13:10:10 | britney | Z |
| ebay.com | 2012-02-12 10:48:10 | harry | Y |
Email table :
| field | type | null | key |
|--------------|--------------|------|------|
| email | varchar(255) | NO | NULL |
| source_fkey | varchar(255) | MUL | NULL |
| email | foreign_key |
|--------------------|-------------|
| john#google.com | X |
| john#google.com | Y | <-- duplicate from wrong foreign/domain
| harry#google.com | X |
| mickael#google.com | X |
| david#ebay.com | Y |
| alice#yahoo.com | Z |
Email View (legit emails and emails from domain/foreign_key of the domain view) :
CREATE VIEW emailview AS
SELECT email.email, email.foreign_key
FROM email, domainview
WHERE email.foreign_key = domainview.foreign_key
AND SUBSTRING_INDEX(email.email,'#',-1) = domainview.domain;
| email | foreign_key |
|--------------------|-------------|
| john#google.com | X |
| harry#google.com | X |
| mickael#google.com | X |
| david#ebay.com | Y |
| alice#yahoo.com | Z |
There is no unique, no indexes, the only primary key is in the table where the foreign_key is.
Thanks for help.
Previous discussion : Select without duplicate from a specific string/key
both queries are slow - first because of the subselect in the IN clause - which is not optimized until MySQL 5.6; the second because uses a function in the where clause.
In the first query you can replace the subselect with a join
In the second, it's best to store the domain in separate column and use it for comparision
Make sure you have composite indexes on the fields used in joins, where and group by clauses

mysql - select distinct mutually exclusive (based on another column's value) rows

First off, I would like to say that if after reading the question, anyone has a suggestion on a more informative title for this question, please tell me, as I think mine is somewhat lacking, now, on to business...
Given this table structure:
+---------+-------------------------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------+-------------------------------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| account | varchar(20) | YES | UNI | NULL | |
| domain | varchar(100) | YES | | NULL | |
| status | enum('FAILED','PENDING','COMPLETE') | YES | | NULL | |
+---------+-------------------------------------+------+-----+---------+----------------+
And this data:
+----+---------+------------------+----------+
| id | account | domain | status |
+----+---------+------------------+----------+
| 1 | jim | somedomain.com | COMPLETE |
| 2 | bob | somedomain.com | COMPLETE |
| 3 | joe | somedomain.com | COMPLETE |
| 4 | frank | otherdomain.com | COMPLETE |
| 5 | betty | otherdomain.com | PENDING |
| 6 | shirley | otherdomain.com | FAILED |
| 7 | tom | thirddomain.com | FAILED |
| 8 | lou | fourthdomain.com | COMPLETE |
+----+---------+------------------+----------+
I would like to select all domains which have a 'COMPLETE' status for all accounts (rows).
Any domains which have a row containing any value other then 'COMPLETE' for the status must not be returned.
So in the above example, My expected result would be:
+------------------+
| domain |
+------------------+
| somedomain.com |
| fourthdomain.com |
+------------------+
Obviously, I can achieve this by using a sub-query such as:
mysql> select distinct domain from test_table where status = 'complete' and domain not in (select distinct domain from test_table where status != 'complete');
+------------------+
| domain |
+------------------+
| somedomain.com |
| fourthdomain.com |
+------------------+
2 rows in set (0.00 sec)
This will work fine on our little mock-up test table, but in the real situation, the tables in question will be tens (or even hundreds) of thousands of rows, and I'm curious if there is some more efficient way to do this, as the sub-query is slow and intensive.
How about this:
select domain
from test_table
group by domain
having sum(case when status = 'COMPLETE'
then 0 else 1 end) = 0
I think this will work. Effectively just joins two basic queries together, then compares their count.
select
main.domain
from
your_table main
inner join
(
select
domain, count(id) as cnt
from
your_table
where
status = 'complete'
group by
domain
) complete
on complete.domain = main.domain
group by
main.domain
having
count(main.id) = complete.cnt
You should also ensure you have an index on domain as this relies on a join on that column.

Select followers and connections that they are not followers in MySQL

I have a complicated query to resolve and I don't know how to get the correct results. First of all, let me show you the tables I have:
+------------+
| users |
+------------+
| id |
| first_name |
| last_name |
+------------+
+--------------+
| clients |
+--------------+
| id |
| users_id |
| uid |
| access_token |
+--------------+
+---------------+
| users_follows |
+---------------+
| users_id |
| follow_id |
+---------------+
+-------------------+
| users_connections |
+-------------------+
| id |
| users_id |
| clients_id |
| uid |
| name |
+-------------------+
Our website uses Facebook Connect, so EACH user connected has a client UID (Facebook UID). For a functionality of the website I need a query that does the next: select all the the people you follow (users_id=ME) plus the users_connections but if a users_connection is also someone I follow do not include it on the final result. Finally, for this rows if it's a "following" I need users.first_name and users.last_name and if it's a connection NOT registered on our website I need users_connections.name.
I will have a lot of rows an probably people can have a lot of people who follow so a NOT IN and id's concatenated I think that it's not the best way to scale it.
Can anyone bring me some light?
Thank you in advance!