Count number of likes and dislikes for each comment - postgresql

I have 2 tables, a ratings table and a comments table. I'm trying to select the number of likes and dislikes for each comment. Each comment can have multiple ratings (like or dislike). Currently, the rating table has a rating column which contains either 0 or 1. 0 is a dislike and 1 is a like.
My question is, how would I be able to count all the occurrences of likes and dislikes for each comment?
I've made this query that is able to return likes, I'd be able to return dislikes by adding another left join lateral and checking if it equals 0, however that would impact the queries performance and I don't think thats the best way of doing things.
SELECT comments.username, comments.text, comments.reply_to_id, l.likes from comments
LEFT JOIN LATERAL (
SELECT COUNT(*) AS likes FROM ratings AS likes WHERE likes.comment_id = replies.id AND likes.rating = 1
) as l on true WHERE comments.id = 1;
Is there a better way to do this?

Related

Counting several repeated values in a cloumn

I need to count how many times certain value occurs in a column
It looks like this (select * from znajezyki order by klos)
klos - is a serial number of a person (this value is repeated)
Now I need to create a query that will show me how many people knows 1,2,3 languages
If the same "klos" value is repeated 2 times that means that this person knows 2 languages if it occurs 3 times that means that pearson knows 3 languages and so on
I'd like my result to look something like this:
I tried refering to this post here but i cannot understand it and can't get it to work
I hope y'all can understand what I am talking about :)
First do the simple thing: count how many languages each person knows
SELECT klos, COUNT(*) AS langs
FROM znajezyki
GROUP BY klos
Then use that result in a subquery to count the people by how many languages they know:
SELECT langs, COUNT(*) AS persons
FROM (
SELECT klos, COUNT(*) AS langs
FROM znajezyki
GROUP BY klos
) AS temp
GROUP BY langs

MySQL Workbench - script storing return in array and performing calculations?

Firstly, this is part of my college homework.
Now that's out of the way: I need to write a query that will get the number of free apps in a DB as a percentage of the total number of apps, sorted by what category the app is in.
I can get the number of free apps and also the number of total apps by category. Now I need to find the percentage, this is where it goes a bit pear-shaped.
Here is what I have so far:
-- find total number of apps per category
select #totalAppsPerCategory := count(*), category_primary
from apps
group by category_primary;
-- find number of free apps per category
select #freeAppsPerCategory:= count(*), category_primary
from apps
where (price = 0.0)
group by category_primary;
-- find percentage of free apps per category
set #totals = #freeAppsPerCategory / #totalAppsPercategory * 100;
select #totals, category_primary
from apps
group by category_primary;
It then lists the categories but the percentage listed in each category is the exact same value.
I had initially thought to use an array, but from what I have read mySql does not seem to support arrays.
I'm a bit lost of how to proceed from here.
Finally figured it out. Since I had been saving the previous results in variables it seems that it was not able to calculate on a row by row basis, which is why all the percentages were identical, it was an average. So the calculation needed to be part of the query.
Here's what I came up with:
SELECT DISTINCT
category_primary,
CONCAT(FORMAT(COUNT(CASE
WHEN price = 0 THEN 1
END) / COUNT(*) * 100,
1),
'%') AS FreeAppSharePercent
FROM
apps
GROUP BY category_primary
ORDER BY FreeAppSharePercent DESC;
Then the query result is:

Compare 2 Tables When 1 Is Null in PostgreSQL

