I have a table app_form_data_audit_trail which I need to join to another table app_fd_listofcomponents.
-The foreign key needs first to be extracted from a column collating some other data before getting the 1st table joined with the 2nd one.
-Some records from the first table needs to be filtered out.
I made the following sql query but getting error. I created a sqlfiddle here for troubleshooting purpose..
Thanks for your help :-)
SELECT DATETIME
,username
,CASE
WHEN locate('operation', DATA) > 0
THEN substring_index(substring_index(DATA, '"operation":"', - 1), '"', 1)
ELSE 0
END AS operation
,CASE
WHEN locate('operation', DATA) > 0
THEN substring_index(substring_index(DATA, '"opdetails":"', - 1), '"', 1)
ELSE 0
END AS opdetails
,CASE
WHEN locate('operation', DATA) > 0
THEN substring_index(substring_index(DATA, '"componentName":"', - 1), '"', 1)
ELSE 0
END AS componentid
,CASE
WHEN locate('operation', DATA) > 0
THEN substring_index(substring_index(DATA, '"package":"', - 1), '"', 1)
ELSE 0
END AS package
FROM app_form_data_audit_trail
WHERE DATA LIKE "%Operation%"
INNER JOIN app_fd_listofcomponents ON app_form_data_audit_trail.componentid = app_fd_listofcomponents.id
FROM app_form_data_audit_trail
INNER JOIN app_fd_listofcomponents ON app_form_data_audit_trail.componentid = app_fd_listofcomponents.id
WHERE DATA LIKE "%Operation%"
Thanks to all, Finally I came to write the query as follows and it works !
SELECT
app_form_data_audit_trail.datetime,
app_form_data_audit_trail.username,
app_form_data_audit_trail.data,
app_fd_listofcomponents.c_component,
substring_index(substring_index(app_form_data_audit_trail.data,'"operation":"',-1),'"',1) AS operation,
substring_index(substring_index(app_form_data_audit_trail.data,'"opdetails":"',-1),'"',1) AS opdetails,
substring_index(substring_index(app_form_data_audit_trail.data,'"package":"',-1),'"',1) AS package
FROM app_form_data_audit_trail
JOIN app_fd_listofcomponents
ON app_form_data_audit_trail.data LIKE CONCAT ('%',app_fd_listofcomponents.id,'%')
Related
I have taken reference from the internet about one user-defined function to locate 'nth occurrence of a string to do the sort column name in the database. I am using MySQL 5.5 version, not the latest version. Here is my sample database link https://dbfiddle.uk/?rdbms=mysql_5.5&fiddle=bcb32a6b47d0d5b061fd401d0888bdc3
My problem is I want to sort column name in the database follow the prefix number, but I am using below the SQL query, it doesn't work.
select t.id,t.name
from
(
select t.*, cast((case when col1_col2_ref > 0
then
substring_index(modified_name,'-',1)
else
modified_name
end
) as unsigned) col1
, cast((case when col1_col2_ref > 0
and col3_ref > 0
then
substr(modified_name,(col1_col2_ref + 1),(col3_ref - (col1_col2_ref + 1)))
when col1_col2_ref > 0
then
substr(modified_name,(col1_col2_ref + 1))
end) as unsigned) col2
, cast((case when col3_ref > 0
and col4_ref > 0
then
substr(modified_name,(col3_ref + 1),(col4_ref - (col3_ref + 1)))
when col3_ref > 0
then
substr(modified_name,(col3_ref + 1))
end) as unsigned) col3
, cast((case when col4_ref > 0
then
substr(modified_name,(col4_ref + 1))
end) as unsigned) col4
from
(
select t.*,substring_index(name,' ',1) modified_name
,locate('-',name,1) col1_col2_ref
,locate('/',name,1) col3_ref
,locate('/',name,locate('/',name,1)+1) col4_ref
from filing_code_management t
) t
) t
order by col1,col2,col3,col4
It shows me below the result, it cannot sort properly.
Output 1
Actually I want the output sample like below:
Output 2
Output 3
This is before I can sort the column name link, https://dbfiddle.uk/?rdbms=mysql_5.5&fiddle=6b12a4d42359cb30f27a5bfb9d0c8210. After I am inserted into new data, it cannot work for me. Maybe an example in new data like this error (R)100-6-2-2 Mesyuarat Majlis Kerajaan Negeri (MMKN) JKK if I put () in front. Or in new data like this error 100-1-1 Penggubalan/Penyediaan/Pindaan Undang-Undang/Peraturan if I put / in between the word.
Hope someone can guide me to solve this problem. Thanks.
You should be able to adapt the following code to your needs (tested at your DB Fiddle!). I've used the file_name column instead of the name column to slightly simplify building the sort fields, as it seems the file name is always repeated in the first part of the name field anyway.
This would be quite a bit simpler using regular expression support, but I note that the version of MySQL you are using doesn't have this feature (I think it arrives in SQL 8.0, if I'm not mistaken).
SELECT id,
num_hyphens,
CAST(SUBSTRING_INDEX(CONCAT(file_name_adj,'-'), '-', 1) AS UNSIGNED) AS sort1,
CAST(CASE WHEN num_hyphens = 0
THEN '0'
ELSE SUBSTRING_INDEX(SUBSTRING_INDEX(file_name_adj,'-', 2), '-',-1)
END AS UNSIGNED) AS sort2,
CAST(CASE WHEN num_hyphens <= 1
THEN '0'
ELSE SUBSTRING_INDEX(SUBSTRING_INDEX(file_name_adj,'-', 3), '-',-1)
END AS UNSIGNED) AS sort3,
CAST(CASE WHEN num_hyphens <= 2
THEN '0'
ELSE SUBSTRING_INDEX(file_name_adj, '-', -1)
END AS UNSIGNED) AS sort4,
file_name,
name
FROM (
SELECT id, name, MID(file_name, instr(file_name, ')') + 1) AS file_name_adj, file_name,
LENGTH(file_name) - LENGTH(REPLACE(file_name, '-', '')) AS num_hyphens
FROM filing_code_management
) t1
ORDER BY sort1, sort2, sort3, sort4
I am trying to add a FORMAT to my query, but when I run my query I get an error.
Here is my query:
SELECT CONCAT('€ ', COALESCE(SUM(r), 0) - COALESCE(SUM(l), 0)) as totaal
FROM trans
WHERE user_id = 1
AND k_id= 110
GROUP
BY user_id
LIMIT 0,1
I tried multiple statements:
(FORMAT(r)) and (FORMAT(l)) gives error
FORMAT(SUM(r), 0) - FORMAT(SUM(l), 0) gives wrong response
CONCAT(FORMAT('€ ', COALESCE(SUM(r), 0) - COALESCE(SUM(l), 0))) gives error
FORMAT(CONCAT('€ ', COALESCE(SUM(r), 0) - COALESCE(SUM(l), 0))) gives also error
Can someone help me with this statement?
format(X,D) takes a number as the first parameter and the decimal places as the second parameter so it should be put where the result is a number and provided with a number of decimal places:
CONCAT('€ ', FORMAT(COALESCE(SUM(r), 0) - COALESCE(SUM(l), 0),0))
This one is a bit of a nightmare. I'm working on frontend for an existing database,and I'm having to jump through hoops to make sure that data is displayed in the correct order. It'd make my life a whole lot simpler if I could just order by Id, but the Ids have little or no correlation to the data.
Here's what I mean
ID DATA
357 "7-1-5: Sensitive Information I can't share"
2521 "30-2-8-17: Yet more sensitive Information"
6002 "9-30: There's a 10 behind the colon, because I hate you"
8999 "2-2-4: This was populated in no particular order"
9001 "30-3: More Info."
I'm trying to get it ordered like this
ID DATA
0001 "2-2-4: This was populated in no particular order"
0002 "7-1-5: Sensitive Information I can't share"
0003 "9-30: There's a 10 behind the colon, because I hate you"
0004 "30-2-8-17: Yet more sensitive Information"
0005 "30-3: More Info."
Basically, I need it to sort by each 1 to 2 digit number that's separated by dashes, again and again, so that 1-3 comes after 1-2-1, which comes after 1-1-50.
Like I said in the beginning, I'm a frontend guy, so executing stuff in MySql is more than I can do alone. Any help would be immensely appreciated.
Edit: I just realized there's foreign keys in a separate table pointing to this one, making things just that much worse.
Try this query:
SELECT col
FROM yourTable
ORDER BY SUBSTRING(col, INSTR(col, '"') + 1, INSTR(col, ':') - INSTR(col, '"') - 1)
The SUBSTRING(...) term in the ORDER BY clause extracts just the ids from the text. Presumably you want them to sorted numerically, from left to right. Even though they are varchar, numerical sorting should still work.
For your sample data, this produced the following output:
ID 8999 DATA "2-2-4: This was populated in no particular order"
ID 2521 DATA "30-2-8-17: Yet more sensitive Information"
ID 357 DATA "7-1-5: Sensitive Information I can't share"
ID 6002 DATA "9-30: There's a 10 behind the colon, because I hate you"
Fiddle is down as of the writing of this answer, but I tested the query in MySQL Workbench and it seems to work well.
Edit:
If you want to assign a new ID to each record, you create a new table (newTable) with an ID column which is auto increment. Then you can use INSERT INTO ... SELECT along with the above ORDER BY logic to populate the table. The ID field should be incremented automatically by MySQL.
INSERT INTO newTable (`id`, `col`)
SELECT NULL, col
FROM yourTable
ORDER BY SUBSTRING(col, INSTR(col, '"') + 1, INSTR(col, ':') - INSTR(col, '"') - 1)
Something like this should work, but it is very delicate; all the fields calculated in the outer SELECT (after the *) must be performed in that exact order. Note that the calculations aliased nl#, p#, and r# (except r0) repeat exactly... so the query is not as complicated as it initially appears.
SELECT *
, #r := dataOrd AS r0 -- #r is "remaining string"
, #nextSep := INSTR(#r, '-') AS nl1
, CAST(CASE #nextSep WHEN 0 THEN #r ELSE SUBSTR(#r, 1, #nextSep-1) END AS UNSIGNED) AS p1
, #r := CASE #nextSep WHEN 0 THEN '' ELSE SUBSTRING(#r, #nextSep+1) END AS r1
, #nextSep := INSTR(#r, '-') AS nl2
, CAST(CASE #nextSep WHEN 0 THEN #r ELSE SUBSTR(#r, 1, #nextSep-1) END AS UNSIGNED) AS p2
, #r := CASE #nextSep WHEN 0 THEN '' ELSE SUBSTRING(#r, #nextSep+1) END AS r2
, #nextSep := INSTR(#r, '-') AS nl3
, CAST(CASE #nextSep WHEN 0 THEN #r ELSE SUBSTR(#r, 1, #nextSep-1) END AS UNSIGNED) AS p3
, #r := CASE #nextSep WHEN 0 THEN '' ELSE SUBSTRING(#r, #nextSep+1) END AS r3
, #nextSep := INSTR(#r, '-') AS nl4
, CAST(CASE #nextSep WHEN 0 THEN #r ELSE SUBSTR(#r, 1, #nextSep-1) END AS UNSIGNED) AS p4
, #r := CASE #nextSep WHEN 0 THEN '' ELSE SUBSTRING(#r, #nextSep+1) END AS r4
FROM
(
SELECT *, SUBSTR(`DATA`, 1, INSTR(`DATA`, ':') - 1) AS dataOrd
FROM yourTable
) AS sepSubQ
ORDER BY p1, p2, p3, p4
;
Technically, the last #r assignment (aliased r4) is unnecessary, but it completes the pattern that will be need to be repeated if you need to handle more than 4 ordering "parts"; in which case you just need to repeat the last three field calculations (with incremented aliases).
If you want to be rid of the "working" fields, you can wrap this in another outer query only selects the fields from the original table you wanted and the pX fields from the above query; technically, you don't even need to select the pX fields as the order will already be performed by this query, or can be done in the wrapper without selecting them.
SELECT `ID`, `DATA`
FROM ([the query above]) AS subQ
ORDER BY p1, p2, p3, p4
;
I have a table with Boolean values (0 and 1 only) that needs to be CSV-ed to a client. I know I can do 1 replace like this:
SELECT REPLACE(email, '%40', '#'),
REPLACE(name,'%20', ' '),
REPLACE(icon_clicked, 1, 'Yes')
FROM myTable
WHERE id > 1000;
This will convert all the values of 1 to 'Yes', but how to do this in a single query for both 1 => Yes and 0 => No so Boolean result is stored in a single column? I tried to do this:
SELECT REPLACE(email, '%40', '#'),
REPLACE(name,'%20', ' '),
REPLACE(icon_clicked, 1, 'Yes'),
REPLACE(icon_clicked, 0, 'No')
FROM myTable
WHERE id > 1000;
But this query created an additional column for the 'No' string replace (so final result had 4 columns, email, name, icon_clicked->yes, icon_clicked->no)
One way is to nest REPLACE:
SELECT REPLACE(REPLACE(icon_clicked, 0, 'No'), 1, 'Yes')), ...
FROM myTable
...
or use CASE WHEN (this will work for most RDBMS comparing to IF function which is MySQL related):
SELECT CASE WHEN icon_clicked THEN 'Yes' ELSE 'No' END, ...
FROM myTable
...
SqlFiddleDemo
EDIT:
There is also one nice way utilizing ELT:
SELECT icon_clicked,
ELT(FIELD(icon_clicked,0,1),'No','Yes'),
ELT(icon_clicked + 1, 'No', 'Yes')
FROM mytable
SqlFiddleDemo2
No need to use nested Replace or Case statement. Try using IF, which is way simpler
SELECT
icon_clicked,
IF(icon_clicked,'Yes','No')
FROM myTable
SQL FIDDLE DEMO
I am trying to populate a table with phone number from a temp table. I have wrote the query with no problem. but my peoblem here is to know if the company already has a primary number or not
so I select 2 fields from my temp table called "cvsnumbers" 1) company_code (id) and the phone number.
I need to add a case statement to change the value of a main_number field. so if the number already has a number with main_number = 1 then I need to insert 0 for the new phone number but if there is no main_number then I need to insert 1 for the new phone number making it a primary phone number for the account.
this is my query
SELECT ac.account_id,
REPLACE(REPLACE(REPLACE(REPLACE(ta.phone_number, '-', ''), ' ', ''), ')', ''),'(','') AS Phone,
IFNULL(ta.ext, '') AS extention,
IFNULL(ta.main_number, 0) AS MainNumber,
ta.type AS contact_type,
'2' AS created_by
FROM cvsnumbers AS ta
INNER JOIN accounts AS ac ON ac.account_id = ta.company_code
WHERE LENGTH(REPLACE(REPLACE(REPLACE(REPLACE(ta.phone_number, '-', ''), ' ', ''), ')', ''),'(','') ) = 10
AND REPLACE(REPLACE(REPLACE(REPLACE(ta.phone_number, '-', ''), ' ', ''), ')', ''),'(','') NOT IN (SELECT contact_number FROM contact_numbers)
My issue is
`IFNULL(ta.main_number, 0) AS MainNumber,`
I want to change that to some what a case statment to check if a company_code already has a main_number or not.
How can I change this?
Thanks
I am still not sure exactly how your query should look like, but how about something along theese lines?
SELECT CASE
WHEN EXISTS (SELECT *
FROM contact_numbers
WHERE main_number = 1
AND contact_number =
<insert contact number from outer expression here>)
THEN 1
ELSE 0
END AS MainNumber
FROM ...