I am trying to solve following problem:
I have a table with timeStamp column and three columns for different types of variables. The columns with values are filled randomly according to the conditions. So it looks like this:
smpl_time float_val num_val str_val 15:31
10 NULL NULL
15:32 NULL 15.4 NULL
15:33
NULL NULL Disabled
What I would like to achieve is a result that would merge all val fields into one column and sorts them according to timeStamp:
smpl_time merge_val
15:31 10
15:32 15.4
15:33 Disabled
So far I have a SELECT just for one val type looking like this (it contains also other field from the table that are common for each entry):
SELECT s.smpl_time AS Time,s.float_val AS Value, e.name AS Severity, m.name AS Status
FROM sample s JOIN channel c ON c.channel_id=s.channel_id JOIN severity e ON
e.severity_id=s.severity_id JOIN status m ON m.status_id=s.status_id WHERE
s.channel_id='id' AND smpl_time BETWEEN TIMESTAMP 'startTime' AND TIMESTAMP 'stopTime';
Does anyone have an idea how to do this or if it is even possible?
Cheers,
Mike
Assuming only one of the three columns is populated for any given row, use the COALESCE function.
SELECT smpl_time, COALESCE(float_vaL, num_val, str_val) AS merge_val
FROM ...
http://dev.mysql.com/doc/refman/5.0/en/comparison-operators.html#function_coalesce
COALESCE(value,...)
Returns the first non-NULL value in the list, or NULL if there are no non-NULL values.
mysql> SELECT COALESCE(NULL,1);
-> 1
mysql> SELECT COALESCE(NULL,NULL,NULL);
-> NULL
Related
Table Data:
ID
Type
1
A
2
A
3
B
4
A
5
A
6
B
7
B
8
A
9
A
10
A
How to get only rows with IDs 1,3,4,6,8, or the first records on type-change by single query?
We were doing this in code using multiple queries and extensive processing especially for large data, is there a way to do this in a single query?
Use LAG() window function to get for every row the previous row's type and compare it to the current type.
Create a flag column that is true if the 2 types are different and use it to filter the table:
WITH cte AS (
SELECT *, type <> LAG(type, 1, '') OVER (ORDER BY id) flag
FROM tablename
)
SELECT * FROM cte WHERE flag;
I assume that the column type does not contain empty values (nulls or
empty strings).
See the demo.
I'm having a hard time solving my sql problem. Would like to select a row if a certain field(LOOKUP) is not null. Else, get the row with the null field instead. Please see table below:
(PAYCODE must be unique)
PAYCODE
LOOKUP
ACCOUNT
201
null
720001
201
659057
999999
202
null
720002
The output must be:
PAYCODE
LOOKUP
ACCOUNT
201
659057
999999
202
null
720002
This looks so easy but I am new to sql and solving this for 2 days while searching for solutions but no luck.
You could try the following logic:
SELECT *
FROM yourTable t1
WHERE LOOKUP IS NOT NULL OR
NOT EXISTS (SELECT 1 FROM yourTable t2
WHERE t2.PAYCODE = t1.PAYCODE AND
t2.LOOKUP IS NOT NULL);
Demo
This logic retains any record whose LOOKUP is not null or any record for which there is no non null record having the same PAYCODE.
I have a table "Cabine" with fields "SBC750" (integer) and "Evaso" (tinyint)
The field Evaso can be 1, 0 or Null
I'm looking for the sum of all sbc750 where Evaso is NOT 1.
I tried with
select sum(sbc750) from cabine where evaso<>1;
but the result is NULL: why???
If I use
select sum(sbc750) from cabine
I obtain 55 and if I use
select sum(sbc750) from cabine where evaso=1
I obtain 34!
So the results might be 21 and not Null. Please help me
With the NULL-safe equality operator you should get the desired results:
select sum(sbc750) from cabine where not evaso<=>1;
Also see here for reference.
SELECT sum(sbc750) FROM cabine where evaso is null or evaso<>1;
I try to get the max value of a mysql select, but want to have it null/empty/0 if there is one row containing no timestamp.
Table stats (simplyfied):
ID CLIENT ORDER_DATE CANCEL_DATE
1 5 1213567200
2 5 1213567200
3 6 1210629600 1281736799
4 6 1210629600 1281736799
5 7 1201042800 1248386399
6 7 1201042800
7 8 1205449200 1271282399
I'm now looking to get the lowest order date (no problem, as it is never empty), and
the maximum cancel date. If the client has already cancelled his subscription, the cancel date is filled, but if he is still active, there is no cancel date at all.
Query:
SELECT ID, min(ORDER_DATE) AS OD, max(CANCEL_DATE) AS CD FROM stats GROUP BY CLIENT
Returns:
ID OD CD
5 1213567200 // fine
6 1210629600 1281736799 // fine
7 1201042800 1248386399 // Should be empty
8 1205449200 1271282399 // fine
I can't figure it out how to return empty/0/NULL if there is one (or more) empty colums for a client. Also tried with NULL fields.
Thanks for any hint.
I don't know how fast it will be but I guess it can be solved like this:
SELECT ID, min(ORDER_DATE) AS OD,
IF(COUNT(*)=COUNT(CANCEL_DATE),max(CANCEL_DATE),NULL) AS CD
FROM stats GROUP BY CLIENT
I couldn't test it but the idea behind this solution is that count(cancel_date) should count all not null value entries and if it's equal to count(*) that means that there are no null values and it will return max(cancel_date), otherwise null.
You could use a query like this:
SELECT
client,
min(ORDER_DATE) AS OD,
case when MAX(CANCEL_DATE IS NULL)=0 THEN max(CANCEL_DATE) END AS CD
FROM
stats
GROUP BY
CLIENT
Please see fiddle here.
CANCEL_DATE IS NULL will be evaluated either to 0, when CANCEL_DATE is not null, or to 1 when it is null
MAX(CANCEL_DATE IS NULL) will be evaluated to 0 if there are no cancel_date with null values, otherwise its value will be 1.
when MAX(CANCEL_DATE IS NULL)=0 it means that there are no rows where CANCEL_DATE is null, and we need to return MAX(cancel_date) in that case, otherwise we need to return NULL.
Is there a way to create a view from two tables, where one of the columns is different among the two tables? The problem I am currently running into is that MYSQL is telling me that there is an undefined index - which makes perfect sense since, in half of the cases, the column won't exist.
Table Layout:
(post_rank_activity)
ID, post_id, ... date
(reply_rank_activity)
ID, rank_id, ... date
What I want the resulting view to look like:
ID | Post_id | Reply_id | Date
x x NULL x
x NULL x x
And the SQL:
$rankView = "Create or replace view userRank as (
select PRA.id, PRA.post_id, PRA.user_id, PRA.vote_up, PRA.rank_date
From post_rank_activity PRA)
union All
(select RRA.id, RRA.reply_id, RRA.user_id, RRA.vote_up, RRA.rank_date
from reply_rank_activity RRA)";
And the result I'm getting, instead of returning null, it's returning the value of "reply_id" for the "post_id" field and then shifting all of the other values over - see below:
ID | Post_id | Reply_id | Date
x x date val x
x reply val date val x
Any ideas?
Unions must contain the same columns in the same order across all parts. You should explicitly select/declare the null columns in each part of the union:
SELECT PRA.id, PRA.post_id, NULL AS reply_id, PRA.user_id, PRA.vote_up, PRA.rank_date
FROM post_rank_activity PRA
UNION All
SELECT RRA.id, NULL AS post_id, RRA.reply_id, RRA.user_id, RRA.vote_up, RRA.rank_date
FROM reply_rank_activity RRA
Your query should look like
select PRA.id, PRA.post_id, null as Reply_id PRA.rank_date
From post_rank_activity PRA
union All
select RRA.id, null as post_id, RRA.reply_id, RRA.rank_date
from reply_rank_activity RRA