How to create a conditional calculated column in SQL? - mysql

How to write a query to create a conditional and calculated field in SQL?
I am trying to merge two or more entities and the context of the entities are similar to the sample ones below. I am having an issue with regards to how to create the calculated field with the column F and £ of C-A. I would greatly appreciate if I could get some help.
FlightTable AirportTable
AKEY CODE F £ Code City Country
001 LHR C 10 ATL Atlanta USA
002 BOS C 15 BOS Boston USA
003 BOS A 9 . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
101 MAN C 21 VIE Schwechat Austria
102 VIE A 9 ZRH Kloten Switzerland
I am trying to get a result of a joined entity similar to:
Joined table
CODE CITY COUNTRY (£ Calculated Field)
001 BOS Boston USA 4
. . . . . . . . . . . . . .

You may be able to use a case statement in the calculation.
SELECT AIR.Code, AIR.City, AIR.Country, SUM(CASE WHEN flight.f = 'C' then £
when flight.f = 'A' then (-1) * £
else null
end) as "£ calculated"
from AirportTable as "air"
join FlightTable as "flight" on "air".CODE = "flight".code -- could be AKEY = AKEY

I think you just want two joins:
select a.*, (fc.£ - fa.£) as calculation
from airporttable a join
flighttable fc
on fc.code = a.code and fc.f = 'C' join
flighttable fa
on fa.code = a.code and fa.f = 'A';

Related

How to merge column value?

How to merge column value in MySQL query? I'm using WordPress for a while now, and I would like to sort data from the price, but each post have different type price (monthly & yearly). The price is stored in wp_postmeta. Here is what I've tried so far.
$mam_global_fields = "
, price.meta_value AS villa_price,
CASE currency.meta_value
WHEN 'IDR' THEN price.meta_value * ". $currency_rate['IDR'] ." / 12
WHEN 'USD' THEN price.meta_value * ". $currency_rate['USD'] ." / 12
WHEN 'EUR' THEN price.meta_value * ". $currency_rate['EUR'] ." / 12
WHEN 'AUD' THEN price.meta_value * ". $currency_rate['AUD'] ." / 12
END AS price_in_usd,
CASE currency_monthly.meta_value
WHEN 'IDR' THEN price_monthly.meta_value * ". $currency_rate['IDR'] ."
WHEN 'USD' THEN price_monthly.meta_value * ". $currency_rate['USD'] ."
WHEN 'EUR' THEN price_monthly.meta_value * ". $currency_rate['EUR'] ."
WHEN 'AUD' THEN price_monthly.meta_value * ". $currency_rate['AUD'] ."
END AS price_in_usd_monthly,
price.meta_key AS price_key,
villa_code.meta_value AS v_codes
";
I join the wp_postmeta multiple times because I want to get the correct data for each post.
$mam_global_join = "
INNER JOIN " . $wpdb->postmeta . " AS currency_monthly ON (" . $wpdb->posts . ".ID = currency_monthly.post_id AND (currency_monthly.meta_key = 'monthly_currency'))
INNER JOIN " . $wpdb->postmeta . " AS price_monthly ON (" . $wpdb->posts . ".ID = price_monthly.post_id AND (price_monthly.meta_key = 'monthly_price'))
INNER JOIN " . $wpdb->postmeta . " AS currency ON (" . $wpdb->posts . ".ID = currency.post_id AND (currency.meta_key = 'currency'))
INNER JOIN " . $wpdb->postmeta . " AS price ON (" . $wpdb->posts . ".ID = price.post_id AND (price.meta_key = 'price'))
INNER JOIN " . $wpdb->postmeta . " AS villa_code ON (" . $wpdb->posts . ".ID = villa_code.post_id AND villa_code.meta_key = 'code')
";
For now it's ordering by 2 columns, but I want to only 1 column that's price_in_usd (but it still showing the wrong villas)
$mam_global_orderby = "price_in_usd, price_in_usd_monthly " . $sort[1];
So how to do this the correct way? because I want to make a sorting programs that will sort the price from both price (yearly or monthly), so if the post have yearly price then the price will be divided by 12. Please help.
I already tried using COALESCE() but I'm stuck, and those codes were the latest version.
EDIT:
Actually I had an idea, but don't know how to do it, I want to get the meta_value to a temporary price, so the yearly or monthly price will be in 1 column, I already looked in google but didn't getting the answer.
EDIT:
What I want, I want to merge the value from two different meta_key (monthly_currency & currency) to a single custom column, that I'll use for sorting, all price will be converted to USD before sorted it, so as you can see, there are CASE currency.meta_value in my code. So after knowing the currency, it'll check if the price if for monthly or yearly, if it's for yearly then it'll divided by 12. So I can sort it by the lowest/highest price, even if it's monthly or yearly rent. The problem I got is, I can't get the correct result, because the price type (yearly / monthly) so how to do it?

