SQL Query - order by date but also group - mysql

OK Ladies and Gents, I would really appreciate some help:
This is my table:
ID postID replyID content entry_date
1 0 40 hey 12/7
2 0 40 hi 12/8
3 0 40 whatsup 12/9
4 2 40 why? 12/10
5 0 40 who? 12/11
I need to run a query to get it like this:
ID postID replyID content entry_date
1 0 40 hey 12/7
2 0 40 hi 12/8
4 2 40 why? 12/10
3 0 40 whatsup 12/9
5 0 40 who? 12/11
You will see that ID 3 and 4 have switched. So basically I need to ASC by entry_date, unless ID = POSTID, then I need those two grouped together and also ASC by entry_date for those two.
Here is what I have tried but I am totally lost:
SELECT t1.ID, t1.postID, t1.replyID, t1.content, t1.entry_date
FROM discussion t1, discussion t2
WHERE t1.replyID = '40' AND t1.ID = t2.postID
ORDER BY t1.entry_date ASC
Which basically does nothing but finds where a row of ID = a row of postID

You can add a CASE statement to your ORDER BY clause
ORDER BY
CASE WHEN postID = 0 THEN ID ELSE postID END
, entry_date
doing so, you can discard the join alltogether and the entire statement could be simplified to
SELECT ID
, postID
, replyID
, content
, entry_date
FROM discussion
ORDER BY
CASE WHEN postID = 0 THEN ID ELSE postID END
, entry_date
Note that I do assume the entry date being a DATETIME column, not a VARCHAR column.

Related

configure query to bring rows which have more than 1 entries

How to get those entries which have more than 1 records?
If it doesn't make sense... let me explain:
From the below table I want to access the sum of the commission of all rows where type is joining and "they have more than 1 entry with same downmem_id".
I have this query but it doesn't consider more entries scenario...
$search = "SELECT sum(commission) as income FROM `$database`.`$memcom` where type='joining'";
Here's the table:
id mem_id commission downmem_id type time
2 1 3250 2 joining 2019-09-22 13:24:40
3 45 500 2 egbvegr new time
4 32 20 2 vnsjkdv other time
5 23 2222 2 vfdvfvf some other time
6 43 42 3 joining time
7 32 353 5 joining time
8 54 35 5 vsdvsdd time
Here's the expected result: it should be the sum of the id no 2, 7 only
ie. 3250+353=whatever.
It shouldn't include id no 6 because it has only 1 row with the same downmem_id.
Please help me to make this query.
Another approach is two levels of aggregation:
select sum(t.commission) income
from (select sum(case when type = 'joining' then commission end) as commission
from t
group by downmem_id
having count(*) > 1
) t;
The main advantage to this approach is that this more readily supports more complex conditions on the other members of each group -- such as at most one "joining" record or both "joining" records and no more than two "vnsjkdv" records.
Use EXISTS:
select sum(t.commission) income
from tablename t
where t.type = 'joining'
and exists (
select 1 from tablename
where id <> t.id and downmem_id = t.downmem_id
)
See the demo.
Results:
| income |
| ----- |
| 3603 |
You can use subquery that will find all downmem_id having more than one occurrence in the table.
SELECT Sum(commission) AS income
FROM tablename
WHERE type = 'joining'
AND downmem_id IN (SELECT downmem_id
FROM tablename t
GROUP BY downmem_id
HAVING Count(id) > 1);
DEMO

Sql select where a column has been set atleast once

I have this table
**applications**
id user_id company_id shortlisted
1 10 99 0
2 10 100 1
3 10 101 1
4 10 102 0
5 11 99 1
6 12 99 0
6 12 101 0
What I want is to select all users
which have been shortlisted at-least once
which have not been shortlisted at all
For the first case, i have the following query:
SELECT user_id
from applications
where shortlisted=1
Group
By user_id
and this gives me the expected result like below
**applications**
user_id
10
11
But I'm trying the following query for the second case and it returns me an empty set:
Select user_id
from applications as Application
where shortlisted=0
and NOT EXISTS(Select user_id from applications where user_id=Application.user_id and shortlisted=1)
What am i missing?
PS: Please ignore any typos as i typed them manually for this post.
To get both results in a single query simply use aggregation:
select user_id, max(shortlisted) as was_shortlisted
from applications
group By user_id
You can use group by and having for both.
For the first:
select user_id
from applications
group By user_id
having max(shortlisted) = 1;
For the second:
select user_id
from applications
group By user_id
having max(shortlisted) = 0;
In all honesty, your version with the where is more efficient for the first query. This is just to show how closely related the queries are.
You can try following query;
select user_id from table1
group by user_id having MIN(shortlisted) = 1
This will give you to at least have shortlisted = 1 condition and don't have shortlisted = 0 records.

