SQL query help( Yes,I have already tried nested select) - mysql

this is a screenshot of the database I am talking about
So suppose I have a database full of people with their ID numbers along with a year in which they made an entry plus their favorite show in that year. The years are always in the range 2014-2018, but not every one has an entry for each year. How can I count the total number of people who have consistently had the same show as their favorite show over all the years they have been recorded for.
I tried doing a nested selected but I kept getting error. I have checked other SQL related questions here talk about calculate 'change over the years' but none of those answers are compatible with my database and the solution wasn't transferable.

I think you need something like this:
See my SQLFiddle
select id, favorite_show, count(id) as total from people
group by id, favorite_show
having count(id) > 1

Hmmm . . . this gets the people who have only one show:
select count(*)
from (select person
from t
group by person
having min(show) = max(show)
) p;

You can count the number of different favorite shows someone has, and if that's 1 then they've had the same favorite every time.
SELECT COUNT(*)
FROM (SELECT 1
FROM yourTable
GROUP BY person_id
HAVING COUNT(DISTINCT favorite_show) = 1) AS x

Related

How to find the oldest and most recent date value in mysql in one query itself

I had a question about an exercise im trying where it asks me to find the manufacturing date of the oldest item as well as the most recent item in a table here
if anyone could help me i would appreciate it thx a ton
If you only want the dates the query you need is:
SELECT MIN(MDATE) AS oldestDate, MAX(MDATE) AS newestDate FROM Product;
If you want the entire rows one option is:
SELECT *
FROM Product
WHERE MDATE IN (
(SELECT MIN(MDATE) FROM Product),
(SELECT MAX(MDATE) FROM Product)
)

Conversations SQL Structure (Group chat)

