Delete Only First Zero in Column - mysql

ch.value values 00 , 01 , 02 , 03.
It must be 0 , 1 , 2 , 3.
I'am using this code :
Concat_ws('_', ch.prop, Trim(LEADING '0' FROM ch.value))
This code does not work at 00 case , how can i fix it ?

You can use below condition:
Concat_ws('_', ch.prop, case when left(ch.value,1)='0' then substring(ch.value,2) end)

Related

cannot pass more than 100 arguments to a function to json_build_object

cannot pass more than 100 arguments to a function to json_build_object, trying to build json from columns of a table.but it is giving me error that cannot pass more than 100 arguments, but argument count not exceeded 100.
code as follows:
array_agg(json_build_object
(
'QuotaName',quota_name,
'QuotaId',quota_id,
'CellId',COALESCE(cell_id,0),
'ValidPanelistCountOtherMedias',COALESCE(valid_panelist_count,0) ,
'ValidPanelistCountMM',COALESCE(mm_valid_panelist_count,0) ,
'Gender',COALESCE(replace(replace(replace(gender,',',':'),']',''),'[',''),''),
'Occupation',COALESCE(replace(replace(replace(occupation_id,',',':'),']',''),'[',''),''),
'Industry',COALESCE(replace(replace(replace(industry_id,',',':'),']',''),'[',''),''),
'Prefecture',COALESCE(replace(replace(replace(prefecture_id,',',':'),']',''),'[',''),''),
'Age1',COALESCE(replace(replace(replace(age,',',':'),']',''),'[',''),''),
'Age2',COALESCE(replace(replace(replace(age2,',',':'),']',''),'[',''),''),
'MaritalStatus',COALESCE(replace(replace(replace(marital_status,',',':'),']',''),'[',''),''),
'HouseHoldIncome',COALESCE(replace(replace(replace(house_income_id,',',':'),']',''),'[',''),''),
'PersonalIncome',COALESCE(replace(replace(replace(personal_income_id,',',':'),']',''),'[',''),''),
'hasChild',COALESCE(replace(replace(replace(has_child,',',':'),']',''),'[',''),''),
'MediaId',COALESCE(replace(replace(replace(media_id,',',':'),']',''),'[',''),''),
'DeviceUsed',COALESCE(replace(replace(replace(device_type,',',':'),']',''),'[',''),''),
'PanelistStatus','',
'IR1', COALESCE(ir_1,1) ,
'IR2', COALESCE(ir_2,1) ,
'IR3', COALESCE(ir_3,1) ,
'Population',COALESCE(population,0),
'MainSurveySampleHopes', COALESCE(sample_hope_main_survey,0) ,
'ScreeningSurveySampleHopes', COALESCE(sample_hope_main_scr,0),
'ParticipateIntentionMM' ,COALESCE(participate_intention_mm,0) ,
'ParticipateIntentionOthers' ,COALESCE(participate_intention,0) ,
'AcquisitionRate', COALESCE(acquisition_rate,0) ,
'PCEnvironment', COALESCE(case when survey_type >3 then 1 else pc_env end,0) ,
'NetworkEnvironment',COALESCE(case when survey_type >3 then 1 else network_env end,0) ,
'PCEnvironmentMM',COALESCE(case when survey_type >3 then 1 else pc_env_mm end,0),
'NetworkEnvironmentMM',COALESCE(case when survey_type >3 then 1 else network_env_mm end,0) ,
'ControlQuotient',COALESCE(control_quotient,0)/100 ,
'ResponseofSCR24' , COALESCE(res_of_scr_24,0),
'ResponseofSCR48' ,COALESCE(res_of_scr_48,0) ,
'ResponseofSCR72' ,COALESCE(res_of_scr_72,0) ,
'ResponseofSCR168' ,COALESCE(res_of_scr_168,0),
'ResponseofMAIN24' ,COALESCE(res_of_main_24,0) ,
'ResponseofMAIN48' , COALESCE(res_of_main_48,0) ,
'ResponseofMAIN72' , COALESCE(res_of_main_72,0) ,
'ResponseofMAIN168' , COALESCE(res_of_main_168,0),
'ResponseofSCR24MM' ,COALESCE(res_of_scr_24_mm,0) ,
'ResponseofSCR48MM' , COALESCE(res_of_scr_48_mm,0),
'ResponseofSCR72MM' , COALESCE(res_of_scr_72_mm,0) ,
'ResponseofSCR168MM' ,COALESCE(res_of_scr_168_mm,0) ,
'ResponseofMAIN24MM' ,COALESCE(res_of_main_24_mm,0),
'ResponseofMAIN48MM' ,COALESCE(res_of_main_48_mm,0),
'ResponseofMAIN72MM' ,COALESCE(res_of_main_72_mm,0),
'ResponseofMAIN168MM' ,COALESCE(res_of_main_168_mm,0),
'ResponseofMAINIntegrationType',0.9,-- this value is based on answer_estimate_list_details_v3
'ParticipationIntention',COALESCE(participate_intention,0),
'MostRecentParticipation',COALESCE(most_recent_exclusions,0)
I had the exact same problem earlier today. After some research, I found that JSONB results can be concatenated. So you should use JSONB_BUILD_OBJECT instead of JSON_BUILD_OBJECT. Then, split things up so you have multiple JSONB_BUILD_OBJECT calls, which are combined with '||'. You'll also need JSONB_AGG for converting the results into an array.
JSONB_AGG(
JSONB_BUILD_OBJECT (
'QuotaName',quota_name,
'QuotaId',quota_id,
'CellId',COALESCE(cell_id,0),
'ValidPanelistCountOtherMedias',COALESCE(valid_panelist_count,0) ,
'ValidPanelistCountMM',COALESCE(mm_valid_panelist_count,0) ,
'Gender',COALESCE(replace(replace(replace(gender,',',':'),']',''),'[',''),''),
'Occupation',COALESCE(replace(replace(replace(occupation_id,',',':'),']',''),'[',''),''),
'Industry',COALESCE(replace(replace(replace(industry_id,',',':'),']',''),'[',''),''),
'Prefecture',COALESCE(replace(replace(replace(prefecture_id,',',':'),']',''),'[',''),''),
'Age1',COALESCE(replace(replace(replace(age,',',':'),']',''),'[',''),''),
'Age2',COALESCE(replace(replace(replace(age2,',',':'),']',''),'[',''),''),
'MaritalStatus',COALESCE(replace(replace(replace(marital_status,',',':'),']',''),'[',''),''),
'HouseHoldIncome',COALESCE(replace(replace(replace(house_income_id,',',':'),']',''),'[',''),''),
'PersonalIncome',COALESCE(replace(replace(replace(personal_income_id,',',':'),']',''),'[',''),''),
'hasChild',COALESCE(replace(replace(replace(has_child,',',':'),']',''),'[',''),''),
'MediaId',COALESCE(replace(replace(replace(media_id,',',':'),']',''),'[',''),''),
'DeviceUsed',COALESCE(replace(replace(replace(device_type,',',':'),']',''),'[',''),''),
'PanelistStatus','',
'IR1', COALESCE(ir_1,1) ,
'IR2', COALESCE(ir_2,1) ,
'IR3', COALESCE(ir_3,1) ,
'Population',COALESCE(population,0),
'MainSurveySampleHopes', COALESCE(sample_hope_main_survey,0) ,
'ScreeningSurveySampleHopes', COALESCE(sample_hope_main_scr,0),
'ParticipateIntentionMM' ,COALESCE(participate_intention_mm,0) ,
'ParticipateIntentionOthers' ,COALESCE(participate_intention,0) ,
'AcquisitionRate', COALESCE(acquisition_rate,0) ,
'PCEnvironment', COALESCE(case when survey_type >3 then 1 else pc_env end,0) ,
'NetworkEnvironment',COALESCE(case when survey_type >3 then 1 else network_env end,0) ,
'PCEnvironmentMM',COALESCE(case when survey_type >3 then 1 else pc_env_mm end,0),
'NetworkEnvironmentMM',COALESCE(case when survey_type >3 then 1 else network_env_mm end,0) ,
'ControlQuotient',COALESCE(control_quotient,0)/100 ,
'ResponseofSCR24' , COALESCE(res_of_scr_24,0),
'ResponseofSCR48' ,COALESCE(res_of_scr_48,0) ,
'ResponseofSCR72' ,COALESCE(res_of_scr_72,0) ,
'ResponseofSCR168' ,COALESCE(res_of_scr_168,0),
'ResponseofMAIN24' ,COALESCE(res_of_main_24,0) ,
'ResponseofMAIN48' , COALESCE(res_of_main_48,0) ,
'ResponseofMAIN72' , COALESCE(res_of_main_72,0) ,
'ResponseofMAIN168' , COALESCE(res_of_main_168,0),
'ResponseofSCR24MM' ,COALESCE(res_of_scr_24_mm,0) ,
'ResponseofSCR48MM' , COALESCE(res_of_scr_48_mm,0),
'ResponseofSCR72MM' , COALESCE(res_of_scr_72_mm,0) ,
'ResponseofSCR168MM' ,COALESCE(res_of_scr_168_mm,0) ,
'ResponseofMAIN24MM' ,COALESCE(res_of_main_24_mm,0),
'ResponseofMAIN48MM' ,COALESCE(res_of_main_48_mm,0),
'ResponseofMAIN72MM' ,COALESCE(res_of_main_72_mm,0),
'ResponseofMAIN168MM' ,COALESCE(res_of_main_168_mm,0)
) ||
JSONB_BUILD_OBJECT (
'ResponseofMAINIntegrationType',0.9,-- this value is based on answer_estimate_list_details_v3
'ParticipationIntention',COALESCE(participate_intention,0),
'MostRecentParticipation',COALESCE(most_recent_exclusions,0)
)
)
I got this from documentation here - https://www.postgresql.org/docs/current/functions-json.html#FUNCTIONS-JSONB-OP-TABLE
Look for "jsonb || jsonb"

SQL: select between delimiters with delimiters itself, insert in other column and delete string

Instead of having one column for each group of values, I made one column named "data" and used HTML like this:
<dt>Phone:</dt><dd>0 23 16/3 82 73 42 23</dd>
<dt>Phone:</dt><dd>0 21 61/81 26 73 13 22</dd>
<dt>Fax:</dt><dd>03 27/3 87 42 37 32</dd>
<dt>Website:</dt><dd>www.example.com</dd>
Now, I recognized, that wasn't very clever and I made a column for each value. My new columns names are "phone", "phone2", "fax" and "website".
I need an SQL code for e.g. selecting all between the delimiters <dt>Phone:</dt><dd> and </dd> and the delimiters itself, insert this string in the column "phone" and delete this string in the "data" column.
But I need to select the first string <dt>Phone:</dt><dd>0 23 16/3 82 73 42 23</dd> not the second <dt>Phone:</dt><dd>0 21 61/81 26 73 13 22</dd>.
Can anybody give me a hint how to do that?
For selecting data between <dt>Phone:</dt><dd> and </dd> you can use SUBSTRING_INDEX.
Like this
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(data, '</dd>', 1), '<dt>Phone:</dt><dd>', -1) as phone,
SUBSTRING_INDEX(SUBSTRING_INDEX(data, '<dt>Phone:</dt><dd>', -1), '</dd>', 1) as phone2,
SUBSTRING_INDEX(SUBSTRING_INDEX(data, '<dt>Fax:</dt><dd>', -1), '</dd>', 1) as fax,
SUBSTRING_INDEX(SUBSTRING_INDEX(data, '<dt>Website:</dt><dd>', -1), '</dd>', 1) as website
from data_col;
Update:
<dt>Phone:</dt> is not always in top.
in case if there is no specified order of data in "data" column, try this one:
SELECT
IF (temp.f_phone > 0, SUBSTR(data, temp.f_phone + LENGTH('<dt>Phone:</dt><dd>'), f_phone_end - temp.f_phone - LENGTH('<dt>Phone:</dt><dd>')), null) as PHONE_1,
IF (temp.s_phone > 0, SUBSTR(data, temp.s_phone + LENGTH('<dt>Phone:</dt><dd>'), s_phone_end - temp.s_phone - LENGTH('<dt>Phone:</dt><dd>')), null) as PHONE_2
from data_col dc
JOIN (
SELECT id, #f_phone:= LOCATE('<dt>Phone:</dt><dd>', data) as f_phone,
LOCATE('</dd>', data, #f_phone+1) f_phone_end,
#s_phone := LOCATE('<dt>Phone:</dt><dd>', data, #f_phone+1) as s_phone,
LOCATE('</dd>', data, #s_phone+1) as s_phone_end
from data_col) temp ON temp.id = dc.id;
First find the starting position of each possible element (e.g. "phone" "phone2") and a position of closing tag <\dd>. And than use SUBSTR from starting position of element + length of delimiter, with length = end_position - start_position - delimiter_length

How to make field act like a table

Sorry but I couldn't find/search for specific "thing"
so.
I have tables
users(id , name , kills , .... ) ;
quests( id , name , description , enemy_id , n_to_kill , en_killed , used_id );
what I want to achieve is for all users to have separate quests table.
I don't understand how it's possible but I think it should be(?)
example:
users:{ 1 , admin , 7 } { 2 , user , 11 } { 3 , john , 0 }
quests:{ 1 , "killall" , "kill all" , 0 , 100 , 0 , ??}
so to save for each user how many quests he finished/killed x out of y
Is it even possible?
Thanks for reading...

how to create an sql view based on calculated vales?

Hie lets assume we have the following table
TABLE NAME : DRINGE
__________________________________________________
ID PRODUCT MACHINE MASS STATE
01 1.76ann HRB 50 inlet
02 1.76ann HRB 38 inlet
03 2.55ann GUDO 45 outlet
04 95mm x 4 GUDO 36 dispatched
___________________________________________________
And the following formula:
(inlet –outlet ) +outlet – dispatched = [resulted displayed to new view]
And the values to be substituted are:
INLET = 50 , 38
OUTLET=45
DISPATCHED = 36
So substituting in the above formula
[(inlet –outlet ) +outlet – dispatched = [resulted displayed to new view]
We get this
(50+38 – 45 ) + 45 – 36 = 52
What I want is for the result ie 52 to be displayed in an sql view like the following view
Dringe VIEW
_____________
Total_summary|
_____________|
52 |
_____________|
.
Does anyone have any idea of an sql query I can use to do this ?
I rily need your help am stuck again, thanx in advance.
The below will follow your formula
CREATE VIEW DRINGEView AS
SELECT sum(case when state = 'inlet' then mass else 0 end) -
sum(case when state = 'outlet' then mass else 0 end)+
sum(case when state = 'outlet' then mass else 0 end) -
sum(case when state = 'dispatched' then mass else 0 end) AS Total_summary
FROM dringe
But adding outlet then subtracting outlet would be redundant. The brackets in your formula would also be redundant as all of your operators are addition/subtraction, could one of your operators be multiplication/division?
you can just add those calculations to your query in something like
(40+50+fieldName*anotherFieldName) AS calculation
and you can even use sub tables like
(40+50+(SELECT fieldName FROM anotherTable WHERE someValue) AS calculation
create view dringe_view as
select (sum(inlet) – sum(outlet) ) +sum(outlet) – sum(dispatched ) as total_summary
from tab
But your claculation can be further simplified (remove outlet - outlet) to (inlet – dispatched)

MySQL order by string with numbers

I have strings such as M1 M3 M4 M14 M30 M40 etc (really any int 2-3 digits after a letter)
When I do " ORDER BY name " this returns:
M1, M14, M3, M30, M4, M40
When I want:
M1, M3, M4, M14, M30, M40
Its treating the whole thing as a string but I want to treat it as string + int
Any ideas?
You could use SUBSTR and CAST AS UNSIGNED/SIGNED within ORDER BY:
SELECT * FROM table_name ORDER BY
SUBSTR(col_name FROM 1 FOR 1),
CAST(SUBSTR(col_name FROM 2) AS UNSIGNED)
If there can be multiple characters at the beginning of the string, for example like 'M10', 'MTR10', 'ABCD50', 'JL8', etc..., you basically have to get the substring of the name from the first position of a number.
Unfortunately MySQL does not support that kind of REGEXP operation (only a boolean value is returned, not the actual match).
You can use this solution to emulate it:
SELECT name
FROM tbl
ORDER BY CASE WHEN ASCII(SUBSTRING(name,1)) BETWEEN 48 AND 57 THEN
CAST(name AS UNSIGNED)
WHEN ASCII(SUBSTRING(name,2)) BETWEEN 48 AND 57 THEN
SUBSTRING(name,1,1)
WHEN ASCII(SUBSTRING(name,3)) BETWEEN 48 AND 57 THEN
SUBSTRING(name,1,2)
WHEN ASCII(SUBSTRING(name,4)) BETWEEN 48 AND 57 THEN
SUBSTRING(name,1,3)
WHEN ASCII(SUBSTRING(name,5)) BETWEEN 48 AND 57 THEN
SUBSTRING(name,1,4)
WHEN ASCII(SUBSTRING(name,6)) BETWEEN 48 AND 57 THEN
SUBSTRING(name,1,5)
WHEN ASCII(SUBSTRING(name,7)) BETWEEN 48 AND 57 THEN
SUBSTRING(name,1,6)
WHEN ASCII(SUBSTRING(name,8)) BETWEEN 48 AND 57 THEN
SUBSTRING(name,1,7)
END,
CASE WHEN ASCII(SUBSTRING(name,1)) BETWEEN 48 AND 57 THEN
CAST(SUBSTRING(name,1) AS UNSIGNED)
WHEN ASCII(SUBSTRING(name,2)) BETWEEN 48 AND 57 THEN
CAST(SUBSTRING(name,2) AS UNSIGNED)
WHEN ASCII(SUBSTRING(name,3)) BETWEEN 48 AND 57 THEN
CAST(SUBSTRING(name,3) AS UNSIGNED)
WHEN ASCII(SUBSTRING(name,4)) BETWEEN 48 AND 57 THEN
CAST(SUBSTRING(name,4) AS UNSIGNED)
WHEN ASCII(SUBSTRING(name,5)) BETWEEN 48 AND 57 THEN
CAST(SUBSTRING(name,5) AS UNSIGNED)
WHEN ASCII(SUBSTRING(name,6)) BETWEEN 48 AND 57 THEN
CAST(SUBSTRING(name,6) AS UNSIGNED)
WHEN ASCII(SUBSTRING(name,7)) BETWEEN 48 AND 57 THEN
CAST(SUBSTRING(name,7) AS UNSIGNED)
WHEN ASCII(SUBSTRING(name,8)) BETWEEN 48 AND 57 THEN
CAST(SUBSTRING(name,8) AS UNSIGNED)
END
This will order by the character part of the string first, then the extracted number part of the string as long as there are <=7 characters at the beginning of the string. If you need more, you can just chain additional WHENs to the CASE statement.
I couldn't get this working for my issue which was sorting MLS Numbers like below:
V12345
V1000000
V92832
The problem was V1000000 wasn't being valued higher than the rest even though it's bigger.
Using this solved my problem:
ORDER BY CAST(SUBSTR(col_name FROM 2) AS UNSIGNED) DESC
Just removed the SUBSTR(col_name FROM 1 FOR 1)
You can use:
order by name,SUBSTRING(name,1,LENGTH(name)-1)
It split number and letters as separately.
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(
SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(col,'1', 1), '2', 1), '3', 1), '4', 1), '5', 1), '6', 1)
, '7', 1), '8', 1), '9', 1), '0', 1) as new_col
FROM table group by new_col;
Try remove the character with SUBSTR. Then use ABS to get the absolute value from field:
SELECT * FROM table ORDER BY ABS(SUBSTR(field,1));
Another method i used in my project is:
SELECT * FROM table_name ORDER BY LENGTH(col_name) DESC, col_name DESC LIMIT 1