Goal: I want to create a report showing each member experience since joining date with case condition showing 3 categories.
I managed to get the experience(in days) from joining date of the member. trying to derive new column categories say low, med and high. I have tried the below query but it is not working, The below query works for non-date values in reg_date column.
select m.member_id, m.first_name, m.last_name, m.store_id,
(case when m.reg_date<='2018-04-01' then "low"
case when m.reg_date>'2018-04-01' and m.reg_date<='2018-07-31' then "med"
case when m.reg_date>'2018-07-31' then "high"
end, '%y%m%d') as category from member m;
multiple bugs:
syntax should be (case when ... when ... when ...) instead of case for each 'when'.
second argument you pass '%y%m%d' is not necessary.
not a bug, but for the sake of clarity, consider using "else" for the last case.
(case
when m.reg_date<='2018-04-01' then "low"
when m.reg_date>'2018-04-01' and m.reg_date<='2018-07-31' then "med"
else "high"
end)
Related
The scenario is that i have two columns one is Quantity and other is Type. Now what i am trying to do is check if type is "rec" then it take all the values from quantity and add them and if the type is "issue" then it will get only those fields whose type is receiving and add them all on the basis of ITEM ID. The SQL Query i have written is here:
SELECT f.`Itemm_ID`,ABS(SUM(f.`Quantity`)) AS recieving, TYPE ,
(CASE
WHEN f.`Type` = 'issue'
THEN ABS(SUM(f.`Quantity`))
END)
FROM stock_journal AS f
WHERE f.`Itemm_ID`='1'
Now the thing is everything is working fine except CASE statement which is returning null.
Please help me in resolving my issue. Thank you
It seems that you need in
SELECT f.`Itemm_ID`,
ABS(SUM(f.`Quantity`)) AS recieving,
TYPE,
ABS(SUM(CASE WHEN f.`Type` = 'issue'
THEN f.`Quantity`
ELSE 0
END))
FROM stock_journal AS f
WHERE f.`Itemm_ID`='1'
PS. Does f.Quantity may be negative? If not then ABS() is excess. If it may then ABS() must wrap inner f.Quantity, not the whole SUM(), maybe.
PPS. TYPE in output is formally incorrect (contradicts with ONLY_FULL_GROUP_BY), I'd recommend wrap it with ANY_VALUE().
i didn't get your recommendation of wrapping type with value can you please elaborate more.
I mean that (maybe, I'm not sure) you need
SELECT f.`Itemm_ID`,
SUM(ABS(f.`Quantity`)) AS recieving,
TYPE,
SUM(CASE WHEN f.`Type` = 'issue'
THEN ABS(f.`Quantity`)
ELSE 0
END)
FROM stock_journal AS f
WHERE f.`Itemm_ID`='1'
Have you checked syntax for CASE I think you are missing ELSE part in the query
Eg:-
SELECT OrderID, Quantity,
CASE
WHEN Quantity > 30 THEN "The quantity is greater than 30"
WHEN Quantity = 30 THEN "The quantity is 30"
ELSE "The quantity is under 30"
END
FROM OrderDetails;
check here for syntax
i have a order table with columns scheduled_arrival_date and actual_arrival_date , i need to find out which order delivered early and late and i need to differentiate orders based on that(two columns should be created ) , as i don't have permission to create new table so i need get this from query.
i tried this, but am getting in single column
SELECT order.id,order.item,
CASE WHEN scheduled_arrival_date >= actual_arrival_date
THEN 'late'
WHEN scheduled_arrival_date <= actual_arrival_date
THEN 'Early'
END as delivered
FROM order
SELECT order.id, order.item, 'late' AS late FROM order WHERE scheduled_arrival_date > actual_arrival_date
UNION ALL
SELECT order.id, order.item, 'early' AS early FROM order WHERE scheduled_arrival_date <= actual_arrival_date
This query is definely not optimized, but it will work. The first query gather all late shippings and put 'late' into the late column. The second one do the exact same trick but with early, and we union all of the result together.
However, i don't really understand why you want two columns, it looks weird this way, your initial request was much better IMO.
PS: Note that you should not use <= and >= in both of your condition, there is a conflit for the equal case
As you want to create a pie diagram it seems to me that you are only interested in the numbers (counts) of the two cases. You can do that like this:
SELECT COUNT(CASE WHEN actual_arrival_date-scheduled_arrival_date>0 THEN 1 END) late,
COUNT(CASE WHEN actual_arrival_date-scheduled_arrival_date<=0 THEN 1 END) early
FROM order
I am at the final stage of my project and have the problem to find if a job is overdue. I link this to priority for example if a job has a priority of 1 it must be complete in 1 day, a priority of 4 then 4 days.
I have come up with a CASE however this doesn't seem to work any help would be appreciated.
SELECT `defect_Id`,`Overtasked`
WHERE
CASE DATEDIFF(DD,`date_Investigaton` - `CURRENT_DATE()`) >= `priority` AS Overtasked
THEN `Overtasked` == 'YES'
ELSE `Overtasked` == 'NO'
END
Solution
`SELECT defect_Id,
CASE WHEN DATEDIFF(date_Investigated, CURDATE()) >= priority
THEN 'YES'
ELSE 'NO'
END AS Overtasked
FROM defect_report
WHERE defect_Id = '82'`
Appreciate the guidance you guys give!
You are completely mixing up SQL dialects and even there are syntax errors.
Assuming you are talking about MS SQL Server let's try this:
SELECT defect_Id,
CASE WHEN DATEDIFF(DD, date_Investigaton, getdate()) >= priority
THEN 'YES'
ELSE 'NO'
END AS Overtasked
FROM <YourTable>
WHERE <YourWhereIfAny>
If date_Investigation is a DATE column, the subtraction date_Investigation - CURRENT_DATE() produces the number of days you need.
Otherwise (if it is a DATETIME, for example) both operands are converted to float and the result is something you are totally not expecting. For such situations use the DATEDIFF() function. It interprets its arguments as DATE (ignores the time part) and returns the integer number of days between the two dates.
Your query should be like:
SELECT
`defect_Id`,
IF (DATEDIFF(`date_Investigaton`, CURRENT_DATE()) >= `priority`, 'YES', 'NO')
AS `Overtasked`
FROM [...your table name here...]
WHERE [...conditions...]
Replace the parts in square brackets ([...]) with the name of the table where to get the data from and some conditions to limit the number of returned rows (otherwise it will get the entire table which, most probably, is not what you want).
Btw, CURRENT_DATE() is also a function. If you write it in backquotes (``), MySQL will try to find a column with this name and it will fail.
Read the accepted answer for this question. It explains when to use back ticks, single quotes or double quotes in MySQL (and partially in PHP).
I have searched SO for this question and found slightly similar posts but was unable to adapt to my needs.
I have a database with server requests since forever, each one with a timestamp and i'm trying to come up with a query that allows me to create a heatmatrix chart (CCC HeatGrid).
The sql query result must represent the server load grouped by each hour of each weekday.
Like this: Example table
I just need the SQL query, i know how to create the chart.
Thank you,
Those looks like "counts" of rows.
One of the issues is "sparse" data, we can address that later.
To get the day of the week ('Sunday','Monday',etc.) returned, you can use the DATE_FORMAT function. To get those ordered, we need to include an integer value 0 through 6, or 1 through 7. We can use an ORDER BY clause on that expression to get the rows returned in the order we want.
To get the "hour" across the top, we can use expressions in the SELECT list that conditionally increments the count.
Assuming your timestamp column is named ts, and assuming you want to pull all rows from the year 2014, we start with something like this:
SELECT DAYOFWEEK(t.ts)
, DATE_FORMAT(t.ts,'%W')
FROM mytable t
WHERE t.ts >= '2014-01-01'
AND t.ts < '2015-01-01'
GROUP BY DAYOFWEEK(t.ts)
ORDER BY DAYOFWEEK(t.ts)
(I need to check the MySQL documentation, WEEKDAY and DAYOFWEEK are real similar, but we want the one that returns lowest value for Sunday, and highest value for Saturday... i think we want DAYOFWEEK, easy enough to fix later)
The "trick" now is the columns across the top.
We can extract the "hour" from timestamp using the DATE_FORMAT() function, the HOUR() function, or an EXTRACT() function... take your pick.
The expressions we want are going to return a 1 if the timestamp is in the specified hour, and a zero otherwise. Then, we can use a SUM() aggregate to count up the 1. A boolean expression returns a value of 1 for TRUE and 0 for FALSE.
, SUM( HOUR(t.ts)=0 ) AS `h0`
, SUM( HOUR(t.ts)=1 ) AS `h1`
, SUM( HOUR(t.ts)=2 ) AS `h2`
, '...'
, SUM( HOUR(t.ts)=22 ) AS `h22`
, SUM( HOUR(t.ts)=23 ) AS `h23`
A boolean expression can also evaluate to NULL, but since we have a predicate (i.e. condition in the WHERE clause) that ensures us that ts can't be NULL, that won't be an issue.
The other issue we can encounter (as I mentioned earlier) is "sparse" data. To illustrate that, consider what happens (with our query) if there are no rows that have a ts value for a Monday. What happens is that we don't get a row in the resultset for Monday. If it does happen that a row is "missing" for Monday (or any day of the week), we do know that all of the hourly counts across the "missing" Monday row would all be zero.
Good morning,
I am trying to combine two queries into one so that the result array can be populated into a single table. Data is pulled from a single table, and math calculations must take place for one of the columns. Here is what I have currently:
SELECT
laboratory,
SUM(total_produced_week) AS total_produced_sum,
SUM(total_produced_over14) AS total_over14_sum,
100*(SUM(total_produced_over14)/sum(total_produced_week)) as divided_sum,
max(case when metrics_date =maxdate then total_backlog else null end) as total_backlog,
max(case when metrics_date =maxdate then days_workable else null end) as days_workable,
max(case when metrics_date =maxdate then workable_backlog else null end) as workable_backlog,
max(case when metrics_date =maxdate then deferred_over_30_days else null end) as deferred_over_30_days
FROM
test,
(
select max(metrics_date) as maxdate
from metrics
) as x
WHERE
YEAR(metrics_date) = YEAR(CURDATE())
AND MONTH(metrics_date) = MONTH(CURDATE())
GROUP BY
laboratory
ORDER BY 1 ASC
Here's the breakdown:
For each laboratory site, I need:
1) Perform a MONTH TO DATE (current month only) sum, division and multiply by 100 for each site to obtain percentage.
2) Display other columns (total_backlog, days_workable, workable_backlog, deferred_over_30_days) for the most recent update date (metrics_date) only.
The above query performs #1 just fine - I get a total_produced_sum, total_over14_sum and divided_sum column with correct math.
The other columns mentioned in #2, however, return NULL. Data is available in the table for the most recently updated date, so the columns should be reporting that data. It seems like I have a problem with the CASE, but I'm not very familiar with the function so it could be incorrect.
I am running MySQL 5.0.45
Thanks in advance for any suggestions!
Chris
P.S. Here are the two original queries that work correctly. These need to be combined so that the full resultset can be output to a table, organized by laboratory.
Query 1:
SELECT SUM(total_produced_week) AS total_produced_sum,
SUM(total_produced_over14) AS total_over14_sum
FROM test
WHERE laboratory = 'Site1'
AND YEAR(metrics_date) = YEAR(CURDATE()) AND MONTH(metrics_date) = MONTH(CURDATE())
Query 2:
SELECT laboratory, total_backlog, days_workable, workable_backlog, deferred_over_30_days,
items_over_10_days, open_ncs, total_produced_week, total_produced_over14
FROM metrics
WHERE metrics_date = (select MAX(metrics_date) FROM metrics)
ORDER BY laboratory ASC
Operator Error.
I created a copy of the original table (named "metrics") to a table named "test". I then modified the metrics_date in the new "test" table to include data from January 2011 (for the month-to-date). While the first part of the query that performs the math was using the "test" table (and working properly), the second half that pulls the most-recently-updated data was using the original "metrics" table, which did not have any rows with a metrics_date this month.
When I changed the query to use "test" for both parts of the query, everything works as expected. And now I feel really dumb.
Thanks anyway, guys!