In the past week I have been trying to come up with the best structure for a conversations chat, after doing a lot of searching, and trying to find better answers. The current structure I have so far, looks like this:
It must be possible to:
Have up to (n) participants in a group. (Let's say n = 5)
Check if a conversation already exists between the participants (this has been bothering me..)
Show the latest conversations, sorted by unread and timestamp of last message (should work)
Show the latest conversations (sort by unread and timestamp)
SELECT * FROM chat_participants WHERE pageId = ? AND isMuted=0 ORDER BY isRead DESC, lastmod DESC
Check if a conversation already exists between participants
The client user will be able to send a new message to a specific end user, or start a new group chat with up to 5 participants. Instead of starting a new conversation each time, I would like to check whether or not the conversation exists already, to append the message there instead. I hope it makes sense. This specific feature has been bothering me pretty much all the time, when I have been trying to come up with a good structure. Does anyone have an idea to solve this "peacefully" with this structure, or do you have better ideas? Thanks :)
I tried things like checking if the page id's existed in the chat_participants with the same chat id, but this brings up its own disadvantages. This is something I tried, but obviously doesn't work as intended, as it returns (x) records, which could be entirely different chatId values.
SELECT * FROM chat_participants WHERE pageId IN(<id1>,<id2>)
I appreciate your input on this. Have a great day ahead! :)
Edit (Answer to #Gordon Linoff)
Example of recipients table:
I used your code such as this: (This one works)
SELECT cp.chatId FROM chatParticipants cp GROUP BY cp.chatId HAVING GROUP_CONCAT(pageId ORDER BY pageId) IN('p1,p2')
But when I try to check another conversation, with other recipients, such as below, it does not.
SELECT cp.chatId FROM chatParticipants cp GROUP BY cp.chatId HAVING GROUP_CONCAT(pageId ORDER BY pageId) IN('deb47fba9bc6936ed76e831578baa480,123')
Also, why does it only seem to work when the values are wrapped within the same quotation marks? E.g if this is used, nothing is returned as well IN ('p1', 'p2')
Edit 2
So I combined some of the suggested answers here, and came up with this query.
SELECT chatId FROM chatParticipants GROUP BY chatId HAVING SUM(pageId NOT IN('deb47fba9bc6936ed76e831578baa480','123')) = 0
It works, sort of, the only issue I have found so far with this above query, is that something like the below query, still returns a chatId value. (Even though (144) does not exist in chatParticipants)
SELECT chatId FROM chatParticipants GROUP BY chatId HAVING SUM(pageId NOT IN('deb47fba9bc6936ed76e831578baa480','144','123')) = 0
Any ideas on how to solve this?
If you want to know if a chatId exists for a specific group of participants then one method is aggregation. For instance, to find chats where exactly 1, 2, and 3 participate:
select cp.chatid
from chat_participants cp
group by cp.chatid
having group_concat(pageid order by pageid)= '1,2,3';

Finding Max Date Along with User ID with One Group By in MySQL

I am trying to figure out the number of visits a site has, the most recent visit and who the user was in the most recent visit. The only item I'm unable to get at the moment is the user who visited the site most recently.There is a user_id column in the data. My current query is below. I'm thinking I will have to use a subquery but want to see if someone has a better method.
Select
site_id,
COUNT(id),
MAX(date_visit)
FROM site_views
GROUP BY 1
The most efficient method with the right indexes is usually:
select sv.*
from site_views sv
where sv.date_visit = (select max(sv2.site_visit) from site_views sv2 where sv2.site_id = sv.sidte_id);

How to count in a SQL list

I've made a table with the columns for a customer name and each activity they participate in. How can I can I count the activities for each name and display it?
I've done;
SELECT Activity_Name, COUNT(*) AS 'Number_of_activities'
FROM tablename
GROUP BY Activity_Name;
which gives me each a table of each activity and how many participants in each activity but not each customer and their number of activities
Apologies for anything I've done wrong, only a couple months into coding and first time posting on stack...
Considering I don't know how your schema looks exactly, this query should be a nice representation of the idea how to do it:
SELECT customer_name, COUNT(*) AS 'Number_of_activities_per_customer'
FROM tablename
GROUP BY customer_name;

Showing all duplicates, side by side, in MySQL

I have a table like so:
Table eventlog
user | user_group | event_date | event_dur.
---- ---------- --------- ----------
xyz 1 2009-1-1 3.5
xyz 2 2009-1-1 4.5
abc 2 2009-1-2 5
abc 1 2009-1-2 5
Notice that in the above sample data, the only thing reliable is the date and the user. Through an over site that is 90% mine to blame, I have managed to allow users to duplicate their daily entries. In some instances the duplicates were intended to be updates to their duration, in others it was their attempt to change the user_group they were working with that day, and in other cases both.
Fortunately, I have a fairly strong idea (since this is an update to an older system) of which records are correct. (Basically, this all happened as an attempt to seamlessly merge the old DB with the new DB).
Unfortunately, I have to more or less do this by hand, or risk losing data that only exists on one side and not the other....
Long story short, I'm trying to figure out the right MySQL query to return all records that have more than one entry for a user on any given date. I have been struggling with GROUP BY and HAVING, but the best I can get is a list of one of the two duplicates, per duplicate, which would be great if I knew for sure it was the wrong one.
Here is the closest I've come:
SELECT *
FROM eventlog
GROUP BY event_date, user
HAVING COUNT(user) > 1
ORDER BY event_date, user
Any help with this would be extremely useful. If need be, I have the list of users/date for each set of duplicates, so I can go by hand and remove all 400 of them, but I'd much rather see them all at once.
Thanks!
Would this work?
SELECT event_date, user
FROM eventlog
GROUP BY event_date, user
HAVING COUNT(*) > 1
ORDER BY event_date, user
What's throwing me off is the COUNT(user) clause you have.
You can list all the field values of the duplicates with GROUP_CONCAT function, but you still get one row for each set.
I think this would work (untested)
SELECT *
FROM eventlog e1
WHERE 1 <
(
SELECT COUNT(*)
FROM eventlog e2
WHERE e1.event_date = e2.event_date
AND e1.user = e2.user
)
-- AND [maybe an additionnal constraint to find the bad duplicate]
ORDER BY event_date, user;
;