I have a table and its data are mentioned below :
id | function
1 | current_date
2 | UUID()
3 | RAND()
Structure of the table is
id int, function varchar(50)
Query : select * from func_table;
My excepted result is
id | function
1 | 2020-08-24
2 | 70d6cffc-ae01-11ea-80ca-c11529136ae3630
3 | 0.982584554752
Thanks in advance.
You can use a giant case expression:
select (case when function = 'current_date' then cast(current_date as char)
when function = 'uuid()' then cast(uuid as char)
when function = 'rand()' then cast(rand as char)
end) as value
If you actually want to evaluate the function directly, then you probably have a problem with your data model. SQL does not directly support such functionality.
Related
Basicly this is my mysql query:
select distinct(shipment_tag) from ir_shipment_registry where shipment_id = '2020111'
and the result set:
| shipment_tag |
+--------------+
| Truck |
| Equipment |
| |
How can I concat the two result set into string so that i can assign it to a variable? I tried
SET #purchasetype = (select distinct(shipment_tag) from ir_shipment_registry where shipment_id = '2020111')
but it returns and error says: Subquery returns more than 1 row.
I want something in my variable like : #purchasetype = "Truck, Equipment".
Perhaps use GROUP_CONCAT here:
SET #purchasetype = (SELECT GROUP_CONCAT(shipment_tag SEPARATOR ', ') FROM ir_shipment_registry WHERE shipment_id = '2020111');
I want to delete everything after "x" in the following urls :
i have :
url
/product/dtphdmi230rx?subtype=384
/product/dtphdmi230tx?subtype=385
/product/dtphdmi330rx?subtype=386
/product/dtphdmi330tx?subtype=387
i want :
url
/product/dtphdmi230rx
/product/dtphdmi230tx
/product/dtphdmi330rx
/product/dtphdmi330tx
I know it's easy with mysql 8.0 with regex_replace but i can't update my server. Is there any way with mysql 5 ?
nb : There is always a "?" in urls, it can be the first character to delete.
Thanks for help
Just:
left(url, locate('x?', url))
Demo on DB Fiddle:
with mytable as (
select '/product/dtphdmi230rx?subtype=384' url
union all select '/product/dtphdmi230tx?subtype=385'
union all select '/product/dtphdmi330rx?subtype=386'
union all select '/product/dtphdmi330tx?subtype=387'
)
select left(url, locate('x?', url)) from mytable
| left(url, locate('x?', url)) |
| :--------------------------- |
| /product/dtphdmi230rx |
| /product/dtphdmi230tx |
| /product/dtphdmi330rx |
| /product/dtphdmi330tx |
Note: as commented by Raymond Nijland, if the ? occurs just once in the string and can be used as the first character to remove, you can also do:
left(url, locate('?', url) - 1)
I am new to mysql, here i am trying to get data from database table.
select id,txnid,amount,status from txn_details;
With above query Getting data successfully but status column getting 0 or 1 or 2, but i want 0 as failed, 1 as success and 2 as not processed.
How to change my query?
You can use a case
select id, txnid, amount,
case when status = 0 then 'failed'
when status = 1 then 'success'
else 'not processed'
end as status
from txn_details;
We can use an expression in the SELECT list. It could be a searched CASE expression e.g.
SELECT CASE t.status
WHEN 0 THEN 'failed'
WHEN 1 THEN 'success'
WHEN 2 THEN 'not processed'
ELSE 'unknown'
END AS status_name
, t.status
, t.amount
, t.txnid
FROM txn_details t
This approach is ANSI-92 standards compliant, and will work in most relational databases.
There are some other MySQL specific alternatives, such as the ELT function ...
SELECT ELT(t.status+1,'failed','success','not processed') AS status_name
, t.status
, t.amount
, t.txnid
FROM txn_details t
https://dev.mysql.com/doc/refman/5.7/en/string-functions.html#function_elt
If you prefer a central point of maintenance (ie you prefer not to recode all your queries when a new status comes along) you could create a status table and either use a join or sub query to get the values, alternatively you could create a function, for example
drop table if exists txn_details,txn_status;
create table txn_details(id int, txnid int, amount int , status int);
insert into txn_details values
(1,1,10,1),(2,1,10,2),(3,1,10,4);
create table txn_status (id int, statusval varchar(20));
insert into txn_status values
(1,'success'),(2,'not processed'), (3,'failed');
drop function if exists f;
delimiter $$
create function f(instatus int)
returns varchar(20)
begin
declare rval varchar(20);
return (select
case when instatus = 1 then 'success'
when instatus = 2 then 'not processed'
when instatus = 3 then 'failed'
else 'Unknown'
end
);
select t.*,coalesce(ts.statusval,'Unknown') status
from txn_details t
left join txn_status ts on ts.id = t.status;
select t.*,coalesce((select statusval from txn_status ts where ts.id = t.status),'Unknown') status
from txn_details t;
Note the use of coalesce in case a status is not found.
Both produce this result
+------+-------+--------+--------+---------------+
| id | txnid | amount | status | status |
+------+-------+--------+--------+---------------+
| 1 | 1 | 10 | 1 | success |
| 2 | 1 | 10 | 2 | not processed |
| 3 | 1 | 10 | 4 | Unknown |
+------+-------+--------+--------+---------------+
3 rows in set (0.00 sec)
Using the function like this
select t.*, f(status) as status
from txn_details t;
also produces the same result.
Of course using a status table or a function means you have to communicate their availability and enforce their use.
I would also consider the using a foreign key constraint in txn_details to cut down on the number of unknown values and put procedures in place to stop people adding new status codes at will without going through change control
The following query would work. It uses CASE ... END to determine and return values for the virtual column status.
SELECT id,txnid,amount,
CASE
WHEN status = 0 THEN 'failed'
WHEN status = 1 THEN 'success'
WHEN status= 2 THEN 'not processed'
END AS status
FROM txn_details;
It seems when I am trying to make a query to get the users transaction sum, it does not return the proper value until I remove the filter on code, what is even more interesting is the filter on the bar code following works perfectly fine, it seems maybe there is an inconsistency between both the subqueries in the WHERE clause?
Explanation:
With the below query, when I remove the and code != "foo" AND code !="foobar" from the query, it returns the correct value, but I also tried changing it to code = "foo" or code = "foobar" to check if any of the results had these codes, and it returns null when I do this.
SELECT SUM(t.amount)
FROM transactions t
WHERE `t`.`deleted_at` IS NULL
AND `t`.`user_id` = 80
AND `t`.`user_id` IS NOT NULL
AND `manually_deleted_at` IS NULL
AND
(SELECT count(*)
FROM `transaction_subcategories` s
WHERE `t`.`transaction_subcategory_id` = `s`.`id`
AND `code` != "foo"
AND `code` != "foobar"
AND
(SELECT count(*)
FROM `transaction_categories` c
INNER JOIN `transaction_categories_transaction_subcategories` sc ON `c`.`id` = `sc`.`transaction_category_id`
WHERE `sc`.`transaction_subcategory_id` = `s`.`id`
AND `code` = "bar") >= 1) >= 1
AND `posted_date` BETWEEN "2016-04-01 00:00:00.000000" AND "2017-03-31 23:59:59.000000"
AND `parent_id` = 0;
While I do realize this is a mysql query issue, the laravel ORM code is a bit cleaner:
$income_transactions = \Auth::user ()->transactions ()
->notManuallyDeleted()
->whereHas('transactionSubcategory', function ($query) {
$query
->where('code', '!=', 'foo')
->where('code', '!=', 'foobar')
->whereHas('transactionCategories', function ($query2){
$query2->where('code', '=', 'bar');
});
})
->whereBetween ( 'posted_date', [$from,$to])
->where('parent_id', '=', 0)
->get ();
Update
Not sure if this helps, but I did a query to see which subcategories it is returning with the WHERE clause and it returns only ones where the code is NULL
mysql> SELECT * FROM transaction_subcategories WHERE id in ('1125', '630', '1395') AND code is null;
+------+-----------------------------------+------+---------+
| id | name | code | user_id |
+------+-----------------------------------+------+---------+
| 630 | foo | NULL | 80 |
| 1125 | foo | NULL | 80 |
| 1395 | foo | NULL | 80 |
+------+-----------------------------------+------+---------+
Update 2 Turns out it is the WHERE doing it, it seems that NULL values won't be compared against a string, in other words if I do a WHERE on a column that has nulls, the null value rows will disappear
Answer Turns out adding OR code is null in a group in the WHERE clause was all I needed. Closed :)
I recently recoded one of my sites, and the database structure is a little bit different.
I'm trying to convert the following:
*----*----------------------------*
| id | file_name |
*----*----------------------------*
| 1 | 1288044935741310953434.jpg |
*----*----------------------------*
| 2 | 1288044935741310352357.rar |
*----*----------------------------*
Into the following:
*----*----------------------------*
| id | file_name |
*----*----------------------------*
| 1 | 1288044935741310953434 |
*----*----------------------------*
| 2 | 1288044935741310352357 |
*----*----------------------------*
I know that I could do a foreach loop with PHP, and explode the file extension off the end, and update each row that way, but that seems like way too many queries for the task.
Is there any SQL query that I could run that would allow me to remove the file exentision from each field in the file_name column?
You can use the REPLACE() function in native MySQL to do a simple string replacement.
UPDATE tbl SET file_name = REPLACE(file_name, '.jpg', '');
UPDATE tbl SET file_name = REPLACE(file_name, '.rar', '');
This should work:
UPDATE MyTable
SET file_name = SUBSTRING(file_name,1, CHAR_LENGTH(file_name)-4)
This will strip off the final extension, if any, from file_name each time it is run. It is agnostic with respect to extension (so you can have ".foo" some day) and won't harm extensionless records.
UPDATE tbl
SET file_name = TRIM(TRAILING CONCAT('.', SUBSTRING_INDEX(file_name, '.', -1) FROM file_name);
You can use SUBSTRING_INDEX function
SUBSTRING_INDEX(str,delim,count)
Where str is the string, delim is the delimiter (from which you want a substring to the left or right of), and count specifies which delimiter (in the event there are multiple occurrences of the delimiter in the string)
Example:
UPDATE table SET file_name = SUBSTRING_INDEX(file_name , '.' , 1);