this is my code for now:
SELECT id, number
FROM Media
WHERE user = 10
ORDER BY id, number
but I want it to look like:
SELECT id, number
FROM Media
WHERE user = 10
ORDER BY while(number IS NULL), id
What I want to do is to have all number that are NULL on the top of the result, but as soon number is not NULL, sort by id
Is that possible?
I use mysql.
what about something like this :
SELECT id, number
FROM Media
WHERE user = 10
ORDER BY (case when number is null then 0 else 1 end), id
If number is NULL, the first order by criteria will be 0 ; else 1
Which means every line will number NULL will come before the others ones
And note that ids will be sorted too, anyway.
You'll get something like this :
number null ; id=1
number null ; id=2
number null ; id=5
number null ; id=8
number not null ; id=3
number not null ; id=4
number not null ; id=7
number not null ; id=10
number not null ; id=12
The ISNULL() function returns 1 if the parameter is null and 0 otherwise.
SELECT id, number
FROM Media
WHERE user = 10
ORDER BY ISNULL(number) DESC, id
Mind you, terrible for performance depending on how many values it needs to order: no index will be used based on the ORDER BY columns.
Union could be used as well.
SELECT id, number
FROM Media
WHERE user = 10 AND number IS NULL
ORDER BY id
UNION
SELECT id, number
FROM Media
WHERE user = 10 AND number IS NOT NULL
ORDER BY id, number;
Related
This question already has answers here:
MySQL AVG() return 0 if NULL
(3 answers)
Closed last month.
I have the following structre
id val
1 ...
.
.
2 ...
.
.
3 null
3 null
3 null
4 ...
.
.
Basically each id has multiple no. of values. And an id has either all values as integers or all values as null
What I want is to perform an aggregate (like AVG) on val group by id. If that id has null values, I want to put 5 there.
#1
SELECT id, (CASE SUM(val) WHEN null THEN 5 ELSE AVG(val) END) AS ac FROM tt GROUP BY id
> executes ELSE even for id = 3
In CASE, there should be an aggregate function that when done on null values give null.
I checked SUM and MAX like
SELECT SUM(val) FROM tt WHERE id = 3
> null
and it gives null here but doesn't work in main statement. I guess it is related to the type of equality and hence tried WHEN IS NULL but its a syntax error.
Also, is there some more standard way of indicating group of values as all null rather than using SUM or MAX.
You can use if condition :
select id, If(sum(val) is null, 5, AVG(val)) as average
FROM tt
group by id
check here : https://dbfiddle.uk/Uso9nNTM
The exact problem with your CASE expression is that to check for null in MySQL we have to use IS NULL rather than equality. So use this version:
CASE WHEN SUM(val) IS NULL THEN 5 ELSE AVG(val) END
But we might as well just use COALESCE() to assign an average of 5 for those id groups having all null values.
SELECT id, COALESCE(AVG(val), 5) AS avg_val
FROM tt
GROUP BY id;
Note that the AVG() function by default ignores nulls. Therefore, the expression AVG(val) would only be null if every record in an id group were having null for val.
I have trouble wondering how do I count distinct value. using if on the select column
I have SQLFIDDLE here
http://sqlfiddle.com/#!2/6bfb9/3
Records shows:
create table team_record (
id tinyint,
project_id int,
position varchar(45)
);
insert into team_record values
(1,1, 'Junior1'),
(2,1, 'Junior1'),
(3,1, 'Junior2'),
(4,1, 'Junior3'),
(5,1, 'Senior1'),
(6,1, 'Senior1'),
(8,1, 'Senior2'),
(9,1, 'Senior2'),
(10,1,'Senior3'),
(11,1, 'Senior3'),
(12,1, 'Senior3')
I need to count all distinct value, between Junior and Senior column.
all same value would count as 1.
I need to see result something like this.
PROJECT_ID SENIOR_TOTAL JUNIOR_TOTAL
1 3 3
mysql query is this. but this is not a query to get the result above.
SELECT
`team_record`.`project_id`,
`position`,
SUM(IF(position LIKE 'Senior%',
1,
0)) AS `Senior_Total`,
SUM(IF(position LIKE 'Junior%',
1,
0)) AS `Junior_Total`
FROM
(`team_record`)
WHERE
project_id = '1'
GROUP BY `team_record`.`project_id`
maybe you could help me fix my query above to get the result I need.
thanks
I think you want this:
SELECT
project_id,
COUNT(DISTINCT CASE when position LIKE 'Senior%' THEN position END) Senior_Total,
COUNT(DISTINCT CASE when position LIKE 'Junior%' THEN position END) Junior_Total
FROM team_record
WHERE project_id = 1
GROUP BY project_id
The CASE will return a null if the WHEN is false (ie ELSE NULL is the default, which I omitted for brevity), and nulls aren't counted in DISTINCT.
Also, unnecessary back ticks, brackets and qualification removed.
I need help with some MySQL pain in the ****... Anyway, i got the following sql :
SELECT id,count(*),
CASE
WHEN count(*) > 1 THEN
// I need the minimal `taskdate_time` column from the selected rows
// where a certain boolean is active
ELSE taskdate_time
END
FROM timehistory th
WHERE `send`=true
GROUP BY date_format(taskdate_time, "%Y-%m-%d"), user_id
As described in the comments, i need to get the earliest time out for the two rows where a column called removed is not FALSE
How do i achieve this?
My columns are :
`id` - int
`taskdateuser_id` int
`user_id` int
`changed_by` int
`batch_id` int
`taskdate_time` timestamp
`send` tinyint
`isread` tinyint
`update` tinyint
`removed` tinyint
Many thanks in advance!!!
EDIT:
I might explain it a bit more. If i got the following table rows :
The red marked rows are captured by the CASE count(*) > 1, because there are 2 rows returned by the group by. Then i need to to a SELECT from that 2 captured rows where removed=false and min(taskdate_time). So if 4 rows are returned for that group by, and 2 of the rows are removed=false and the other are removed=true then i need to do a subselect for the minimum taskdate_time that 2 rows where removed=false.
SELECT id,
count(*),
CASE WHEN count(*) > 1
THEN (SELECT MAX(taskdate_time) FROM timehistory f WHERE f.id = th.id AND removed = 0)
ELSE taskdate_time
END
FROM timehistory th
WHERE `send` = true
GROUP BY date_format(taskdate_time, "%Y-%m-%d"), user_id
You could try something like this:
SELECT TH.user_id, COUNT(*),
CASE WHEN COUNT(*) > 1
THEN MIN(IF(TH.removed, TH.taskdate_time, NULL))
ELSE TH.taskdate_time
END
FROM TimeHistory TH
...
Sample Fiddle Demo
However, if COUNT > 1 AND there aren't any records where TH.removed is true, then this will return NULL for that value. What should it return in those cases?
--EDIT--
In response to comments, then this should work just wrapping it with COALESCE:
COALESCE(
CASE
WHEN COUNT(*) > 1
THEN MIN(IF(TH.removed, TH.taskdate_time, NULL))
ELSE TH.taskdate_time
END, MIN(TH.taskdate_time))
I have three queries that get stats from the database, but the total does not add up correctly for my results. If I do the math myself this is what I get: // 440728 / 1128 = 390.72
However, the following is what is returned by my queries:
SELECT * FROM facebook_accts
WHERE user_id IN (SELECT id FROM `user_accts` WHERE owner_id = '121')
// returns 1128
SELECT sum(friend_count) FROM facebook_accts
WHERE user_id IN
(SELECT id FROM `user_accts` WHERE owner_id = '121')
// returns 440728
SELECT avg(friend_count) FROM facebook_accts
WHERE user_id IN
(SELECT id FROM `user_accts` WHERE owner_id = '121')
// returns 392.11 (number formatted to two decimal places by php)
this may be happening because of column friend_count having some NULL values because SUM and AVG sunctions ignore NULL values. see here.
I guess the 1128 rows contain NULL values (which AVG and SUM ignore).
I need help with a SQL query.
I have a table with a 'state' column. 0 means closed and 1 means opened.
Different users want to be notified after there have been x consecutive 1 events.
With an SQL query, how can I tell if the last x rows of 'state' = 1?
If, for example, you want to check if the last 5 consecutive rows have a state equals to 1, then here's you could probably do it :
SELECT IF(SUM(x.state) = 5, 1, 0) AS is_consecutive
FROM (
SELECT state
FROM table
WHERE Processor = 3
ORDER BY Status_datetime DESC
LIMIT 5
) as x
If is_consecutive = 1, then, yes, there is 5 last consecutive rows with state = 1.
Edit : As suggested in the comments, you'll have to use ORDER BY in your query, to get the last nth rows.
And for more accuracy, since you have a timestamp column, you should use Status_datetime to order the rows.
You should be able to use something like this (replace the number in the HAVING with the value of x you want to check for):
SELECT Processor, OpenCount FROM
(
SELECT TOP 10 Processor, DateTime, Sum(Status) AS OpenCount
FROM YourTable
WHERE Processor = 3
ORDER BY DateTime DESC
) HAVING OpenCount >= 10