MySQL Trigger code never called

I have a MySQL table like this
ID USER_ID FIELD_ID VALUE
1 1 1 0
2 1 2 2
3 1 3 0<----- USER ID 0
. . . .
. . . .
. . . .
40 20 1 6
41 20 2 3
42 20 3 1<------ USER ID 1
. . . .
. . . .
. . . .
73 34 1 9
74 34 2 6
75 34 3 20<----- user ID 20
. . . .
. . . .
. . . .
field_id #3 above contains either "0" or the ID of another user.
I'm trying to write a MYSQL trigger that runs BEFORE UPDATE so that if user "A" is writing the ID of user B into field_id #3, and if user "B" field_id #3 is not "0" then write "0" in to user "A" field_id #3.
so the pseudo code for the trigger is basically:
if (B["field_id3"]!="0") THEN
A["field_id3"]="0";
The MYSQL trigger code is below, but it doesnt do anything, there are no syntax errors, but it doesnt work, anybody can help?
BEGIN
IF (NEW.FIELD_ID='3') THEN
IF (EXISTS(SELECT USER_ID,FIELD_ID,VALUE FROM table WHERE USER_ID=NEW.VALUE)) THEN
IF (FIELD_ID='3' AND VALUE!='0') THEN
SET NEW.VALUE='0'; # <<---NEVER GETS CALLED
END IF;
END IF;
END IF;
END

How to add 'AND' parts to Joomla Jdatabase query?

