Mysql if statement to select multiple rows - mysql

I need to retrieve a set of data if a condition is true, and a set of other ata if the condition is false.
I searched in mysql manual and I tested the select case when statement, but as my subqueries return multiple rows, I'm not able to use it.
Is it a simple way to write a query with if statement? (without using stored procedure)
Here is my condition:
select case when ( right(from_unixtime(300 * floor(unix_timestamp(now())/300)) - INTERVAL 10 MINUTE, 8) = '23:50:00' ) then ( select SERVER_KEY from OVERSERVER ) else ( select SERVER_KEY from SERVER ) end;
Thanks

try something like this:
select SERVER_KEY from OVERSERVER
where right(from_unixtime(300 * floor(unix_timestamp(now())/300)) - INTERVAL 10 MINUTE, 8) = '23:50:00'
union all
select SERVER_KEY from SERVER
where right(from_unixtime(300 * floor(unix_timestamp(now())/300)) - INTERVAL 10 MINUTE, 8) != '23:50:00'

I am not sure but just give a try this-
select SERVER_KEY from (case when ( right(from_unixtime(300 * floor(unix_timestamp(now())/300)) - INTERVAL 10 MINUTE, 8) = '23:50:00' ) then "OVERSERVER" else "SERVER"
OR
select SERVER_KEY from (case when ( right(from_unixtime(300 * floor(unix_timestamp(now())/300)) - INTERVAL 10 MINUTE, 8) = '23:50:00' ) then OVERSERVER else SERVER
Note: above query is not tested.

Related

wrong order in SQL using PDO

I have this query, which will be stored in a variable named $query (the actual query is much more complex, but this example successfully addresses my problem):
select * from
(
select
id_field as 'id',
date_field as 'date',
name_field as 'name',
cast((#counter := #counter + 1) AS SIGNED) as 'counter'
from my_table
cross join (select #counter := 0) as tmp
) as x
At some point, the final query will be:
$final_sql = "select * from ($query) t order by date desc"; //this can't be changed
What's happening is that I'm not getting the rows ordered by date, instead I'm getting some random order.
I've narrowed the problem to the double select * from while running the query with php/pdo on the server (localhost works fine). If I run the raw sql directly in database (localhost or server) it also works fine
If $query was like this, then I get the correct order (select * from removed):
select
id_field as 'id',
date_field as 'date',
name_field as 'name',
cast((#counter := #counter + 1) AS SIGNED) as 'counter'
from my_table
cross join (select #counter := 0) as tmp
But I've also noticed that if I keep the double select * from and get rid of the variables, then it will work as expected (but I need that column so it's not an option)
select * from
(
select
id_field as 'id',
date_field as 'date',
name_field as 'name'
from my_table
) as x
So, what is going on here?! How can I make it work on my server, just like my localhost?
localhost:
db > MySQL 8.0.25
php > 7.3.27
pdo > mysqlnd 5.0.12-dev - 20150407
server:
db > MariaDB 10.1.44
php > 7.3.17
pdo > mysqlnd 5.0.12-dev - 20150407
By nature the resultset of subquery are unsorted, while mysql keeps it mariadb skips it
What you can do is making a LIMIT with an ORDER BY so that mysql and mariadb keops the order you need
select * from
(
select
id_field as 'id',
date_field as 'date',
name_field as 'name',
cast((#counter := #counter + 1) AS SIGNED) as 'counter'
from my_table
cross join (select #counter := 0) as tmp
ORDER BY date_field
LIMIT 18446744073709551615
) as x

SQL Query Case with Where/Having Clause

How do you apply a Where or Having clause to a query? I am having problems with the Having clause.
DECLARE #dtDate DATE
SET #dtDate = GETDATE();
with EMS as
(
select * from ReportingView.WTA where FiscalMonth = DATENAME(MONTH, #dtDate) + ', ' + DATENAME(YEAR, #dtDate) and ProductGroup = 'AAD'
)
select
[ID]
,(CASE
WHEN Entitlements <= 0 THEN '0'
ELSE CAST([Activations] as float) / [Entitlements]
END) as Utilization
from EMS
**HAVING Utilization >= .25**
The HAVING keyword is only used if you are using a GROUP BY too. What you want is a WHERE but you will not be able to reference Utilization unless you wrap it in a sub select.
Both a where and a having clause go at the end of your query. If you have both, then the where comes before the having.
In your case, your having is not working, because having is only to be used with group by. having is essentially a where clause for aggregate values (such as sum, count, etc)
Examples:
WHERE
SELECT
*
FROM
EMS
WHERE
Utilization >= 0.25
HAVING
SELECT
col1, count(*)
FROM
EMS
GROUP BY
col1
HAVING
count(*) > 10
HAVING and WHERE
SELECT
col1, count(*)
FROM
EMS
WHERE
Utilization >= 0.25
GROUP BY
col1
HAVING
count(*) > 10
Edit: This modified query should work for you. I'm not sure why your original query was using a CTE, but I've moved the case logic to the CTE.
with EMS as
(
select
[ID],
(
CASE
WHEN Entitlements <= 0 THEN '0'
ELSE CAST([Activations] as float) / [Entitlements]
END
) as Utilization
from
ReportingView.WTA
where
FiscalMonth = DATENAME(MONTH, #dtDate) + ', ' + DATENAME(YEAR, #dtDate)
and ProductGroup = 'AAD'
)
select
*
from
EMS
where
Utilizaiton >= .25

Select in Concat mysql

I'm trying to get a date value with:
- Current year
- Current month
- Day number from one select
the query
SELECT rat_data FROM rate_unita WHERE rateid = 1
as a result one INT value.
When I try to execute the following:
SELECT DATE(CONCAT(YEAR(NOW())),(MONTH(NOW())), (SELECT rat_data FROM rate_unita WHERE rateid = 1))
Mysql mark my syntax as incorrect near ' ( MONTH( NOW( ) ) ) , ( SELECT rat_data FROM rate_unita WHERE r
I think that there is something wrong with the way I'm calling the SELECT in the CONCAT, what is the correct query to reach my goal?
Thanks
L
You're closing the concat function too early. Remove some extra parentheis
SELECT DATE(CONCAT(YEAR(NOW()),
MONTH(NOW()),
(SELECT rat_data FROM rate_unita WHERE rateid = 1)
))
But you need to add some hyphens to make it a true date value
SELECT DATE(
CONCAT(
YEAR(NOW()),
'-',
MONTH(NOW()),
'-',
(SELECT rat_data FROM rate_unita WHERE rateid = 1)
)
)
This should result in a date of YEAR-MONTH-rat_data
Here's a working SQL Fiddle
Use DATE_FORMAT function. Here are a few examples:
http://www.w3schools.com/sql/func_date_format.asp
http://www.mysqltutorial.org/mysql-date_format/

calculate percentage with subqueries

I'm trying to calculate a percentage in my SQL query.
This is what I have right now:
SELECT
DATE(processed_at) AS day,
(
SELECT
COUNT(*) FROM return_items
WHERE return_id IN (SELECT id FROM returns WHERE DATE(processed_at) = day)
) as products_returned,
COUNT(*) as return_count,
(
SELECT
COUNT(*) as co_returns
FROM returns
WHERE return_method = 'mondial_relais'
AND DATE(processed_at) = day
) as return_rate_mr
FROM returns
WHERE MONTH(processed_at) = 10
AND YEAR(processed_at) = 2011
GROUP BY day;
Basically I need the return_rate_mr to be a percentage value.
I tried doing something like return_rate_mr * 100 / return_count as perc_value but this doesn't work. (I don't actually need the current return_rate_mr value, just the percentage.
Any ideas?
Assuming your original query returns the desired results, you can wrap it as a subquery:
SELECT
day,
return_rate_mr * 100 / return_count as perc_value,
... any other columns ...
FROM
( ... your original query here ...) as myalias;
Basically, the subquery creates a result set where the columns are renamed. Then, the outer query is free to use those new column names.
Are you looking for this?
SELECT
`day`,
`products_returned`,
(`return_rate_mr` * 100) / `return_count` AS `percentage`
FROM (
SELECT
DATE(processed_at) AS day,
(
SELECT
COUNT(*) FROM return_items
WHERE return_id IN (SELECT id FROM returns WHERE DATE(processed_at) = day)
) as products_returned,
COUNT(*) as return_count,
(
SELECT
COUNT(*) as co_returns
FROM returns
WHERE return_method = 'mondial_relais'
AND DATE(processed_at) = day
) as return_rate_mr
FROM returns
WHERE MONTH(processed_at) = 10
AND YEAR(processed_at) = 2011
GROUP BY day) AS `ss`
Did you try something like:
SELECT (`return_rate_mr` * 100 ) / `return_count` as "yourValue", OthersFields
FROM SELECT
DATE(processed_at) AS day,
(
SELECT
COUNT(*) FROM return_items
WHERE return_id IN (SELECT id FROM returns WHERE DATE(processed_at) = day)
) as products_returned,
COUNT(*) as return_count,
(
SELECT
COUNT(*) as co_returns
FROM returns
WHERE return_method = 'mondial_relais'
AND DATE(processed_at) = day
) as return_rate_mr
FROM returns
WHERE MONTH(processed_at) = 10
AND YEAR(processed_at) = 2011
GROUP BY day;
Hope this helps
Try:
SELECT DATE(processed_at) AS day,
count(distinct id) as products_returned,
COUNT(*) as return_count,
100* sum(case return_method when 'mondial_relais' then 1 end) / COUNT(*)
as return_perc_mr
FROM returns
WHERE MONTH(processed_at) = 10
AND YEAR(processed_at) = 2011
GROUP BY day;
I suspect that products_returned should be counting distinct item_id values (or something similar), but this should duplicate the logic in the original query.

How to get mysql random integer range?

I am trying to generate a random integer for each row I select between 1 and 60 as timer.
SELECT downloads.date, products.*, (FLOOR(1 + RAND() * 60)) AS timer
I have searched and keep coming up to this FLOOR function as how to select a random integer in a range. This is giving me a 1 for every row.
What am I missing?
I am on mysql 5.0.75
Heres the rest of the query I belive it might be a nesting issue
SELECT *
FROM (
SELECT downloads.date, products.*, FLOOR(1 + (RAND() * 60)) AS randomtimer,
(
SELECT COUNT( * )
FROM distros
WHERE distros.product_id = products.product_id
) AS distro_count,
(SELECT COUNT(*) FROM downloads WHERE downloads.product_id = products.product_id) AS true_downloads
FROM downloads
INNER JOIN products ON downloads.product_id = downloads.product_id
) AS count_table
WHERE count_table.distro_count > 0
AND count_table.active = 1
ORDER BY count_table.randomtimer , count_table.date DESC LIMIT 10
This is working for me. Your mysql version maybe?
SELECT id, (FLOOR( 1 + RAND( ) *60 )) AS timer
FROM users
LIMIT 0 , 30
The output of the RAND function will always be a value between 0 and 1.
Try this:
SELECT downloads.date, products.*, (CAST(RAND() * 60 AS UNSIGNED) + 1) AS timer
Old question, but always actual problem.
Here a way to create a MySQL function random_integer() based on manual :
CREATE FUNCTION random_integer(value_minimum INT, value_maximum INT)
RETURNS INT
COMMENT 'Gets a random integer between value_minimum and value_maximum, bounds included'
RETURN FLOOR(value_minimum + RAND() * (value_maximum - value_minimum + 1));
SELECT ALL random_integer(1, 60) AS timer;
I'm running your query and it does give me a random number for each row.... maybe has something to do with the name of the random (timer)?
You can increase the number multiplied by the number of records in the table.
SELECT id,
(FLOOR( (SELECT MIN(id) FROM your_table ) + RAND( ) * 1000000 ) ) AS timer
FROM your_table
LIMIT 0 , 30