PostgreSQL count data based on grouped data - node.js

I have a database that looks like this
users
email name state id
bill#domain.com Bill CA 1
Susan WY 2
jill#domain.com Jill CA 3
phil#domain.com Phil WY 4
You'll notice that Susan does not have an email.
I'm trying to get a count of records per state, then a total number of non null emails for each state.
I was able to get the total count of states like this:
SELECT state, COUNT(*) as count FROM users GROUP BY state
That works great.
Then I tried getting the total number of emails like this:
SELECT state, COUNT(*) as count, COUNT(SELECT * FROM users WHERE email IS NOT NULL) as email_count FROM users GROUP BY state
But that returned a parse syntax error.
I'm trying to get a return dataset like this:
[
{state: 'CA', count: 2, email_count: 2},
{state: 'WY', count: 2, email_count: 1}
]

Try this!
SELECT
state,
COUNT(*) AS total_count,
SUM(CASE WHEN email is not null then 1 ELSE 0 END) AS count_email_not_null
FROM users
GROUP BY state
It will give you your intended output.

Related

Replacing Null Values with Mean Value of the Column in Grid DB

So, I was working with GridDB NodeJs Connector, I know the query to find out the null values which shows the records/rows:
SELECT * FROM employees where employee_salary = NaN;
But I want to replace the null values of the column with the mean value of the column, in order to maintain the data consistency for data analysis. How do I do that in GridDB?
The Employee table looks like the following:
employee_id employee_salary first_name department
---------------+---------------+--------------+--------------
0 John Sales
1 60000 Lisa Development
2 45000 Richard Sales
3 50000 Lina Marketing
4 55000 Anderson Development

Limit returned entries per user per query

I have the following request:
let artPerCall = 20
let artPerUser = 2
let start = req.params.page
let query = `
SELECT * from
(
SELECT a.*, row_to_json(u.*) as userinfo,
row_number() over (partition by u.address order by a.date desc) as ucount
FROM artworks a INNER JOIN users u ON a.address = u.address
WHERE a.flag != ($1) OR a.flag IS NULL
) t
WHERE ucount <= ($2)
ORDER BY date DESC
LIMIT ${artPerCall} OFFSET ${(start-1) * artPerCall}`
pool.query(query, ["ILLEGAL", artPerUser])
.then(users => {
if (users) {
res.json(users.rows);
}
})
.catch(err => {
next(err);
})
Called through an API with the following path /artworks/paginate/1/20 where (/artworks/paginate/{page}/20)
The expected result is to get 20 results per call with a maximum of 2 entries per user.
The current result:
It seem that it return only 2 entries per user as expected but once it return 2 for a user on a page then no more result for the same user in the following pages even if they have entries.
Any idea what i'm missing?
It seem that it return only 2 entries per user as expected but once it return 2 for a user on a page then no more result for the same user in the following pages even if they have entries.
Correct, this is what the query does. It selects:
row_number() over (partition by u.address order by a.date desc) as ucount
...
WHERE ucount <= ($2)
If parameter $2 is set to 2 as it is in your example code, then it will select 2 entries per user, not more, before sorting and pagination. If the user has more entries they will be filtered out.
If you remove "WHERE ucount <= ($2)" then you'll simply get all the results ordered by date, but that doesn't sound like what you want.
However, what I think you want to achieve sounds a bit complicated. I'm not sure either it would be great for usability as the results would look quite random to the user. So you will need to describe exactly what you want, with example data.
For example, if you want to avoid one user posting a lot of items with the same date pushing all the other users down in the search results, limiting the number of results per user is a good idea, but perhaps a button "more from this user..." would be a better choice than pushing the users' items down to the next pages.
Suppose you have only two users, user1 posts 20 items with date "today" and user2 posted 10 items yesterday. Do you want 2 items from user1, then 2 items from user2, then the 18 remaining items from user1, then the 8 remaining items from user? Or will they be interleaved with each other somewhat, which will make the date order a bit random in the results?
EDIT
Here's a proposal:
SELECT * from
(
SELECT *,
row_number() over (partition by user_id order by date desc) as ucount
FROM artworks
) t
ORDER BY (ucount/3)::INTEGER ASC, date DESC
LIMIT 20 OFFSET 0;
"(ucount/3)::INTEGER" is 0 for the first two artworks of each user, then 1 for the next 3, then 2 for the next 3, etc. So the most recent 2 artworks of each user end up first, then the most recent 3 artworks of each user, etc.
Another one:
ORDER BY ucount<3 ASC, date DESC
This will put the most recent 2 artworks of each user first, then the rest is simply sorted by date.

How to get three tables data in laravel7

i have three table country, state, customer_contacts.
I want display all customer details into list structure. But in my customer table only id save of country and state respectively.
Table structure as follows :
Country
id name
1 India
2 Canada
State
id name country_id
1 Mumbai 1
2 Delhi 1
3 abc 2
4 xyz 2
Customer_contact
id c_name country_id state_id
1 abcdee 1 2
2 xyzerr 1 1
3 extraa 2 3
4 newsss 2 4
i want to fetch customer name with country name and state name.
I am using below query to fetch data but getting only customer contact data how to fetch name uaing any query or relationship.
$data = CustomerContact::latest()->get();
If any solution then let me know
You 2 have possibillities here:
First, you can use the relationships:
CustomerContact model
country()
{
return $this->belongsTo(Country::class);
}
Country model
state()
{
return $this->belongsTo(State::class);
}
Use the relationships like this:
$data = CustomerContact::with('country.state')->latest()->get();
Second option would be to use join():
CustomerContact
::join('countries', 'countries.id', 'customer_contact.country_id')
->join('states', 'states.id', 'countries.state_id')
->latest()
->get();

RunningCount webi Business Objects Formula

I am trying to produce a running count of salesid's for each distinct customer id.
I have tried this formula:
=RunningCount([Order ID])ForAll([Query 1].[Brand Account ID])
And unfortunately it yields this result:
We can see that where 'Count_of_Salesorder' == 12, it should have reset to 1 because the customer id has changed from B000115545 to B000159009
How can I achieve the running count of 'Order ID' for each distinct customer id? (Customer id is the field containing values that begin with 'B000')
You need to specify that you want the count to reset for each value of Brand Account ID.
=RunningCount([Order ID]; ([Brand Account ID]))
If you navigate to the RunningCount function with the Variable Editor and click on the "More on this function" link you will see its documentation.

Sub query to count users

I am having trouble with adding a sub query to the following query -
SELECT state
FROM users
ORDER BY state
Output:
Alabama
Alaska
Arizona
...
I would like to include the number of users from each state so I can output it
like:
Alabama (12)
Alaska (4)
Arizona (25)
ANSWER:
$query=mysqli_query($connect,"select state,
count(*) AS count from users
GROUP BY state");
while($rows=mysqli_fetch_assoc($query))
{
echo $rows['state'];
echo $rows['count'];
}
I didn't realize I had to name count(*) AS count so I could output it.
What you need to do is do a "group by" in the query.
The way it would work is like this:
select state, count(id)
from users
group by state
order by state
what this will do is group the records by the state and show how many records exist for that state.

Resources