How to Exclude Mysql Group - mysql

I would like to know how to exclude a mysql group, i did research on here for some time but just dont make it right.
I tried
SELECT * FROM booking GROUP BY BookingId HAVING Status!="Cancellation"
which obviously doesn't work.
Example Database looks like this:
+----+-----------+--------------+
| id | BookingId | Status |
+----+-----------+--------------+
| 1 | 1 | Booked |
| 2 | 1 | Cancellation |
| 3 | 2 | Booked |
+----+-----------+--------------+
I would like to group them by BookingId and if one of the found entries got the Status Cancellation this group shouldnt show up, so from above just the id 3 would be seen.

You need to use aggregate functions like sum in a having clause
SELECT BookingId
FROM booking
GROUP BY BookingId
HAVING sum(Status = 'Cancellation') = 0

Related

get multiple rows from table where column = array

This is a revised question of my previous question, because I dont think I asked it correctly.
I am creating a chat room in NodeJS, and in order to do that I have the following table that lists which users are in each room:
+----+--------+--------+--+
| id | roomID | userID | |
+----+--------+--------+--+
| 1 | 9 | 3 | |
| 2 | 9 | 4786 | |
| 3 | 9 | 7991 | |
| 4 | 7 | 3 | |
| 5 | 7 | 4786 | |
| 6 | 1 | 3 | |
+----+--------+--------+--+
I need to be able to select from the list the roomID from an array of users. So lets say, I want to get the roomID that users 4786 and 3 are using, It would return 7. If I wanted to get the roomID that users 4786,3 AND 7991 are using, it would return 9.
Okay so. In my previous question the answer I got was to use SELECT * FROM table WHERE userID IN (4786,3,7991). What I didnt realise (I dont use the IN statement that much) was that the IN statement was essentially a shortcut for the OR statement.
Which leads me to the problem, The first thing I tried was OR and because it doesnt explicitly match each userID in the table, the results are unreliable.
I've created an SQLFiddle here.
I want to be able to say: Give me the unique roomID for these users and and these users only. It doesnt matter if they are involved in other rooms.
I hope i've made myself a bit more understandable.
SQL DEMO
SELECT roomId, COUNT(CASE WHEN `userID` IN (4786,3)
THEN 1
END) total_match
FROM `chat-room-users`
GROUP BY roomId
HAVING total_match = 2 -- because are 2 users in (4786,3)
AND total_match = COUNT(`userID`)
Lets say you put your users in a table search_user to be more generic your query become:
SELECT roomId, COUNT(CASE WHEN `userID` IN (SELECT userID FROM search_users)
THEN 1
END) total_match
FROM `chat-room-users`
GROUP BY roomId
HAVING total_match = (SELECT COUNT(*) FROM search_users)
AND total_match = COUNT(`userID`)

How to count users with where condition previous row

please help me i have no idea for this...
I have table like this (create_at YYYY-MM-DD). ID is auto increment
-----------------------------------------------------------------
| ID | id_user | activity | create_at |
-----------------------------------------------------------------
| 1 | 10 | A | 2017-10-11 |
| 2 | 52 | A | 2017-10-11 |
| 3 | 41 | A | 2017-10-12 |
| 4 | 52 | A | 2017-10-12 |
| 5 | 41 | B | 2017-10-12 |
| 6 | 52 | B | 2017-10-13 |
| 7 | 10 | B | 2017-10-14 |
-----------------------------------------------------------------
How to get count (mysql) user who doing activity "B" after activity "A" in sameday create_at.. In this case, the result is 1 (IDUser 41).. How can i do this in mysql? thankyou
We could use a semi-join or a correlated subquery.
we start like this, users that are doing activity B
SELECT t.id_user
FROM table_like_this t
WHERE t.activity = 'B'
we can match those rows to users that are doing activity A on the "same day" with JOIN operation back to the same table...
SELECT t.id_user
FROM table_like_this t
JOIN table_like_this r
ON r.id_user = t.id_user
AND r.create_at = t.create_at
AND r.activity = 'A'
WHERE t.activity = 'B'
As far as whether activity B is occurring "after" activity A, I don't see any information in the table that can tell us that (we can't tell what time each activity A and B occurred, and can't determine which one was "after" the other.)
For testing, we can include other columns in the SELECT list, to verify which rows from t and r are being returned, if the matching is being done properly.
Once we are satisfied, we can replace the SELECT list, to get a count of distinct id_user
SELECT COUNT(DISTINCT t.id_user)
FROM ...
Note that this will collapse occurrences of id_user that performed activity A and B on several different days so that the id_user will be counted only once.
If we want to count the number of days for each id_user, and include each of those days in the count, the query would need to be changed.

