How do you create a uitab or uitabgroup - octave

I wish to run some Matlab code in Octave.
It calls uitabgroup()
I have searched for an Octave way to create tabs but to no avail
I have fltk gnuplot and qt graphic toolkits available
can anyone help?
Thank you

I had a go at this out of interest. Here I show a particular example of how you could convert simple code using uitabgroup and uitab to octave. This is by no means a general solution, but if you study the code for a couple of minutes it should be obvious enough how to adapt it to your own problems.
The main idea is that you write your own uitabgroup and uitab functions, and get them to create 'buttons' instead of 'tab-labels', and 'uipanels' in the same place, serving as tab contents. Pressing each button makes one uipanel visible and hides all others.
Here's what the comparison looks like:
The matlab code:
% in 'uitabs_matlab_demo.m'
clf
f = figure( 1 ); set( f, 'position', [500, 500, 500, 500 ] );
tabgp = uitabgroup( f, 'position', [.05, .05, .9, .9] );
tab1 = uitab( tabgp, 'title','Data' );
tab2 = uitab( tabgp, 'title','Plot' );
ax = axes( tab2, 'position', [ 0.1, 0.1, 0.80, 0.80 ] );
p = plot( ax, 1:9 );
axis( [0, 10, 0, 10 ] );
title( 'Dynamic Plot', 'fontsize', 10, 'fontweight', 'normal' );
u1_x = uicontrol( tab1, 'style', 'text', 'string', 'X = 1, Y = ', 'units', 'normalized', 'position', [0.05, 0.90, 0.20, 0.05] );
u2_x = uicontrol( tab1, 'style', 'text', 'string', 'X = 2, Y = ', 'units', 'normalized', 'position', [0.05, 0.80, 0.20, 0.05] );
u3_x = uicontrol( tab1, 'style', 'text', 'string', 'X = 3, Y = ', 'units', 'normalized', 'position', [0.05, 0.70, 0.20, 0.05] );
u4_x = uicontrol( tab1, 'style', 'text', 'string', 'X = 4, Y = ', 'units', 'normalized', 'position', [0.05, 0.60, 0.20, 0.05] );
u5_x = uicontrol( tab1, 'style', 'text', 'string', 'X = 5, Y = ', 'units', 'normalized', 'position', [0.05, 0.50, 0.20, 0.05] );
u6_x = uicontrol( tab1, 'style', 'text', 'string', 'X = 6, Y = ', 'units', 'normalized', 'position', [0.05, 0.40, 0.20, 0.05] );
u7_x = uicontrol( tab1, 'style', 'text', 'string', 'X = 7, Y = ', 'units', 'normalized', 'position', [0.05, 0.30, 0.20, 0.05] );
u8_x = uicontrol( tab1, 'style', 'text', 'string', 'X = 8, Y = ', 'units', 'normalized', 'position', [0.05, 0.20, 0.20, 0.05] );
u9_x = uicontrol( tab1, 'style', 'text', 'string', 'X = 9, Y = ', 'units', 'normalized', 'position', [0.05, 0.10, 0.20, 0.05] );
u1_y = uicontrol( tab1, 'style', 'edit', 'String', '1', 'units', 'normalized', 'position', [0.25, 0.90, 0.20, 0.05], 'callback', {#y_callback, p, 1} );
u2_y = uicontrol( tab1, 'style', 'edit', 'String', '2', 'units', 'normalized', 'position', [0.25, 0.80, 0.20, 0.05], 'callback', {#y_callback, p, 2} );
u3_y = uicontrol( tab1, 'style', 'edit', 'String', '3', 'units', 'normalized', 'position', [0.25, 0.70, 0.20, 0.05], 'callback', {#y_callback, p, 3} );
u4_y = uicontrol( tab1, 'style', 'edit', 'String', '4', 'units', 'normalized', 'position', [0.25, 0.60, 0.20, 0.05], 'callback', {#y_callback, p, 4} );
u5_y = uicontrol( tab1, 'style', 'edit', 'String', '5', 'units', 'normalized', 'position', [0.25, 0.50, 0.20, 0.05], 'callback', {#y_callback, p, 5} );
u6_y = uicontrol( tab1, 'style', 'edit', 'String', '6', 'units', 'normalized', 'position', [0.25, 0.40, 0.20, 0.05], 'callback', {#y_callback, p, 6} );
u7_y = uicontrol( tab1, 'style', 'edit', 'String', '7', 'units', 'normalized', 'position', [0.25, 0.30, 0.20, 0.05], 'callback', {#y_callback, p, 7} );
u8_y = uicontrol( tab1, 'style', 'edit', 'String', '8', 'units', 'normalized', 'position', [0.25, 0.20, 0.20, 0.05], 'callback', {#y_callback, p, 8} );
u9_y = uicontrol( tab1, 'style', 'edit', 'String', '9', 'units', 'normalized', 'position', [0.25, 0.10, 0.20, 0.05], 'callback', {#y_callback, p, 9} );
% In matlab, in-line functions need to be defined at the END of a script
function y_callback( Handle, Event, PlotHandle, XVal )
YData = get( PlotHandle, 'ydata' );
YData( XVal ) = str2num( get( Handle, 'string' ) );
set( PlotHandle, 'ydata', YData );
end
The equivalent octave code:
% in 'uitabs_octave_demo.m'
% Starting an m-file with an instruction as opposed to a 'function' keyword,
% interprets the m-file as a script, as opposed to a function definition.
1;
% In octave, in-line functions need to be defined 'before' their use, as opposed
% to matlab which demands them at the 'end' of a script.
function y_callback( Handle, Event, PlotHandle, XVal )
YData = get( PlotHandle, 'ydata' );
YData( XVal ) = str2num( get( Handle, 'string' ) );
set( PlotHandle, 'ydata', YData );
end
% This is the "extra" bit we provide; since octave does not currently implement the
% 'uitabgroup' and 'uitab' functions, we provide our own definitions for them here
function Handle = uitabgroup( FigHandle, PosOpt, PosVal )
Handle = uipanel( FigHandle, PosOpt, PosVal);
setappdata( Handle, 'tabs_buttons', {} );
setappdata( Handle, 'tabs_contents', {} );
end
function on_tab_select( Handle, Event, TabGroupHandle, TabContents )
Tabs_contents = getappdata( TabGroupHandle, 'tabs_contents' )
for i=1:length(Tabs_contents); set(Tabs_contents{i}, 'visible', 'off'); end
set( TabContents, 'visible', 'on' );
end
function TabContents = uitab( TabGroupHandle, TitleOpt, TitleVal )
Tabs_buttons = getappdata( TabGroupHandle, 'tabs_buttons' );
Tabs_contents = getappdata( TabGroupHandle, 'tabs_contents' );
TabContents = uipanel( TabGroupHandle, 'units', 'normalized', 'position', [ 0, 0, 1, 0.95 ] );
TabButton = uicontrol( TabGroupHandle, 'style', 'pushbutton' ,'string', TitleVal, 'units', 'normalized', 'position', [ length(Tabs_buttons) * 0.1, 0.95, 0.1, 0.05 ], 'callback', {#on_tab_select, TabGroupHandle, TabContents } );
Tabs_buttons{end+1} = TabButton;
Tabs_contents{end+1} = TabContents;
setappdata( TabGroupHandle, 'tabs_buttons' , Tabs_buttons );
setappdata( TabGroupHandle, 'tabs_contents', Tabs_contents );
end
% Rest of script as before
clf
f = figure( 1 ); set( f, 'position', [500, 500, 500, 500 ] );
tabgp = uitabgroup( f, 'position', [.05, .05, .9, .9] );
tab1 = uitab( tabgp, 'title','Data' );
tab2 = uitab( tabgp, 'title','Plot' );
ax = axes( tab2, 'position', [ 0.1, 0.1, 0.80, 0.80 ] );
p = plot( ax, 1:9 );
axis( [0, 10, 0, 10 ] );
title( 'Dynamic Plot', 'fontsize', 10, 'fontweight', 'normal' );
u1_x = uicontrol( tab1, 'style', 'text', 'string', 'X = 1, Y = ', 'units', 'normalized', 'position', [0.05, 0.90, 0.20, 0.05] );
u2_x = uicontrol( tab1, 'style', 'text', 'string', 'X = 2, Y = ', 'units', 'normalized', 'position', [0.05, 0.80, 0.20, 0.05] );
u3_x = uicontrol( tab1, 'style', 'text', 'string', 'X = 3, Y = ', 'units', 'normalized', 'position', [0.05, 0.70, 0.20, 0.05] );
u4_x = uicontrol( tab1, 'style', 'text', 'string', 'X = 4, Y = ', 'units', 'normalized', 'position', [0.05, 0.60, 0.20, 0.05] );
u5_x = uicontrol( tab1, 'style', 'text', 'string', 'X = 5, Y = ', 'units', 'normalized', 'position', [0.05, 0.50, 0.20, 0.05] );
u6_x = uicontrol( tab1, 'style', 'text', 'string', 'X = 6, Y = ', 'units', 'normalized', 'position', [0.05, 0.40, 0.20, 0.05] );
u7_x = uicontrol( tab1, 'style', 'text', 'string', 'X = 7, Y = ', 'units', 'normalized', 'position', [0.05, 0.30, 0.20, 0.05] );
u8_x = uicontrol( tab1, 'style', 'text', 'string', 'X = 8, Y = ', 'units', 'normalized', 'position', [0.05, 0.20, 0.20, 0.05] );
u9_x = uicontrol( tab1, 'style', 'text', 'string', 'X = 9, Y = ', 'units', 'normalized', 'position', [0.05, 0.10, 0.20, 0.05] );
u1_y = uicontrol( tab1, 'style', 'edit', 'String', '1', 'units', 'normalized', 'position', [0.25, 0.90, 0.20, 0.05], 'callback', {#y_callback, p, 1}, 'backgroundcolor', 'w' );
u2_y = uicontrol( tab1, 'style', 'edit', 'String', '2', 'units', 'normalized', 'position', [0.25, 0.80, 0.20, 0.05], 'callback', {#y_callback, p, 2}, 'backgroundcolor', 'w' );
u3_y = uicontrol( tab1, 'style', 'edit', 'String', '3', 'units', 'normalized', 'position', [0.25, 0.70, 0.20, 0.05], 'callback', {#y_callback, p, 3}, 'backgroundcolor', 'w' );
u4_y = uicontrol( tab1, 'style', 'edit', 'String', '4', 'units', 'normalized', 'position', [0.25, 0.60, 0.20, 0.05], 'callback', {#y_callback, p, 4}, 'backgroundcolor', 'w' );
u5_y = uicontrol( tab1, 'style', 'edit', 'String', '5', 'units', 'normalized', 'position', [0.25, 0.50, 0.20, 0.05], 'callback', {#y_callback, p, 5}, 'backgroundcolor', 'w' );
u6_y = uicontrol( tab1, 'style', 'edit', 'String', '6', 'units', 'normalized', 'position', [0.25, 0.40, 0.20, 0.05], 'callback', {#y_callback, p, 6}, 'backgroundcolor', 'w' );
u7_y = uicontrol( tab1, 'style', 'edit', 'String', '7', 'units', 'normalized', 'position', [0.25, 0.30, 0.20, 0.05], 'callback', {#y_callback, p, 7}, 'backgroundcolor', 'w' );
u8_y = uicontrol( tab1, 'style', 'edit', 'String', '8', 'units', 'normalized', 'position', [0.25, 0.20, 0.20, 0.05], 'callback', {#y_callback, p, 8}, 'backgroundcolor', 'w' );
u9_y = uicontrol( tab1, 'style', 'edit', 'String', '9', 'units', 'normalized', 'position', [0.25, 0.10, 0.20, 0.05], 'callback', {#y_callback, p, 9}, 'backgroundcolor', 'w' );

Related

SQL Query return zero if is NOT in list

I have the followin
SELECT
au.country as country_code,
COALESCE(SUM(uwm.amount), 0) as amountInbound
FROM user_wallet_movement uwm
LEFT JOIN user_wallet uw ON uwm.wallet_id = uw.id
LEFT JOIN app_user au ON uw.user_id = au.id
WHERE
status = 'execute'
and direction = 'inbound'
and mov_date > '2020-07-01'
and au.country IN ('AD', 'AC', 'AE', 'AF', 'AG', 'AI', 'AL', 'AM', 'AN', 'AO', 'AQ', 'AR', 'AS', 'AT', 'AU', 'AW', 'AZ', 'BA', 'BB', 'BD', 'BE', 'BF', 'BG', 'BH', 'BI', 'BJ', 'BM', 'BN', 'BO', 'BR', 'BS', 'BT', 'BV', 'BW', 'BY', 'BZ', 'CA', 'CC', 'CD', 'CF', 'CG', 'CH', 'CI', 'CK', 'CL', 'CM', 'CN', 'CO', 'CR', 'CU', 'CV', 'CX', 'CY', 'CZ', 'DE', 'DJ', 'DK', 'DM', 'DO', 'DZ', 'EC', 'EE', 'EG', 'EH', 'ER', 'ES', 'ET', 'FI', 'FJ', 'FK', 'FM', 'FO', 'FR', 'GA', 'GB', 'GD', 'GE', 'GF', 'GH', 'GI', 'GL', 'GM', 'GN', 'GP', 'GQ', 'GR', 'GT', 'GU', 'GW', 'GY', 'HK', 'HM', 'HN', 'HR', 'HT', 'HU', 'ID', 'IE', 'IL', 'IN', 'IO', 'IQ', 'IR', 'IS', 'IT', 'JM', 'JO', 'JP', 'KE', 'KG', 'KH', 'KI', 'KM', 'KN', 'KP', 'KR', 'KW', 'KY', 'KZ', 'LA', 'LB', 'LC', 'LI', 'LK', 'LR', 'LS', 'LT', 'LU', 'LV', 'LY', 'MA', 'MC', 'MC', 'MD', 'ME', 'MG', 'MH', 'MK', 'ML', 'MM', 'MN', 'MP', 'MQ', 'MR', 'MS', 'MT', 'MU', 'MV', 'MW', 'MX', 'MY', 'MZ', 'NA', 'NC', 'NE', 'NF', 'NG', 'NI', 'NL', 'NO', 'NP', 'NR', 'NU', 'NZ', 'OM', 'PA', 'PE', 'PF', 'PG', 'PH', 'PK', 'PL', 'PM', 'PN', 'PR', 'PT', 'PW', 'PY', 'QA', 'RE', 'RO', 'RS', 'RU', 'RW', 'SA', 'SB', 'SC', 'SD', 'SE', 'SG', 'SH', 'SI', 'SJ', 'SK', 'SL', 'SM', 'SN', 'SO', 'SR', 'ST', 'SV', 'SY', 'SZ', 'TC', 'TD', 'TF', 'TG', 'TH', 'TJ', 'TK', 'TL', 'TM', 'TN', 'TO', 'TR', 'TT', 'TV', 'TZ', 'UA', 'UG', 'UM', 'US', 'UY', 'UZ', 'VA', 'VC', 'VE', 'VG', 'VI', 'VN', 'VU', 'WF', 'WS', 'xA', 'xE', 'xF', 'XK', 'xN', 'xO', 'xS', 'YE', 'YT', 'ZA', 'ZM', 'ZW')
GROUP BY country_code
ORDER BY country_code
Which should return me the amount of money spent in each country in the list.
My output is
AE 0.35365110000000016
AR 1.0367374499999995
AT 0.11195171000000001
AU 1.7345992
BE 1.9242438800000006
BG 5.043282479999997
CA 0.5906319000000001
CH 0.5082077999999999
CO 0.14248785
CR 0.036722840000000014
CU 0.11325390999999999
CY 0.18752883999999997
CZ 0.11454307999999999
DE 8.057752660000036
DO 0.8858295500000001
EE 0.7410690900000001
ES 31.125371000000023
FR 0.4851664099999999
GB 1.44115391
HR 0.023154
HU 1.0131190899999998
IE 0.3229343799999997
IN 0.026833529999999984
IT 2199.1061043693944
KE 0.21115987
KR 0.161765
LU 0.20279967
MC 0.2127708600000001
MT 0.028277630000000005
MX 0.45381685
NL 0.1408655
PE 0.00108554
QA 1.8347713
RO 7.0233499800000105
RS 0.25260947000000006
RU 0.16577983
SE 3.4979126399999947
SH 1.1328741000000002
SI 0.00178069
SK 0.04637177
SZ 0.3603625199999996
US 2.41114205
VE 0.53491791
So, as you can see, there are countries in the list which not appear in the output because the amount is null.
How can I include them in the list with the value 0?
Thank you
EDIT:
Not all countries in the list are in the table; I also would like to be in the output countries that are not in the table but are in the list
the problem is if you don't have data in wallet tables for given table join will return nothing. instead you can use left join :
SELECT
au.country as country_code,
COALESCE(SUM(uwm.amount), 0) as amountInbound
FROM
app_user au
left join user_wallet uw ON uw.user_id = au.id
left JOIN user_wallet_movement uwm ON uwm.wallet_id = uw.id
WHERE
status = 'execute'
and direction = 'inbound'
and mov_date > '2020-07-01'
au.country IN ('AD', 'AC', 'AE', 'AF', 'AG', 'AI', 'AL', 'AM', 'AN', 'AO', 'AQ', 'AR', 'AS', 'AT', 'AU', 'AW', 'AZ', 'BA', 'BB', 'BD', 'BE', 'BF', 'BG', 'BH', 'BI', 'BJ', 'BM', 'BN', 'BO', 'BR', 'BS', 'BT', 'BV', 'BW', 'BY', 'BZ', 'CA', 'CC', 'CD', 'CF', 'CG', 'CH', 'CI', 'CK', 'CL', 'CM', 'CN', 'CO', 'CR', 'CU', 'CV', 'CX', 'CY', 'CZ', 'DE', 'DJ', 'DK', 'DM', 'DO', 'DZ', 'EC', 'EE', 'EG', 'EH', 'ER', 'ES', 'ET', 'FI', 'FJ', 'FK', 'FM', 'FO', 'FR', 'GA', 'GB', 'GD', 'GE', 'GF', 'GH', 'GI', 'GL', 'GM', 'GN', 'GP', 'GQ', 'GR', 'GT', 'GU', 'GW', 'GY', 'HK', 'HM', 'HN', 'HR', 'HT', 'HU', 'ID', 'IE', 'IL', 'IN', 'IO', 'IQ', 'IR', 'IS', 'IT', 'JM', 'JO', 'JP', 'KE', 'KG', 'KH', 'KI', 'KM', 'KN', 'KP', 'KR', 'KW', 'KY', 'KZ', 'LA', 'LB', 'LC', 'LI', 'LK', 'LR', 'LS', 'LT', 'LU', 'LV', 'LY', 'MA', 'MC', 'MC', 'MD', 'ME', 'MG', 'MH', 'MK', 'ML', 'MM', 'MN', 'MP', 'MQ', 'MR', 'MS', 'MT', 'MU', 'MV', 'MW', 'MX', 'MY', 'MZ', 'NA', 'NC', 'NE', 'NF', 'NG', 'NI', 'NL', 'NO', 'NP', 'NR', 'NU', 'NZ', 'OM', 'PA', 'PE', 'PF', 'PG', 'PH', 'PK', 'PL', 'PM', 'PN', 'PR', 'PT', 'PW', 'PY', 'QA', 'RE', 'RO', 'RS', 'RU', 'RW', 'SA', 'SB', 'SC', 'SD', 'SE', 'SG', 'SH', 'SI', 'SJ', 'SK', 'SL', 'SM', 'SN', 'SO', 'SR', 'ST', 'SV', 'SY', 'SZ', 'TC', 'TD', 'TF', 'TG', 'TH', 'TJ', 'TK', 'TL', 'TM', 'TN', 'TO', 'TR', 'TT', 'TV', 'TZ', 'UA', 'UG', 'UM', 'US', 'UY', 'UZ', 'VA', 'VC', 'VE', 'VG', 'VI', 'VN', 'VU', 'WF', 'WS', 'xA', 'xE', 'xF', 'XK', 'xN', 'xO', 'xS', 'YE', 'YT', 'ZA', 'ZM', 'ZW')
GROUP BY country_code
ORDER BY country_code
Probably your inner joins are limiting the rows in your output, try using outer joins:
SELECT
au.country as country_code,
COALESCE(SUM(uwm.amount), 0) as amountInbound
FROM user_wallet_movement uwm
LEFT OUTER JOIN user_wallet uw ON uwm.wallet_id = uw.id
LEFT OUTER JOIN app_user au ON uw.user_id = au.id
WHERE
status = 'execute'
and direction = 'inbound'
and mov_date > '2020-07-01'
and au.country IN (...)
GROUP BY country_code
ORDER BY country_code
If your data has all the countries, then a simple fix is to use conditional aggregation:
SELECT au.country as country_code,
SUM(CASE WHEN status = 'execute' and direction = 'inbound' and mov_date > '2020-07-01' THEN uwm.amount ELSE 0 END) as amountInbound
FROM user_wallet_movement uwm JOIN
user_wallet uw
ON uwm.wallet_id = uw.id JOIN
app_user au
ON uw.user_id = au.id
WHERE au.country IN ('AD', 'AC', 'AE', 'AF', 'AG', 'AI', 'AL', 'AM', 'AN', 'AO', 'AQ', 'AR', 'AS', 'AT', 'AU', 'AW', 'AZ', 'BA', 'BB', 'BD', 'BE', 'BF', 'BG', 'BH', 'BI', 'BJ', 'BM', 'BN', 'BO', 'BR', 'BS', 'BT', 'BV', 'BW', 'BY', 'BZ', 'CA', 'CC', 'CD', 'CF', 'CG', 'CH', 'CI', 'CK', 'CL', 'CM', 'CN', 'CO', 'CR', 'CU', 'CV', 'CX', 'CY', 'CZ', 'DE', 'DJ', 'DK', 'DM', 'DO', 'DZ', 'EC', 'EE', 'EG', 'EH', 'ER', 'ES', 'ET', 'FI', 'FJ', 'FK', 'FM', 'FO', 'FR', 'GA', 'GB', 'GD', 'GE', 'GF', 'GH', 'GI', 'GL', 'GM', 'GN', 'GP', 'GQ', 'GR', 'GT', 'GU', 'GW', 'GY', 'HK', 'HM', 'HN', 'HR', 'HT', 'HU', 'ID', 'IE', 'IL', 'IN', 'IO', 'IQ', 'IR', 'IS', 'IT', 'JM', 'JO', 'JP', 'KE', 'KG', 'KH', 'KI', 'KM', 'KN', 'KP', 'KR', 'KW', 'KY', 'KZ', 'LA', 'LB', 'LC', 'LI', 'LK', 'LR', 'LS', 'LT', 'LU', 'LV', 'LY', 'MA', 'MC', 'MC', 'MD', 'ME', 'MG', 'MH', 'MK', 'ML', 'MM', 'MN', 'MP', 'MQ', 'MR', 'MS', 'MT', 'MU', 'MV', 'MW', 'MX', 'MY', 'MZ', 'NA', 'NC', 'NE', 'NF', 'NG', 'NI', 'NL', 'NO', 'NP', 'NR', 'NU', 'NZ', 'OM', 'PA', 'PE', 'PF', 'PG', 'PH', 'PK', 'PL', 'PM', 'PN', 'PR', 'PT', 'PW', 'PY', 'QA', 'RE', 'RO', 'RS', 'RU', 'RW', 'SA', 'SB', 'SC', 'SD', 'SE', 'SG', 'SH', 'SI', 'SJ', 'SK', 'SL', 'SM', 'SN', 'SO', 'SR', 'ST', 'SV', 'SY', 'SZ', 'TC', 'TD', 'TF', 'TG', 'TH', 'TJ', 'TK', 'TL', 'TM', 'TN', 'TO', 'TR', 'TT', 'TV', 'TZ', 'UA', 'UG', 'UM', 'US', 'UY', 'UZ', 'VA', 'VC', 'VE', 'VG', 'VI', 'VN', 'VU', 'WF', 'WS', 'xA', 'xE', 'xF', 'XK', 'xN', 'xO', 'xS', 'YE', 'YT', 'ZA', 'ZM', 'ZW')
GROUP BY country_code
ORDER BY country_code;
Otherwise, you will need to use a LEFT JOIN. For that purpose, it is better to start with a countries table of some sort. Do you have such a table?
If you would like to have all the countries from table A to show up even though table b has less number of countries then your join should be LEFT instead of Inner.
This way rows with no amount will be null in cases where the countries doesn't exist in table B. This null can be replaced using COALESCE()
COALESCE returns the first non-null value. if both are not null then it returns the first one.
SELECT
au.country as country_code,
COALESCE(SUM(uwm.amount), 0) as amountInbound
FROM user_wallet_movement uwm
LEFT JOIN user_wallet uw
ON uwm.wallet_id = uw.id
LEFT JOIN app_user au
ON uw.user_id = au.id
WHERE
status = 'execute'
and direction = 'inbound'
and mov_date > '2020-07-01'
and au.country IN ('ALL THE COUNTRIES')
GROUP BY
country_code
ORDER BY
country_code

How to calculate difference between all current date records total and previous dates records total using GROUP BY and INNER JOIN?

I have a table below:
SELECT * FROM reports;
# id, date, o_type, quantity, vendor
'1', '2020-04-05', '2511', '200', 'apple'
'2', '2020-04-05', '5120', '350', 'apple'
'3', '2020-04-05', '2520', '150', 'apple'
'4', '2020-04-05', '5114', '400', 'apple'
'5', '2020-04-05', 'HG851', '200', 'google'
'6', '2020-04-05', 'HG851A', '400', 'google'
'7', '2020-04-05', 'MA5620G', '9000', 'google'
'8', '2020-04-05', 'OT550', '7000', 'google'
'9', '2020-04-05', 'OT925', '2000', 'google'
'10', '2020-04-05', 'OT928', '2000', 'google'
'11', '2020-04-06', '2520', '150', 'apple'
'12', '2020-04-06', 'HG851', '200', 'google'
'13', '2020-04-06', 'HG851', '200', 'google'
'14', '2020-04-06', 'HG851A', '400', 'google'
'15', '2020-04-07', '2511', '200', 'apple'
'16', '2020-04-07', '5120', '350', 'apple'
'17', '2020-04-07', '2520', '150', 'apple'
'18', '2020-04-07', '5114', '400', 'apple'
'19', '2020-04-07', 'G-440G-A', '200', 'NOKIA'
'20', '2020-04-07', '1240GA', '400', 'NOKIA'
'21', '2020-04-07', '1440GP', '9000', 'NOKIA'
'22', '2020-04-07', 'B-0404G-B', '7000', 'NOKIA'
'23', '2020-04-07', 'B2404GP', '2000', 'NOKIA'
'24', '2020-04-07', 'G-881G-A', '2000', 'NOKIA'
'25', '2020-04-08', 'G-881G-B', '150', 'NOKIA'
'26', '2020-04-08', 'HG851', '200', 'google'
'27', '2020-04-08', 'HG851A', '400', 'google'
I have a below query as per my project requirement:
SELECT Date(a.date), a.vendor, a.o_type, a.quantity, b.total FROM reports a
INNER JOIN (
SELECT vendor, date, SUM(quantity) as total
FROM reports WHERE date >= '2020-04-06' AND date <= '2020-04-08'
GROUP BY vendor, date) b ON a.date = b.date AND a.vendor = b.vendor
# Date(a.date), vendor, o_type, quantity, total
'2020-04-06', 'apple', '2520', '150', '150'
'2020-04-06', 'google', 'HG851', '200', '800'
'2020-04-06', 'google', 'HG851', '200', '800'
'2020-04-06', 'google', 'HG851A', '400', '800'
'2020-04-07', 'apple', '2511', '200', '1100'
'2020-04-07', 'apple', '5120', '350', '1100'
'2020-04-07', 'apple', '2520', '150', '1100'
'2020-04-07', 'apple', '5114', '400', '1100'
'2020-04-07', 'NOKIA', 'G-440G-A', '200', '20600'
'2020-04-07', 'NOKIA', '1240GA', '400', '20600'
'2020-04-07', 'NOKIA', '1440GP', '9000', '20600'
'2020-04-07', 'NOKIA', 'B-0404G-B', '7000', '20600'
'2020-04-07', 'NOKIA', 'B2404GP', '2000', '20600'
'2020-04-07', 'NOKIA', 'G-881G-A', '2000', '20600'
'2020-04-08', 'NOKIA', 'G-881G-B', '150', '150'
'2020-04-08', 'google', 'HG851', '200', '600'
'2020-04-08', 'google', 'HG851A', '400', '600'
I have to add an extra column DIFFERENCE to the above INNER JOIN query. How to calculate the difference between the current date and previous dates vendor column's total.
Example1:
2020-04-06 ---> apple ---> total(150)
2020-04-07 ---> apple ---> total(1100) Here difference equals to -950 (150-1100)
Example2:
2020-04-07 ---> apple ---> total(1100)
2020-04-08 ---> apple ---> total(0) Here difference equals to -1100 (0-1100)
Example3:
2020-04-07 ---> NOKIA ---> total(20600)
2020-04-08 ---> apple ---> total(150) Here difference equals to -20450 (150-20600)
Please guide me on how to proceed further? or if any other details required from my end kindly let me know.

How to set all 50 states to a country code as 'US'

Okay so I'm using Google Charts API to create a map that displays sales based on location. Some code in my chart are countries so France is displayed in my CSV file as FR. However, the API ONLY does Countries so my data in the file that are states such as NC, CA, NY etc... need to be stored as US. Would a case statement for each state be the best way to go?
States I need these states to be set equal to 'US'
StateID
-------
AL
CA
HI
NY
etc...
try this sql...
SELECT
CASE WHEN
CUST_STATE_CD in ('AK', 'AZ', 'AR', 'CA', 'CO', 'CT', 'DE', 'DC', 'FL', 'GA', 'HI', 'ID', 'IL', 'IN', 'IA', 'KS', 'KY', 'LA', 'ME', 'MD', 'MA', 'MI', 'MN', 'MS', 'MO', 'MT', 'NE', 'NV', 'NH', 'NJ', 'NM', 'NY', 'NC', 'ND', 'OH', 'OK', 'OR', 'PA', 'PR', 'RI', 'SC', 'SD', 'TN', 'TX', 'UT', 'VT', 'VA', 'WA', 'WV', 'WI', 'WY')
THEN
'US'
ELSE
CUST_STATE_CD
END as state,
count(CUST_NM) as totalCust
FROM
sales_filev1
GROUP BY
CASE WHEN
CUST_STATE_CD in ('AK', 'AZ', 'AR', 'CA', 'CO', 'CT', 'DE', 'DC', 'FL', 'GA', 'HI', 'ID', 'IL', 'IN', 'IA', 'KS', 'KY', 'LA', 'ME', 'MD', 'MA', 'MI', 'MN', 'MS', 'MO', 'MT', 'NE', 'NV', 'NH', 'NJ', 'NM', 'NY', 'NC', 'ND', 'OH', 'OK', 'OR', 'PA', 'PR', 'RI', 'SC', 'SD', 'TN', 'TX', 'UT', 'VT', 'VA', 'WA', 'WV', 'WI', 'WY')
THEN
'US'
ELSE
CUST_STATE_CD
END

Rank by calculated variable in MySQL

The following table is for practice only. I will use the code on a much larger table.
SELECT *
FROM price_practice;
gives
id company dt price
'16', 'Amex', '2015-07-01', '5.00'
'17', 'Amex', '2015-07-02', '5.10'
'18', 'Amex', '2015-07-03', '5.00'
'19', 'Amex', '2015-07-06', '5.88'
'20', 'Amex', '2015-07-07', '4.21'
'21', 'Citi', '2015-07-01', '1.00'
'22', 'Citi', '2015-07-02', '1.10'
'23', 'Citi', '2015-07-03', '1.00'
'24', 'Citi', '2015-07-06', '0.88'
'25', 'Citi', '2015-07-07', '1.01'
'26', 'Amex', '2015-07-08', '5.23'
'27', 'Amex', '2015-07-09', '5.35'
'28', 'Amex', '2015-07-10', '5.55'
'29', 'Amex', '2015-07-13', '5.88'
'30', 'Amex', '2015-07-14', '6.01'
'31', 'Citi', '2015-07-08', '0.95'
'32', 'Citi', '2015-07-09', '0.83'
'33', 'Citi', '2015-07-10', '0.79'
'34', 'Citi', '2015-07-13', '0.72'
'35', 'Citi', '2015-07-14', '0.59'
The following snippet calculates the percentage change in price from one date to the next.
SELECT x.id, x.company, x.dt, x.price, (x.price - y.price)/y.price AS 'Change'
FROM
(
SELECT a.id AS aid, MAX(b.id) AS aPrevid
FROM price_practice a
INNER JOIN price_practice b
WHERE a.id > b.id
AND a.company = b.company
GROUP BY a.id
) Sub1
INNER JOIN price_practice x ON Sub1.aid = x.id
INNER JOIN price_practice y ON Sub1.aPrevid = y.id
ORDER BY x.id DESC
As intended, it returns
id company dt price Change
'35', 'Citi', '2015-07-14', '0.59', '-0.180556'
'34', 'Citi', '2015-07-13', '0.72', '-0.088608'
'33', 'Citi', '2015-07-10', '0.79', '-0.048193'
'32', 'Citi', '2015-07-09', '0.83', '-0.126316'
'31', 'Citi', '2015-07-08', '0.95', '-0.059406'
'30', 'Amex', '2015-07-14', '6.01', '0.022109'
'29', 'Amex', '2015-07-13', '5.88', '0.059459'
'28', 'Amex', '2015-07-10', '5.55', '0.037383'
'27', 'Amex', '2015-07-09', '5.35', '0.022945'
'26', 'Amex', '2015-07-08', '5.23', '0.242280'
'25', 'Citi', '2015-07-07', '1.01', '0.147727'
'24', 'Citi', '2015-07-06', '0.88', '-0.120000'
'23', 'Citi', '2015-07-03', '1.00', '-0.090909'
'22', 'Citi', '2015-07-02', '1.10', '0.100000'
'20', 'Amex', '2015-07-07', '4.21', '-0.284014'
'19', 'Amex', '2015-07-06', '5.88', '0.176000'
'18', 'Amex', '2015-07-03', '5.00', '-0.019608'
'17', 'Amex', '2015-07-02', '5.10', '0.020000'
The following snippet does something entirely different: it ranks observations by price for every company seperately.
SELECT (
CASE company
WHEN #curType
THEN #curRow := #curRow + 1
ELSE #curRow := 1 AND #curType := company END
) + 1 AS rank,
id,
company,
dt,
price
FROM price_practice,
(SELECT #curRow := 0, #curType := '') r
ORDER BY company DESC, price DESC;
As intended, it returns
rank id company dt price
'1', '22', 'Citi', '2015-07-02', '1.10'
'2', '25', 'Citi', '2015-07-07', '1.01'
'3', '23', 'Citi', '2015-07-03', '1.00'
'4', '21', 'Citi', '2015-07-01', '1.00'
'5', '31', 'Citi', '2015-07-08', '0.95'
'6', '24', 'Citi', '2015-07-06', '0.88'
'7', '32', 'Citi', '2015-07-09', '0.83'
'8', '33', 'Citi', '2015-07-10', '0.79'
'9', '34', 'Citi', '2015-07-13', '0.72'
'10', '35', 'Citi', '2015-07-14', '0.59'
'1', '30', 'Amex', '2015-07-14', '6.01'
'2', '19', 'Amex', '2015-07-06', '5.88'
'3', '29', 'Amex', '2015-07-13', '5.88'
'4', '28', 'Amex', '2015-07-10', '5.55'
'5', '27', 'Amex', '2015-07-09', '5.35'
'6', '26', 'Amex', '2015-07-08', '5.23'
'7', '17', 'Amex', '2015-07-02', '5.10'
'8', '18', 'Amex', '2015-07-03', '5.00'
'9', '16', 'Amex', '2015-07-01', '5.00'
'10', '20', 'Amex', '2015-07-07', '4.21'
The question is:
How do I rank observations by percentage change?
I imagine you can save the percentage change data in a new column and then rank it, but I suspect this is not the best method. I will do many similar calculations (eg weekly % change, variance etc), and I have around 3,000,000 observations, so the table would grow big quickly. If this is the only way to do it, I will, but I think combining the two snippets above to calculate percentage change and rank in one go would be better. Or what do you think?
As I'm sure you can tell from my question, I'm a beginner at MySQL. Any advise on how to proceed is appreciated!

Row Number with a mySQL Join

I have the following Query that works correctly:
SELECT #row_num := IF(#prev_value=concat(o.CITY, o.keyword_text) ,#row_num+1, 1) AS POSITION
,o.idBUSINESS
,o.KEYWORD_TEXT
,o.CITY
, o.BID_AMOUNT
,#prev_value := concat(o.CITY, o.keyword_text)
FROM (SELECT #row_num := 1) x,
(SELECT #prev_value := '') y,
(SELECT #prev_value1 := '') z,
elevated_business_queue o
ORDER BY o.CITY , o.KEYWORD_TEXT, o.BID_AMOUNT DESC
This query returns:
# POSITION, idBUSINESS, KEYWORD_TEXT, CITY, BID_AMOUNT, #prev_value := concat(o.CITY, o.keyword_text)
'1', '7', '2', 'New Jersey', '3.50', 'New Jersey2'
'2', '5', '2', 'New Jersey', '2.50', 'New Jersey2'
'3', '1', '2', 'New Jersey', '2.50', 'New Jersey2'
'1', '5', '1', 'New York', '2.50', 'New York1'
'2', '7', '1', 'New York', '2.30', 'New York1'
'3', '1', '1', 'New York', '1.50', 'New York1'
'1', '9', '2', 'New York', '7.50', 'New York2'
'2', '1', '2', 'New York', '4.50', 'New York2'
'3', '5', '2', 'New York', '3.50', 'New York2'
'4', '7', '2', 'New York', '2.50', 'New York2'
This data is correct. Now, I want to join the elevated_business_queue with another table. I am doing it as follows:
SELECT #row_num := IF(#prev_value=concat(o.CITY, o.keyword_text) ,#row_num+1, 1) AS POSITION
,o.idBUSINESS
,o.KEYWORD_TEXT
,o.CITY
, o.BID_AMOUNT
,#prev_value := concat(o.CITY, o.keyword_text)
FROM (SELECT #row_num := 1) x,
(SELECT #prev_value := '') y,
(SELECT #prev_value1 := '') z,
elevated_business_queue o
INNER JOIN funds_balance fb ON fb.idBUSINESS = o.idBUSINESS
WHERE fb.PREMIUM_POSITIONS_CREDIT >= (o.BID_AMOUNT + ROUND((12.36/100)*o.BID_AMOUNT, 2))
ORDER BY o.CITY , o.KEYWORD_TEXT, o.BID_AMOUNT DESC
However, when I join, my POSITION gets messed up. I am now getting:
# POSITION, idBUSINESS, KEYWORD_TEXT, CITY, BID_AMOUNT, #prev_value := concat(o.CITY, o.keyword_text)
'2', '7', '2', 'New Jersey', '3.50', 'New Jersey2'
'1', '1', '2', 'New Jersey', '2.50', 'New Jersey2'
'1', '5', '2', 'New Jersey', '2.50', 'New Jersey2'
'2', '5', '1', 'New York', '2.50', 'New York1'
'3', '7', '1', 'New York', '2.30', 'New York1'
'1', '1', '1', 'New York', '1.50', 'New York1'
'1', '1', '2', 'New York', '4.50', 'New York2'
'2', '5', '2', 'New York', '3.50', 'New York2'
'1', '7', '2', 'New York', '2.50', 'New York2'
Can someone please help.
--------------UPDATE----------------------
I tried with the following query but the POSITION is still off:
SELECT T1.*,fb.* FROM
(SELECT #row_num := IF(#prev_value=concat(o.CITY, o.keyword_text) ,#row_num+1, 1) AS POSITION
,o.idBUSINESS
,o.KEYWORD_TEXT
,o.CITY
,o.BID_AMOUNT
,#prev_value := concat(o.CITY, o.keyword_text)
FROM (SELECT #row_num := 1) x,
(SELECT #prev_value := '') y,
(SELECT #prev_value1 := '') z,
elevated_business_queue o
ORDER BY o.CITY , o.KEYWORD_TEXT, o.BID_AMOUNT DESC)T1
INNER JOIN funds_balance fb ON fb.idBUSINESS = T1.idBUSINESS
WHERE fb.PREMIUM_POSITIONS_CREDIT >= (T1.BID_AMOUNT + ROUND((12.36/100)*T1.BID_AMOUNT, 2))
ORDER BY T1.CITY ,T1.KEYWORD_TEXT, T1.BID_AMOUNT DESC;
I now get the following result-set:
# POSITION, idBUSINESS, KEYWORD_TEXT, CITY, BID_AMOUNT, #prev_value := concat(o.CITY, o.keyword_text), idBUSINESS, PREMIUM_POSITIONS_CREDIT
'1', '7', '2', 'New Jersey', '3.50', 'New Jersey2', '7', '17.30'
'3', '1', '2', 'New Jersey', '2.50', 'New Jersey2', '1', '12.31'
'2', '5', '2', 'New Jersey', '2.50', 'New Jersey2', '5', '15.19'
'1', '5', '1', 'New York', '2.50', 'New York1', '5', '15.19'
'2', '7', '1', 'New York', '2.30', 'New York1', '7', '17.30'
'3', '1', '1', 'New York', '1.50', 'New York1', '1', '12.31'
'2', '1', '2', 'New York', '4.50', 'New York2', '1', '12.31'
'3', '5', '2', 'New York', '3.50', 'New York2', '5', '15.19'
'4', '7', '2', 'New York', '2.50', 'New York2', '7', '17.30'
There is no POSITION=1 for KEYWORD_TEXT=2 in New York. The following row should have a position of 1:
'2', '1', '2', 'New York', '4.50', 'New York2', '1', '12.31'
Perhaps you could replace your row_num calculation with a window function like this:
row_number() over(partition by o.CITY , o.KEYWORD_TEXT order by o.BID_AMOUNT DESC)
Here you're misplacing the order by columns. If you require ordering by KEYWORD_TEXT then by BID_AMOUNT and CITY (if yes then)
Change order by as:
ORDER BY KEYWORD_TEXT, BID_AMOUNT CITY