Selecting a count on two separate conditions

Let's say I have the following data.
id name_id completed
1 10 1
2 10 0
3 15 1
4 10 0
5 20 1
6 15 0
7 20 1
8 15 0
I'm trying to find a count by the name id, which is pretty simple
SELECT name_id, COUNT(*) FROM db
GROUP BY name_id
Now, I have a second component which I want to include in the query.
For name_id 10, I want to count just those values where completed is 1. For the other name_id's, I want to select them regardless of whether they are 0 or 1.
So I should end up with:
name_id count(*)
10 1
15 3
20 2
Name_id 10 only has a count of 1 because it's just the 1 which is completed, while the other counts include both 0 and 1.
Can anyone help with this task.
Thanks!
You can use a CASE expression inside of your aggregate function.
SELECT name_id,
sum(case
when name_id = 10
then case when completed = 1 then 1 else 0 end
else 1 end) Total
FROM db
GROUP BY name_id;
See SQL Fiddle with Demo.
Exclude the rows where name_id = 10 and completed = 0:
SELECT name_id, COUNT(*) FROM db
WHERE NOT (completed = 0 AND name_id = 10)
GROUP BY name_id
SELECT name_id, COUNT(*) FROM db
WHERE name_id != 10 or completed = 1
GROUP BY name_id
Count when name_id is not 10. If it is 10, count when completed = 1:
SELECT
name_id,
COUNT(CASE WHEN name_id <> 10 or completed = 1 THEN 1 END)
FROM db
GROUP BY name_id

SUM of rows in My Sql with condition

My Data is
ID SCORE
1 55
1 -1
1 25
1 -1
1 -1
1 35
2 25
2 -1
2 65
2 55
2 21
2 -1
Now i want to add/sum the score of each id ignoring -1 and i am trying with this code which is not working
SELECT SUM(CASE when SCORE>-1 THEN SUM(SCORE) ELSE 0 END)
FROM jbit WHERE htno='$id'
Here i am already using WHERE so how can i use another WHERE, if i use multiple Where in single query it may effect other processes.. please help me out
Help me out friends
if there is only two column then there is no need to use SUM, you can try below
SELECT id, IF(SCORE=-1,0,SCORE) AS scoreSum
FROM table1
GROUP BY id
Working DEMO
alternative ( not tested )
SELECT id, SUM(IF(SCORE=-1,0,SCORE)) AS scoreSum
FROM table1
WHERE htno =$id
GROUP BY id
SELECT SUM(score) AS score_sum
FROM jbit
WHERE htno='$id'
AND score <> -1 ;
SELECT SUM(`SCORE`)
FROM `jbit`
WHERE `htno` = '$id'
`SCORE` > 0;
Though, I'd suggest you to change '$id' to just $id if the column type of htno is INTEGER.
SELECT SUM(score) FROM <tablename> WHERE score != -1

mysql random with condition

I have a table in mysql, say table1.
I am running this on it:
SELECT FLOOR( MAX(id) * RAND()) FROM `table1`
This works well, but I am now trying to add a condition of "AND tom".
Where tom is a integer field.
For example:
id tom
1 0
2 3
3 2
4 0
5 0
6 3
7 1
8 1
9 3
etc.
So, my question is,
How can I pick a random value from id, which also satisfies tom='0' say?
SELECT id FROM `table1` WHERE tom = 0 ORDER BY RAND() LIMIT 1
This will first get all rows in which tom = 0,then order those results randomly. MySQL will then limit those results to just one, returning the single value you want to retrieve.
I hope I understood correctly:
SELECT id FROM `table1` WHERE tom = 0 order by rand() limit 1
select * from (
select * from table where tom = 0 ) as t order by rand() limit 1