List item
I am kinda new in PostgreSQL and I have difficulty to get the result that I want.
In order to get the appropriate result, I need to make multiple joins and I have difficulty when counting grouping them in one query as well.
The table names as following: pers_person, pers_position, and acc_transaction.
What I want to accomplish is;
To see who was absent on which date comparing pers_person with acc_transaction for any record, if there any record its fine... but if record is null the person was definitely absent.
I want to count the absence by pers_person, how many times in month this person is absent.
Also the person hired_date should be considered, the person might be hired in November in October report this person should be filtered out.
pers_postition table is for giving position information of that person.
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
SELECT tr.create_time::date AS Date, pers.pin, tr.dept_name, tr.name, tr.last_name, pos.name, Count(*)
FROM acc_transaction AS tr
RIGHT JOIN pers_person as pers
ON tr.pin = pers.pin
LEFT JOIN pers_position as pos
ON pers.position_id=pos.id
WHERE tr.event_no = 0 AND DATE_PART('month', DATE)=10 AND DATE_PART('month', pr.hire_date::date)<=10 AND pr.pin IS DISTINCT FROM tr.pin
GROUP BY DATE
ORDER BY DATE
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
*This is report for octeber,
*Pin is ID number
I'd start by
changing the RIGHT JOIN for a LEFT JOIN as they works the same in reverse but it's confusing to figure them both in mind :
removing for now the pers_position table as it is used for added information purpose rather than changing any returned result
there is an unknown alias pr and I'd assume it is meant for pers (?), changing it accordingly
that leads to strange WHERE conditions, removing them
"pers.pin IS DISTINCT FROM pers.pin" (a field is never distinct from itself)
"AND DATE_PART('month', DATE)=10 " (always true when run in october, always false otherwise)
Giving the resulting query :
SELECT tr.create_time::date AS Date, pers.pin, tr.dept_name, tr.name, tr.last_name, Count(*)
FROM pers_person as pers
LEFT JOIN acc_transaction AS tr ON tr.pin = pers.pin
WHERE tr.event_no = 0
AND DATE_PART('month', pers.hire_date::date)<=10
GROUP BY DATE
ORDER BY DATE
At the end, I don't know if that answers the question, since the title says "Compare 2 Tables When 1 Is Null in PostgreSQL" and the content of the question says nothing about it.

TSQL - Best way to select data where a leave date falls in range of an invoice

Background: I have a payroll system where leave is paid only if it falls in range of the invoice being paid. So if the invoice covers the last 2 weeks then only leave in the last 2 weeks is to paid.
I want to write a sql query to select the leave.
Assume a table called DailyLeaveLedger which has among others a LeaveDate and Paid flag.
Assume a table called Invoice that was a WeekEnding field and a NumberWeeksCovered field.
Now assume week ending date 15/05/09 and NumberWeeksCovered = 2 and a LeaveDate of 11/05/09.
This is an example of how I want it written. The actual query is quite complex but I want the LeaveDate check to be a In subquery.
SELECT *
FROM DailyLeaveLedger
WHERE Paid = 0 AND
LeaveDate IN (SELECT etc...What should this be to do this)
Not sure if its possible the way I mention?
Malcolm
So LeaveDate should be between (WeekEnding-NoOfWeeksCovered) and (WeekEnding) for some Invoice?
If I've understood it right, you might be able to use an EXISTS() subquery, something like this:
SELECT *
FROM DailyLeaveLedger dl
WHERE Paid = 0 AND
EXISTS (SELECT *
FROM Invoice i
WHERE DateAdd(week,-i.NumberOfWeeksCovered,i.WeekEnding) < dl.LeaveDate
AND i.WeekEnding > dl.LeaveDate
/* and an extra clause in here to make sure
the invoice is for the same person as the dailyleaveledger row */
)

Is it possible / how to get number of a particular Facebook Group members (even if number of them is 500+)?

I need to monitor number of the facebook group users and display it on the website. I know that it is possible to get User IDs using their API, but they are limited to 500 only (if the total number of members is 500+).
What would be the easiest way to get total number of members that signed up to a Facebook Group that I'd set up? Is this at all possible?
If you write an http bot, it shouldn't be very hard to scrap, given that real-time performance is not the key.
You can do it with a FQL query like this:
SELECT uid FROM group_member WHERE gid = <group_id> limit 500
SELECT uid FROM group_member WHERE gid = <group_id> limit 500 offset 500
SELECT uid FROM group_member WHERE gid = <group_id> limit 500 offset 1000
...
Get the number of members
Do it inside a loop (until you get 0 results) and you'll get the total number of group members
perPage = 500
for count in range(100):
res = fql('SELECT uid FROM group_member WHERE gid = %s limit %d offset %d' % (fbUserId, perPage, perPage * count))
if len(res) == 0:
break
friends += len(res)
Get the members detail
You can even join with the user FQL table to have all the user detail:
SELECT uid, name, pic_square FROM user WHERE uid IN (
SELECT uid FROM group_member WHERE gid = <group_id> limit 500 offset %d )
According to the documentation for Groups.getMembers it isn't possible to get > 500 group members with an API call. Worse, you seem to only be able to get 500 random members.
You may want to consider using Facebook Connect with your site instead. I'm no expert on Connect but I believe you wont have this problem using it since you are actually writing Facebook-specific code -- seems like there would be no purpose in limiting results. That'd be the direction I'd look, at least.
Good luck.