I use Doctirine 2 and zf2. How can i convert this sql query to dql. (Doctirine Query Language)
My product entity is here "Application\Entity\Product" I 've tried it but it doesn't work..
Thanks for your help.
SELECT price_range, count(*) AS num
FROM
(SELECT CASE WHEN price >= 0 AND price <= 10 THEN '0-10'
WHEN price >= 10 AND price <= 20 THEN '10-20'
WHEN price >= 20 AND price <= 30 THEN '30-40'
WHEN price >= 30 AND price <= 40 THEN '30-40'
WHEN price >= 40 AND price <= 50 THEN '40-50'
WHEN price >= 50 AND price <= 60 THEN '50-60'
WHEN price >= 60 AND price <= 70 THEN '60-70'
WHEN price >= 70 AND price <= 80 THEN '70-80'
WHEN price >= 80 AND price <= 90 THEN '90-100'
WHEN price >= 100 AND price <= 110 THEN '100-110'
ELSE 'over 1000'
END as price_range
FROM product
WHERE 1
) AS price_summaries
GROUP BY price_range
Well, unfortunately you can't. Doctrine doesn't support CASE. And looking at your problem, I'm also unable to find an adequate other solution with DQL.
You can however use a native query. Native queries are embedded raw SQL queries, basically an extension of PDO.
Native queries are of course generally discouraged, as they have two disadvantages:
You must do the hydration into Doctrine entities yourself, using ResultSetMapping (if you want the result of the query to contain ready-made entities instead of plain arrays/objects).
Native queries undermine the whole point of using a DBAL: you loose portability. (But, to be honest, most projects don't just switch their RDBMS, so it's a rather theoretical concern).
But if you need to have the above query executed, use a native query in this single case.
Doctirine support case statement.
This works
SELECT CASE WHEN (p.price >= 0 AND p.price <= 10) THEN '0-10'
WHEN (p.price >= 10 AND p.price <= 20) THEN '10-20'
WHEN (p.price >= 20 AND p.price <= 30) THEN '30-40'
WHEN (p.price >= 30 AND p.price <= 40) THEN '30-40'
WHEN (p.price >= 40 AND p.price <= 50) THEN '40-50'
WHEN (p.price >= 50 AND p.price <= 60) THEN '50-60'
WHEN (p.price >= 60 AND p.price <= 70) THEN '60-70'
WHEN (p.price >= 70 AND p.price <= 80) THEN '70-80'
WHEN (p.price >= 80 AND p.price <= 90) THEN '90-100'
WHEN (p.price >= 100 AND p.price <= 110) THEN '100-110'
ELSE 'over 1000'
END as price_range
FROM \Application\Entity\Product p
But this doesn't work, i think i should try native query
SELECT price_range, count(*) AS num
FROM
(SELECT CASE WHEN (p.price >= 0 AND p.price <= 10) THEN '0-10'
WHEN (p.price >= 10 AND p.price <= 20) THEN '10-20'
WHEN (p.price >= 20 AND p.price <= 30) THEN '30-40'
WHEN (p.price >= 30 AND p.price <= 40) THEN '30-40'
WHEN (p.price >= 40 AND p.price <= 50) THEN '40-50'
WHEN (p.price >= 50 AND p.price <= 60) THEN '50-60'
WHEN (p.price >= 60 AND p.price <= 70) THEN '60-70'
WHEN (p.price >= 70 AND p.price <= 80) THEN '70-80'
WHEN (p.price >= 80 AND p.price <= 90) THEN '90-100'
WHEN (p.price >= 100 AND p.price <= 110) THEN '100-110'
ELSE 'over 1000'
END as price_range
FROM \Application\Entity\Product p
) AS price_summaries
GROUP BY price_range
Related
Is there a way in which I can write a dynamic conditional statement. For example, I want to see that my data can be grouped by 50 or 100 by just tipping the value 50 or 100.
table = generate(1,9000000, 0.01)
Here there is an example, when I want to group the data by 50
= Table.AddColumn(one_pm_test_lm_5_sek_xyl_1_Table, "XLenght bin", each if
[XLength] >= 500 then "500 and above"
else if [XLength] >= 450 then "450 - 500"
else if [XLength] >= 400 then "400 - 450"
else if [XLength] >= 350 then "350 - 400"
else if [XLength] >= 300 then "300 - 350"
else if [XLength] >= 250 then "250 - 300"
else if [XLength] >= 200 then "200 - 250"
else if [XLength] >= 150 then "150 - 200"
else if [XLength] >= 100 then "100 - 150"
else if [XLength] >= 50 then "50 - 100"
else "50 or below")
I try to create a dynamic function or something like that which makes posible that I group the data for example in 50. Until now, I make it manually. I would like to know if there is another way to do it in order to enter the values manually.
XLength Group = SWITCH(TRUE(),
[XLength] < 50, "<50",
[XLength] <= 100, "50-100",
[XLength] <= 150, "100-150",
[XLength] <= 200, "150-200",
[XLength] <= 250, "200-250",
[XLength] <= 300, "250-300",
[XLength] <= 350, "300-350",
[XLength] <= 400, "350-400",
[XLength] <= 450, "400-450",
[XLength] <= 500, "450-500",
[XLength] > 500, "500+")
How to write the following if-else condition in Linear Programming?
If YR1 == 1 , then 20 <= XR1 <= 80, else XR1 = 0
YR1 is a binary variable, XR1 is a continuous variable.
I tried
20 - XR1 <= 1000 * (1 - YR1)
80 - XR1 <= 1000 * (1 - YR1)
XR1 - 20 <= 1000 * YR1
Is it correct? If not, how can I convert the statement to linear programming conditions?
XR1 is called a semi-continuous variable. It can be modeled as:
20*YR1 <= XR1 <= 80*YR1
YR1 ∈ {0,1}
You need to split this into two inequalities.
I use following block of code to test some conditions in gw-basic program.
IF Average >= 80 AND Average <= 100 THEN Grade$ = "A"
IF Average >= 70 AND Average <= 79 THEN Grade$ = "B"
IF Average >= 60 AND Average <= 69 THEN Grade$ = "C"
IF Average >= 50 AND Average <= 59 THEN Grade$ = "D"
IF Average >= 40 AND Average <= 49 THEN Grade$ = "E" ELSE Grade$ = "F"
PRINT "Average is: ", Average
PRINT "Grade is: ", Grade$
It always prints Grade is: F whatever is the value of Àverage.
What is the error in this gw-basic program?
IF Average >= 40 AND Average <= 49 THEN Grade$ = "E" ELSE Grade$ = "F"
Because this IF THEN ELSE line will always assign a value to Grade$ (no matter the content of Average), all of the previous IF THEN's don't count for much.
The solution however is very, very simple. Don't use the ELSE clause and give the Grade$ a default value of "F" to start with. That way, only if all of those conditions evaluate to false, the program will return "Grade is: F".
Grade$ = "F"
IF Average >= 80 AND Average <= 100 THEN Grade$ = "A"
IF Average >= 70 AND Average <= 79 THEN Grade$ = "B"
IF Average >= 60 AND Average <= 69 THEN Grade$ = "C"
IF Average >= 50 AND Average <= 59 THEN Grade$ = "D"
IF Average >= 40 AND Average <= 49 THEN Grade$ = "E"
PRINT "Average is: ", Average
PRINT "Grade is: ", Grade$
suppose print average line is line number 70, so after each line except the ELSE line write GOTO 70. Try if that works.
I'm having trouble deciphering this bit of code. I've encountered a return statement as complicated as this, so can someone break it down for me? (This code was from a problem in which I had to differentiate between a leap year and a non-leap year). Thanks!
return ((year % 4) || (!(year % 100) && ((year+300) % 400))) ? 28 : 29;
It's just a conditional expression, condition ? true_value : false_value.
It gets clearer if you separate out the condition:
bool not_leap_year = (year % 4) || (!(year % 100) && ((year+300) % 400));
return not_leap_year ? 28 : 29;
It's more common to compute the negation of the condition though, as the rules for when there is a leap year are better known than the rules for when there isn't (so there's less chance of bugs).
bool leap_year = year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
return leap_year ? 29 : 28;
((year % 4) || (!(year % 100) && ((year+300) % 400))) ? 28 : 29;
This is the ternary operator ? with a relatively complex boolean expression. You could achieve the same with an if expression:
if ( (year % 4) // year not dividable by 4
or
(
not (year % 100) // year dividable by 100
and
((year+300) % 400))) // year + 300 not dividable by 400
{
return 28;
}
else
{
return 29;
}
One can make that a bit more readable using a helper function:
bool dividableBy(unsigned value, unsigned divisor) {
return value % divisor == 0;
}
//...
if ((not dividableBy(year, 4)) or
(dividableBy(year, 100) and
(not dividableBy(year+300, 400)))) {
return 28;
}
else {
return 29;
}
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
if (month > 0 && month <= 12)
if (day > 0 && day <= checkDays(month, year))
if (year >= 1752 || year <= 9999)
if((month != 12 && day != 31 && year != 9999))
return true;
else return false;
else return false;
else return false;
else return false;
I have the values month = 12, days = 31, and year = 2008 and the data validation is failing at the last part, but I cannot figure out why.
Your first year condition uses OR when you wanted AND; your second year condition is exactly inverted from what I suspect you wanted.
You also have an order-of-operations bug: you can't check the day until after you validate the month and the year (assuming what checkDays does is provide the maximum day number for a particular (month, year) pair; if so, you should rename it days_in_month).
Finally, code like this is generally much easier to read if written as a series of if-fail-return-false conditions without any nesting. Like so:
// Year range supported is [1752, 9999].
// (Gregorian calendar introduced in 1752 in Great Britain.)
if (year < 1752 || year > 9999)
return false;
// Valid month numbers in [1, 12].
if (month < 1 || month > 12)
return false;
// Valid day numbers in [1, n] where n depends on month and year.
if (day < 1 || day > checkDays(month, year))
return false;
// 9999-12-31 is invalid (used as a sentinel value?)
if (year == 9999 && month == 12 && day == 31)
return false;
return true;
By the way, the Long Now people would like a word regarding your upper year limit.
I find it's nearly always easier to write these things with the "find the false things and return". So:
if (month < 1 || month > 12) return false;
if (day < 1 || day > 31) return false;
if (year < 1752 || year > 9999) return false;
if (month == 12 && day == 31 && year == 9999) return false;
// If we get here, everything is fine, so return true.
return true;
Of course, you should probably check the day based on which month it is:
int daysInMonth[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
if (month < 1 || month > 12) return false; // Must do this before checking day!
int daysThisMonth = daysInMonth[month];
// Check for leapyear.
if (month == 2 && year % 4 == 0 && (year % 100 != 0 || year % 400 == 0))
{
daysThisMonth = 29;
}
if (month != 2 && day < 1 || day > daysThisMonth) return false;
...
A bit of speculation, since I don't quite know what your function is supposed to do, but here goes.
month != 12 && day != 31 && year != 9999 only returns true if the month is not 12 and the day is not 31 and the year is not 9999.
So for your input, it's:
month != 12 && day != 31 && year != 9999
=> false && false && true
=> false
Don't you maybe want:
month != 12 || day != 31 || year != 9999
Which will return true if either the month is not 12 or the day is not 31 or the year is not 9999.
An equivalent, but possibly more understandable way of writing it:
!(month == 12 && day == 31 && year == 9999)
So that's "if the month is 12 and the day 31 and the year 9999, return false".