Removing users accounts with a zero order value inside wordpress multisite database - sql

I am looking for a query to best remove user accounts from a multisite database, the database has over 20 thousand users account and a majority of them have 0 orders against them is it possible to delete customers that have no order against their account so in theory an sql query that selects the user where order amount is zero

Based on the example query you included in the question, it seems like Order is a column in your table that holds the total number of orders. If so, a delete command like below would work:
delete from user
where order = 0
If each order is shown by a different entry, you will need the list of UserIDs and use those in your delete command like below:
delete from Users
where UserID in (
Select F_UserID
From Orders
Group by F_UserID
Having count(*) < 1
)

Related

Getting all entries from N unique users

I am working with Google BigQuery and I have two tables as described by the following link:
[Tables].
user_metric contains entries with the lifetime information of all users.
user_daily_metric contains entries for each user and each of the days they have been active
My challenge is that I wish to take the first 500 unique users (represented by the candidate key user_metric.userid) and I want to create a table with entries for each of these 500 unique users and all of their days active. Resulting in a table similar to this: [Resulting table]
(Consider the user with userid = 0690894780 as not being a part of the first 500 unique users)
My current query works for creating the table I desire, in terms of columns, but I have not been able to figure out how to limit it to only entries from the 500 unique users.
Current query:
SELECT
user_metrics.userid, user_metrics.userProgression, user_daily_metrics.missionSecondsPlayed_sum, user_daily_metrics.missionMovesUsed_sum
FROM
user_metric
JOIN user_daily_metric
ON user_metric.userid = user_daily_metric.userid
ORDER BY
user_metrics.userid
In advance, thank you very much for taking the time to read my question (and if I'm lucky, even reply to it) :)
Use a subquery:
SELECT um.userid, um.userProgression, user_daily_metrics.missionSecondsPlayed_sum,
udm.missionMovesUsed_sum
FROM (SELECT um.*
FROM user_metric um
ORDER BY um.userid
LIMIT 500
) um JOIN
user_daily_metric udm
ON um.userid = udm.userid
ORDER BY um.userid

Setting a column value for only one user depending on results

I'm currently playing around with SQL and trying to find the best way to accomplish this:
I currently have a user table that has a user_id, organisation_id, registered_datetime. There are
a number of users in this table with different organisations. There may be 3 different users in
1 organisation, or 1 in 1 organisation, etc.
I have added a new column called admin_user and I am trying to string up an SQL statement together
to update the admin user column. There can only be one admin user per organisation, and I want
the user who registered the earliest for that organisation to be the admin.
I could do this manually but it would take time if I had a lot of users. What would be the best
way to accomplish this?
EDIT:
So I have a number of users like this with the columns. The ones highlighted are the users that has registered the earliest. I want to be able to set those users as an admin user. The only admin user within their organisation and set the rest to 0. 1 (Admin) 0 (Not Admin)
This SQL query will mark users which registered_datetime are lowest in its organisation_id as admin.
UPDATE users SET admin_user = 1
WHERE user_id IN (
SELECT u.user_id FROM users u
WHERE u.registered_datetime IS NOT NULL AND NOT EXISTS(
SELECT 1 FROM users iu
WHERE iu.organisation_id = u.organisation_id AND iu.registered_datetime < u.registered_datetime
)
)
You might want to update all users to admin_user = 0 before this code, so all your users will have their values set.
One caveat here, if two users in one organisation were registered in exact same time, then both of them will be marked as administrators.
Update
I have added u.registered_datetime IS NOT NULL into the WHERE clause to filter out users with NULL in registered_datetime.
MSSQL
In MsSql server I usually solve this problem a in another way, by using ROW_NUMBER():
WITH base AS (
SELECT user_id, ROW_NUMBER() OVER ( PARTITION BY organisation_id ORDER BY registered_datetime ASC ) AS rn
FROM user
WHERE registered_datetime IS NOT NULL
)
UPDATE user SET is_admin = 1
WHERE user_id IN (
SELECT base.user_id FROM base WHERE rn = 1
)
This is too long for a comment.
You are describing three different tables:
Users
Organizations
UserOrganizations
The last has one row per user and per organization. This provides the mapping between the two. This can be called a "mapping" table, "junction" table, or "association" table.
How you implement one admin per organization depends on the database you are using.
You do not need the admin_user column. You need a column isadmin.
When a user is registered, if he is the first in the organization, then the isadmin column has the value 1, otherwise 0
Also, you can use the AAA query to find the administrator
SELECT `table`.`user_id`, MIN(`table`.`registered_datetime`) WHERE `organisation_id`=...

How can I select users based on whether or not there are multiple rows for that user?

I recently had an interview question that was worded something like this:
Select all users from the user table where the user works for multiple businesses and has a salary over 90000 at at least one of the businesses.
Where each row represented a user. Some users had multiple rows (for when they worked for multiple businesses) and each had a businessId.
I'm still pretty new to SQL, I do a lot of basic select and update statements when writing application code, but I'm not sure how to go about doing this. Should I be using count to find out if there are multiple rows for one user? I'm not sure how to structure it with the where clause to check the salary.
Group by the user (for instance the name). Then you can use the having clause to do aggregate operations in the group - meaning for every user
select username
from users
group by username
having count(distinct businessId) > 1
and max(salary) > 90000

SQL to get X number of accounts from DB, which could be variable number of rows

I have a SQL Server table AccountAction which is denormalised. It is a flattened version of the Account and Action tables, which I'm hoping should be a lot quicker for reporting queries over millions of rows. One Account can have many Actions, so the table looks similar to:
Account Action
account1 action1
account1 action2
account1 action10
account2 action5
However I'm having some trouble getting the information back for a restricted subset in a simple stored procedure.
select Account, Action
from AccountAction
where ???
What I'm looking for is to get the first X accounts, with all their actions. So this will be a dynamic number of rows. So using the example table above if I passed in 1, I would get 3 rows (i.e. give me all rows for the first account).
(I don't mind that the account name will be in each row - it is pivoted elsewhere)
Do I need to use a ROWNUM or similar to restrict the rows? I'm sure this must be a simpler issue than I've found so far.
EDIT
The answers using TOP won't work, in the example I'd be wanting 3 rows returned if I said 'give me one (the first) account'. But how do I know there will be 3? Its dynamic. Also they may not be sequential, what if account1's action99 was at position 55 million in the results.
WITH
SequencedData
AS
(
SELECT
DENSE_RANK() OVER (ORDER BY Account) AS account_sequence_id,
*
FROM
AccountAction
)
SELECT
*
FROM
SequenceData
WHERE
account_sequence_id = ???
Or, for multiples...
WHERE
account_sequence_id BETWEEN 3 AND 5 -- For the 3rd, 4th and 5th accounts.
SELECT *
FROM AccountAction
WHERE account IN (SELECT account
FROM AccountAction
GROUP BY account HAVING account BETWEEN *start-account* AND *end-account*
ORDER BY account
)
Explanation: The subquery groups by the distinct accounts (and allows for more fine-grained selection criteria than a simple DISTINCT) and returns only those accounts. The outer SELECT gets you a variable number of rows depending on the distinct accounts fetched by the subquery.
EDIT: The above assumes that one can filter by the account field in AccountAction table; this is usually the case in tables that join a M:N relationship at DB level.
If I got the question right
then if u want to select initial 10 rows then use
SELECT TOP 10 Account, Action
FROM AccountAction
or if u want some initial 20 percent records then use-
SELECT TOP 10 PERCENT Account, Action
FROM AccountAction
did you try TOP?
declare #hoW_many int
set #hoW_many = 10
select top (#hoW_many) *
from AccountAction
A simple sub-select with top keyword (and distinct), would give you all actions for first X accounts
select * from AccountAction
where Account in
(select distinct top (#NumberOfAccounts) Account
from AccountAction order by Account)

Sql query - selecting top 5 rows and further selecting rows only if User is present

I kind of stuck on how to implement this query - this is pretty similar to the query I posted earlier but I'm not able to crack it.
I have a shopping table where everytime a user buys anything, a record is inserted.
Some of the fields are
* shopping_id (primary key)
* store_id
* user_id
Now what I need is to pull only the list of those stores where he's among the top 5 visitors:
When I break it down - this is what I want to accomplish:
* Find all stores where this UserA has visited
* For each of these stores - see who the top 5 visitors are.
* Select the store only if UserA is among the top 5 visitors.
The corresponding queries would be:
select store_id from shopping where user_id = xxx
select user_id,count(*) as 'visits' from shopping
where store_id in (select store_id from shopping where user_id = xxx)
group by user_id
order by visits desc
limit 5
Now I need to check in this resultset if UserA is present and select that store only if he's present.
For example if he has visited a store 5 times - but if there are 5 or more people who have visited that store more than 5 times - then that store should not be selected.
So I'm kind of lost here.
Thanks for your help
This should do it. It uses an intermediate VIEW to figure out how many times each user has shopped at each store. Also, it assumes you have a stores table somewhere with each store_id listed once. If that's not true, you can change SELECT store_id FROM stores to SELECT DISTINCT store_id FROM shopping for the same effect but slower results.
CREATE VIEW shop_results (store_id, user_id, purchase_count) AS
SELECT store_id, user_id, COUNT(*)
FROM shopping GROUP BY store_id, user_id
SELECT store_id FROM stores
WHERE 'UserA' IN
(SELECT user_id FROM shop_results
WHERE shop_results.store_id = stores.store_id
ORDER BY purchase_count DESC LIMIT 5)
You can combine these into a single query by placing the SELECT from the VIEW inside the sub-query, but I think it's easier to read this way and it may well be true that you want that aggregated information elsewhere in the system — more consistent to define it once in a view than repeat it in multiple queries.