Cast function output as column name - mysql

I have come across a scenario where I need to "cast" the output of a function as the column name I want to select:
(SELECT
LOWER(DATE_FORMAT(NOW(), '%b'))
FROM lang_months
WHERE langRef = lang_statements.langRef
) AS month
Just returns the current month which is expected, but I want this to select the column called "may" in this case.
How would I do this?
Thanks, your answer gave me an idea. I just put the current date into a variable and used that in the query like so:
$thisMonth = strtolower(date('M')) ;
(SELECT
$thisMonth
FROM lang_months
WHERE langRef = lang_statements.langRef
) AS month

This is not possible. The name of an entity must be known when the query reaches MySQL.
The easiest option would probably be to determine the column name in whatever language you're using then to just use that. For example, in PHP:
$col = 'someAlias';
$query = "SELECT blah as `{$col}` FROM tbl";

I don't think this is possible.
You could create a view that offers this view on your data so you can they query it more expressively, but you're still going to have to write those 12 subqueries and aliases by hand.

This should work:
$month = LOWER(DATE_FORMAT(NOW(), '%b')); // Results in 'may'
$result = mysql_query('SELECT * FROM $month'); // Returns all records in table 'may'

Related

How to count all records if use alias in select query?

I use Sphinx with Yii2 and need to query with filter by jSON field.
$query = new \yii\sphinx\Query();
$query->from('announcements');
$query->addSelect("*");
$query->addSelect(new Expression("IN(filters['color'], 'blue', 'red', 'green') AS f_color"));
$query->where("is_active = 1");
$query->andWhere("f_color = 1");
$announces = $query->all();
There is jSON field filters in my Sphinx index. For example:
[filters] => {"brand":"Toyota","model":"Prius","color":"red","price":"12000"... etc]
It works OK. But now I need to make a pagination... and there is a problem when I try to count records before $query->all()
$count = $query->count(); // Return error "no such filter attribute 'f_color'"
Generated query was:
SELECT COUNT(*) FROM announcements WHERE ( is_active = 1 ) AND ( f_color = 1 )
count() by default replaces the select part with * and this is where your alias is defined hence the error.
There are different ways to achieve it like:
use ActiveDataProvider like described here,
use META information like described here
Since you want to make a pagination I would go with the first example.

Using two sets of conditions in where clause

I'm trying to get the count of items in my table where it should satisfy these conditions
status = active
type = Pre-order
date = $date_input
OR
status = active
type = Both
date = $date_input
I'm trying to use this statement but I'm pretty sure it's messed up.
SELECT COUNT(id) as count_date from date_restriction
where (date='$date_input' AND status='active' AND type='Pre-order')
OR (date='$date_input' AND status='active' AND type='Both')
I also tried this to no avail
SELECT COUNT(id) as count_date from date_restriction
where date='$date_input' AND status='active' AND type='Pre-order' OR type='Both'
Whe you have mixed AND and OR condition you need () for the or clause
SELECT COUNT(id) as count_date
from date_restriction
where date='$date_input'
AND status='active'
AND ( type='Pre-order' OR type='Both')
or instear of several or condition you could use a IN clause
AND type IN ('Pre-order', 'Both')
anyway you should avoid the use of php var in SQL you are at risk for sqlinjection .. for avoid this you should take a look at prepared statement and binding param for your db driver
Your code should work. I would write this as:
select count(*) as count_date
from date_restriction
where date = ? AND status = 'active' AND
type in ('Pre-order', 'Both');
Note: The ? is for a parameter so you are not munging the query string with input values.
If I had to guess why this isn't working, I would speculate that one or both of the dates have a time component. You might try:
where date(date) = date(?) . . .
to be sure you are matching on the date, regardless of time.
SELECT count(id) as count_date
FROM date_restriction
WHERE date='$date_input' AND status='active' AND (type='Pre-order' OR type='Both');
Here, date and status both fields are common in your case; hence, don't wrap it in parenthesis whereas, add OR condition for type field only and con-cat it with AND in WHERE clause.

MYSQL ORDER BY CASE stored value

Im trying to show first the value that is stored in the 'zone' field, since each customer has different value, I want the one in his ZONE to show first in his lists. Thanks
first run a query for using the VAR later
$data = "SELECT * FROM users;
$datas = mysqli_query($con,$data) or die(mysqli_error($con));
$query = mysqli_fetch_array($datas);
Now I can use the {$query['zone']} and show those first in the query
"SELECT * FROM users WHERE ORDER by zone CASE zone WHEN '{$query['zone']}' THEN 0 ELSE 2'";
Im not getting the expected results, any advice? Thanks
I think you want something like this:
ORDER by (zone = '{$query['zone']}') desc,
zone
This assumes that the expression '{$query['zone']}' is the zone that you want to give priority to. User's whose zone's match this will appear first.

Yii2 select by max date?

Suppose I have table A with its active record in yii2, What is the best way to can load the record with max created date to the model.
This is the query :
select *
from A
where created_date = (
select max(created_date) from A
)
Now I am getting the max date first then use it in another access to database ie:
$max = A::find()->select("created_date)")->max();
$model = A::find()->where("created_date = :date",[":date"=>$max])->one();
I am sure that this can be done with one access to database , but I don't know how.
please any help.
Your query is the equivalent of:
SELECT * FROM A ORDER BY created_date DESC LIMIT 1;
You can order your records by created_date in descending order and get the first record i.e:
$model = A::find()->orderBy('created_date DESC')->limit(1)->one();
Why limit(1)? As pointed out by nicolascolman, according to the official Yii documentation:
Neither yii\db\ActiveRecord::findOne() nor yii\db\ActiveQuery::one() will add LIMIT 1 to the generated SQL statement. If your query may return many rows of data, you should call limit(1) explicitly to improve the performance, e.g., Customer::find()->limit(1)->one().
$maxdate=A::find()->max('created_date');
Try this
$model = A::find()->orderBy("created_date DESC")->one();

MySql dynamic column name

[major edit to make things clear]
I want to write a query that returns a dynamic column name like this:
SELECT
f2 AS
(
SELECT column_name
FROM column_names_tbl
WHERE column_name = "experience"
limit 0,1
)
FROM some_table
so that would output the same as this:
SELECT
f2 AS experience
FROM some_table
This is no correct SQL syntax, even because the two queries (the selected field and it's alias) are both subqueries and unrelated to each other. So, there's also no possibility for mysql to distinguish what name you want to connect to what value, even if the syntax was correct...
You already use a more or less normalized relational table, so I suggest the following solution:
you select the revision ID and name in a separate query; store them in PHP and use them for whatever you want
next, you evaluate the following query into a separated result set: SELECT ps.keyname, psv.keyvalue FROM page_setting_values AS psv INNER JOIN page_settings AS ps ON ps.id = psv.setting_id WHERE psv.page_revision_id = :revision with :revision representing your revision id
you may now assemble an associated array from that result set:
$settings = [];
$result = $db->executeQuery('...')->fetchAll();
foreach($result as $setting)
{
$settings[$setting['keyname']] = $setting['keyvalue'];
}
Hope that helps ;)