Select first and last timestamp where userID is unique

I'm trying to do a query to get first and last timestamp of each unique user.
Database looks like this:
| ID | EventID | Timestamp | Person | Number |
--------------------------------------------------------
| 1 | 2 | 2015-01-08 17:31:40 | 7 | 5 |
| 2 | 2 | 2015-01-08 17:35:40 | 7 | 4 |
| 3 | 2 | 2015-01-08 17:38:40 | 7 | 7 |
--------------------------------------------------------
I'm trying to put together a MySQL query that will do the following:
SUM of number field for each unique user.
Time difference (in hours) between first and last row for each unique user.
I would imagine that if I could get the first and last timestamp for each user, I should be able to use timediff to get the time difference in hours.
What I've got so far:
SELECT
person,
SUM(number) AS 'numbers_all_sum'
FROM database
WHERE eventid = 2
GROUP BY person
ORDER BY numbers_all_sum DESC
Any help would be greatly appreciated.
Something like this:
SELECT
Person
MIN(Timestamp),
MAX(Timestamp),
SUM(number) AS 'numbers_all_sum'
FROM database
WHERE eventid = 2
GROUP BY person

how to group mysql based on items and today date

I have a database that store transaction logs, I would like to count all the logs for that day and group them based on prod_id
MySQL table structure:
Table name = products
+------+---------+------------+--------+
| ID | PROD_ID | DATE | PERSON |
+------+---------+------------+--------+
| 1 | 2 | 1400137633 | 1 |
| 2 | 2 | 1400137666 | 1 |
| 3 | 3 | 1400137125 | 2 |
| 4 | 4 | 1400137563 | 1 |
| 5 | 2 | 1400137425 | 2 |
| 6 | 3 | 1400137336 | 1 |
+------+---------+------------+--------+
MYSQL CODE:
$q = 'SELECT count(ID) as count
FROM PRODUCTS
WHERE PERSON ='.$db->qstr($person).'
AND DATE(FROM_UNIXTIME(DATE)) = DATE(NOW())';
so what I get is the number of items for the given date. Since the date is the same as all other entries. however I would like to group the items by prod_id, I tried GROUP BY PROD_ID but that did not give me what I want. I would like it to group if the PROD_ID is multiple and the date is the same display as one entry while still count the others
so here I should get an output ($Person = 1).... 2+2+2=1 +3 +4 so total should be 3
any suggestions?
Use DISTINCT with COUNT on PROD_ID.
Example:
SELECT count( distinct PROD_ID ) as count
FROM PRODUCTS
WHERE PERSON = 1 -- <---- change this with relevant variable
AND DATE( FROM_UNIXTIME (DATE ) ) = curdate();
And I suggest you to use Prepared Statement to bind values.

Writing a MySQL query that counts entries uniquely

This is my table structure-
TABLE : T_LOG
---------------------------------------------------
| ID | AREA | USER_ID | DATE
---------------------------------------------------
| 1 | AREA1 | 5 | 2000-05-17
---------------------------------------------------
| 2 | AREA1 | 5 | 2002-12-12
---------------------------------------------------
| 3 | AREA2 | 5 | 2003-02-19
---------------------------------------------------
| 4 | AREA1 | 5 | 2006-05-22
---------------------------------------------------
| 5 | AREA2 | 5 | 2006-07-29
---------------------------------------------------
| 6 | AREA3 | 5 | 2009-05-07
---------------------------------------------------
In this table USER_ID 5 has been to several AREAs at several DATEs.
I want to pick how many (uniquely) AREAs the particular USER_ID has been to so far.
The following query
SELECT COUNT(*) FROM T_LOG WHERE USER_ID = 5 GROUP BY 'AREA'
returns 6 as in 6 entries. But I want it to return 3 as in 3 Areas uniquely (AREA1, AREA2, AREA3)
How do I correct this query?
You can use count (distinct):
SELECT COUNT(DISTINCT AREA) FROM T_LOG WHERE USER_ID = 5
Your actual problem is that you have specified Area column as a value in the GROUP BY clause (i.e. GROUP BY 'Area'). Which should be without single quotes. (i.e. GROUP BY Area)
So try this query:
SELECT COUNT(*) FROM T_LOG WHERE USER_ID = 5 GROUP BY AREA
See this SQLFiddle
Alternatively you can directly use COUNT(DISTINCT Area) as already mentioned in other answers (which one is more preferable).
SELECT COUNT(DISTINCT AREA), USER_ID FROM T_LOG WHERE USER_ID = 5