I need to write an db query based on the Joomla jdatabase format, but I get stuck with writing the 2 'AND' parts for the native sql query below (I could not figure it out based on http://docs.joomla.org/Selecting_data_using_JDatabase).
How to include the 2 AND parts? Appreciate your help
//get userid of collective based on entered collective name, and get productid based on entered productname
//NATIVE MYSQL:
SELECT #__users.id, #__products.productid
FROM #__users INNER JOIN #__products
ON #__users.id = #__products.owner
AND #__users.name = $form_username
AND #__products.productname = $form_productname;
What I have sofar:
//Joomla Jdatabase query sofar:
$query
->select($db->quoteName(array('a.id', 'b.productid')))
->from($db->quoteName('#__users', 'a'))
->join('INNER', $db->quoteName('#__products', 'b') . ' ON (' . $db->quoteName('a.id') . ' = ' . $db->quoteName('b.owner') . ') ') //HERE I think some AND parts need to be included in some way?
->order($db->quoteName('a.created') . ' DESC');
I haven't tested this so please let me know if it works and if not, I will come back with an edit
->join('INNER', $db->quoteName('#__products', 'b') . ' ON (' . $db->quoteName('a.id') . ' = ' . $db->quoteName('b.owner') . ')
AND ' . $db->quoteName('#__users.name') . ' = ' . $form_username . '
AND ' . $db->quoteName('#__products.productname') . ' = ' . $form_productname)

How to return largest value of the selected row?

I'm trying to select latest date in row (not in column)
It must be 'articles_date_added' or 'articles_last_modified' in table like that
Id | ... | ... | articles_date_added | articles_last_modified | ...
My real query looks like:
select
a.articles_id, a.authors_id, a.articles_date_added,
a.articles_last_modified,
IF(a.articles_last_modified >= a.articles_date_added,
a.articles_last_modified,
a.articles_date_added) as latestdate,
ad.articles_viewed,
ad.articles_name, ad.articles_head_desc_tag,
COUNT(vh.articles_id) as total_votes,
SUM(v.vote_value)/COUNT(v.vote_value) AS vote_avg,
au.authors_name, td.topics_name, a2t.topics_id
from
" . TABLE_ARTICLES . " a
left join " . TABLE_AUTHORS . " au using(authors_id)
left join VOTE_HISTORY vh using (articles_id)
left join VOTE v using (vote_id),
" . TABLE_ARTICLES_DESCRIPTION . " ad,
" . TABLE_ARTICLES_TO_TOPICS . " a2t
left join " . TABLE_TOPICS_DESCRIPTION . " td using(topics_id)
where
(a.articles_date_available IS NULL or
to_days(a.articles_date_available) <= to_days(now())) and
a.articles_status = '1' and a.articles_id = a2t.articles_id and
ad.articles_id = a2t.articles_id and
ad.language_id = '" . (int)$languages_id . "'
and td.language_id = '" . (int)$languages_id . "'
and a2t.topics_id = '" . (int)$current_topic_id . "' and
au.authors_id = '" . (int)$_GET['filter_id'] . "'
GROUP BY a.articles_id
ORDER BY latestdate desc
As you can see to select it I use
IF(a.articles_last_modified >= a.articles_date_added,
a.articles_last_modified, a.articles_date_added) as latestdate
but it returms 1054 - Unknown column 'latestdate' in 'order clause
Why?
I'm on MySql 5.0.
Since adding is a modification, it'd be a good idea if your a.articles_last_modified would contain the same date as a.articles_date_added upon inserting a row.
UPDATE `articles`
SET `articles_last_modified` = `articles_date_added`
WHERE `articles_last_modified` = '0000-00-00 00:00:00'
ALTER TABLE `articles`
CHANGE COLUMN `articles_last_modified` `articles_last_modified`
TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;
This way you won't need this condition in where clausule

Sorting in mysql

I have a column abc in table t1. The column has values
A1
A2
A3
A4
.
.
A12
B1
B2
.
.
.
B12
C1
C2
.
.
.
C12
H1
.
.
H12
I wanna sort them such that the output is
A1
B1
C1
.
.
H1
A2
B2
C2
.
.
.
H2
.
.
.
.
A12
.
.
.
H12
A select * from abc statement gives A1,A10,A2.... as output. I am trying to use SUBSTR but haven't gotten it right.
This should do it;
SELECT * FROM TEST
ORDER BY SUBSTRING(VALUE, 2) + 0,
SUBSTRING(VALUE, 1, 1);
Demo here.
Considering the format is always a single alpha char followed by any number of digits:
ORDER BY RIGHT(colname, LENGTH(colname)-1)
maybe this:
ORDER BY LEFT(colname,1), RIGHT(colname, LENGTH(colname)-1)
order by lpad(date_created,1,0) ASC
#bfavaretto i think if you use -1 in length colname, and you have 3 characters like in example you will have some strange results.
SELECT Square
FROM Table1
ORDER BY
CASE WHEN Square REGEXP '^[A-Z]{2}'
THEN 1
ELSE 0
END ASC,
CASE WHEN Square REGEXP '^[A-Z]{2}'
THEN LEFT(Square, 2)
ELSE LEFT(Square, 1)
END ASC,
CASE WHEN Square REGEXP '^[A-Z]{2}'
THEN CAST(RIGHT(Square, LENGTH(Square) - 2) AS SIGNED)
ELSE CAST(RIGHT(Square, LENGTH(Square) - 1) AS SIGNED)
END ASC