Joining multiple different update queries into single query - PostgreSQL - sql

Apologies if something similar has been asked before, currently I run 3 different update queries in order to get the desired result. The Queries are as follows,
UPDATE users SET enabled = false where username in (SELECT username
FROM users WHERE enabled = true AND lastaccess != 0 AND lastaccess
< (EXTRACT('epoch' FROM CURRENT_TIMESTAMP) - (86400*200))*1000 AND
username NOT LIKE ('admintest%'));
Once this query runs (disabling all users who haven't accessed the system in a certain period), then I run the following 2 Queries on the whole table,
update users set weeklypopupuse = 0;
update users set monthlypopupuse = 0;
These 2 queries then reset the weekly and monthly use to 0.
Now this works perfectly fine as per the requirements, however is there a more elegant way of writing all these 3 queries into a single query which gives the same result.
Any help or advice will be highly appreciated. Thanks in advance

update
after OP gave full structure, refactored to:
update users
set
weeklypopupuse = 0
, monthlypopupuse = 0
, enabled = case
when
enabled = true
AND lastaccess != 0
AND lastaccess < (EXTRACT('epoch' FROM CURRENT_TIMESTAMP) - (86400*200))*1000
AND username NOT LIKE ('admintest%')
then false
end

Related

SQL Update each row until none of them are 0

I'm trying to use the following code to update a column in each of my rows until none of them are 0 (The default value). Here's my code:
UPDATE PERSON
WHILE = 0
SET TEAM = 1
WHERE TEAM = 0;
No need for a while, also the syntax is wrong for plsql block
UPDATE PERSON --UPDATING TABLE PERSONS
SET TEAM = 1
WHERE TEAM = 0; --WHEN IT'S 0 IT UPDATES
The above query will do what you asked.
Should work for mysql and oracle.
Hope my answer helps you.
No need to loop SQL can handle this in a single command.
UPDATE Person SET Team = 1 WHERE Team = 0

SQL Update table - 2 tables based on date - Table 2 Subset of table 1

Ok I have a rather unique situation and I can't believe there is not a better way of doing this than my solution.
Requirements:
Table 2 - EpmTask_UserView_RM is a subset of table 1 -
MSP_EpmTask_UserView So while all the fields match Table 1 has many
more rows than table 2
Table 2 needs to get updated from table 1 based on the date a task has changed (We can't do a drop and replace) There are three cases:
Task updates where something has changed about the task (We will know based on the task date stamp)
Task Deletes where a task has been deleted
Task Adds where a new task exists
I have 3 different queries that do this and am thinking there is a better way.
**** DELETE Tasks from ZZZ_TEST_OF_UPDATE_MSP_EpmTask_UserView_RM table if no longer present in Production***/
USE [ProjectWebApp]
GO
DELETE FROM [dbo].[ZZZ_TEST_OF_UPDATE_MSP_EpmTask_UserView_RM]
WHERE [dbo].[ZZZ_TEST_OF_UPDATE_MSP_EpmTask_UserView_RM].TaskUID IN
(SELECT
/*Subquery to select all records in ZZZ_TEST_OF_UPDATE_MSP_EpmTask_UserView_RM NOT found in MSP_EpmTask_UserView_RM */
[ProjectWebApp].[dbo].[ZZZ_TEST_OF_UPDATE_MSP_EpmTask_UserView_RM].[TaskUID]
FROM [ProjectWebApp].[dbo].[ZZZ_TEST_OF_UPDATE_MSP_EpmTask_UserView_RM]
LEFT JOIN [MSPSPRO].[ProjectWebApp].[dbo].[MSP_EpmTask_UserView] as Prod
on Prod.TaskUID = [ProjectWebApp].[dbo].[ZZZ_TEST_OF_UPDATE_MSP_EpmTask_UserView_RM].TASKuid
where Prod.TaskUID is NULL)
Query 2 the Update
UPDATE [dbo].[ZZZ_TEST_OF_UPDATE_MSP_EpmTask_UserView_RM]
SET
[ProjectUID] = Source.[ProjectUID]
,[TaskUID] = Source.[TaskUID]
,[TaskName] = Source.[TaskName]
,[TaskIndex] = Source.[TaskIndex]
,[TaskOutlineLevel] = Source.[TaskOutlineLevel]
,[TaskOutlineNumber] = Source.[TaskOutlineNumber]
,[TaskStartDate] = Source.[TaskStartDate]
,[TaskFinishDate] = Source.[TaskFinishDate]
,[TaskActualStartDate] = Source.[TaskActualStartDate]
,[TaskActualFinishDate] = Source.[TaskActualFinishDate]
,[TaskPercentCompleted] = Source.[TaskPercentCompleted]
,[Health] = Source.[Health]
,[Milestone Significance Level] = Source.[Milestone Significance Level]
,[TaskModifiedDate] = Source.[TaskModifiedDate]
,[TaskBaseline1StartDate] = Source.[TaskBaseline1StartDate]
,[TaskBaseline1FinishDate] = Source.[TaskBaseline1FinishDate]
,[TaskBaseline1Duration] = Source.[TaskBaseline1Duration]
,[QueryTimestamp] = GetDate()
FROM [MSPSPRO].[ProjectWebApp].[dbo].[MSP_EpmTask_UserView] AS Source
WHERE Source.TaskUID = [dbo].[ZZZ_TEST_OF_UPDATE_MSP_EpmTask_UserView_RM].TaskUID
AND GetDate() - Source.TaskModifiedDate <= .01 -- Update any task changed in last 14 minutes (14 minutes = 1% of a full day, ie '.01')
GO
Task 3 the add
SELECT
[MSP_EpmProject_UserView].[ProjectUID]
,[TaskUID]
,[TaskName]
,[TaskIndex]
,[TaskOutlineLevel]
,[TaskOutlineNumber]
,[TaskStartDate]
,[TaskFinishDate]
,[TaskActualStartDate]
,[TaskActualFinishDate]
,[TaskPercentCompleted]
,[Health]
,[Milestone Significance Level]
,[TaskModifiedDate]
,[TaskBaseline1StartDate]
,[TaskBaseline1FinishDate]
,[TaskBaseline1Duration]
,GetDate() as QueryTimestamp
INTO [ProjectWebApp].[dbo].[MSP_EpmTask_UserView_RM]
FROM [MSPSPRO].[ProjectWebApp].[dbo].[MSP_EpmTask_UserView]
Inner Join [MSPSPRO].[ProjectWebApp].[dbo].[MSP_EpmProject_UserView]
on [MSP_EpmProject_UserView].projectUID = [MSP_EpmTask_UserView].ProjectUID
WHERE [SMO Programs] = 'SMO Day 1 Release Management'
AND [Milestone Significance Level] is not null
/*AND [TaskModifiedDate] > (getdate() - 1)*/
Thoughts?
This looks like an ideal situation for a MERGE statement. If you haven't used them much or at all, I'd strongly suggest this site as a primer.
A MERGE can carry out INSERT, UPDATE, and DELETE in one shot, in the right conditions. The basic idea is that you compare rows in two tables, your source and destination, and from that comparison (and potentially other conditions) you then take the appropriate action.
MERGE can perform very well because it carries out these actions in bulk - but do test it out. Sometimes people have found them to be slower than using the separate statements in some situations. Indexing correctly (Microsoft suggest indexing the columns used to join in both tables) can help immensely. Writing the MERGE statement correctly and well is important in terms of both getting the right result, and getting good performance - so definitely do your reading up if you haven't used them before. The above link is a good starter, but there are plenty of other articles around.

sql - selecting, counting and Updating

I'm wondering if this is correct...
I want to select all users from teams in a match and then add a win, loose or draw to his profile.
$short = $_POST['short'];
$opponent = $_POST['opponent'];
$oppuser = safe_query("SELECT userID FROM ".PREFIX."teams_members WHERE teamID='".$opponent."'");
$shortuser = safe_query("SELECT userID FROM ".PREFIX."teams_members WHERE teamID='".$short."'");
safe_query("UPDATE ".PREFIX."teams_members SET win=win+1 WHERE userID='".$oppuser."'");
safe_query("UPDATE ".PREFIX."teams_members SET lost=lost+1 WHERE userID='".$shortuser."'");
Something is not allowing updating the rows.
You don't need those selects. Your update is not working because the select statement is returning you multiple entries. You can update the entire team without selecting the users:
$short = $_POST['short'];
$opponent = $_POST['opponent'];
safe_query("UPDATE ".PREFIX."teams_members SET win=win+1 WHERE teamID='$opponent'");
safe_query("UPDATE ".PREFIX."teams_members SET lost=lost+1 WHERE teamID='$short'");

Applying the count function within the case function

I am relatively new to SQL and am trying to apply the case function within a view.
While I understand the fundamentals of it, I am having difficulty applying it in the way that I need.
I have 3 columns ApplicationID, ServerName and ServerShared? (true/false).
Each application can have many servers associated to it, while each server only has 1 server type.
I would like to use case to create a further field which can take three values dependent upon whether the values of ServerShared related to an application are all True = Shared, False = Non-shared, Both True and False = Partially shared.
My thoughts were using count function within the case function to set statements where:
if 'count true > 0 and count false > 0' then ServerShared? =
partially if 'count true > 0' and 'count false = 0' then
ServerShared = true and vice versa.
I believe the above logic a way of achieving my result, yet I would appreciate help in both how to structure this within a case statement and any wisdom if there is a better way.
Thanks in advance!
If I get your question right, this should do the trick. Maybe you need to add further columns or adapt the logic. But you should get the logic behind.
SELECT ServerName,
CASE
WHEN COUNT(distinct ServerShared) = 2
THEN N'Server shared'
WHEN MIN(ServerShared) = 0
THEN N'Server not shared'
WHEN MAX(ServerShared) = 1
THEN N'Server shared'
END as ServerShared
FROM myTable
GROUP BY ServerName
There are two main ways to do this problem (super generic answer from non expert :D)
less often executed (one off?), slow execution with potential exponential time increases as rows go up:
This is similar to your suggested solution and involves putting other queries in the Select / field list part of the query - this will get executed for every row returned by the main part of the query (bad news generally speaking):
select
applicationID
, Case (select count * from table as b where a.applicationid = b.applicationid and shareserver=true)
WHEN 0 then 'Non-Shared'
WHEN (select count * from table where a.applicationid = b.applicationid) then 'Shared'
ELSE 'Partially-Shared' END as ShareType
from
tabls as a
get all your data once then perform just the comparison row by row. this is what i would use by default.. its basically better as far as i know but sometimes can be harder to think through.
this line is here to fix formatting issue
select
a.applicationid
,case
when sharedservers = 0 then 'Non-Shared'
when totalservers=sharedservers then 'Shared'
else 'Partially-Shared' END as ShareType
FROM
(select applicationID, count(*) as TotalServers from table) as a
LEFT OUTER JOIN (select applicationID, count(*) as SharedServersfrom table where sharedserver = true) as b
ON a.applicationid=b.applicationid
these queries are just written off the top of my head let me know if there are bug :/
note also the two uses of case statement. one with CASE *value* WHEN *possible value* THEN .. and the second way CASE WHEN *statement that evaluates to boolean* THEN ..

SQL query for updating based on results

I am trying to update records based on a secondary statement but i dont know how to link them together.
UPDATE WEBSITE SET CMS_ID = 99
SELECT *
FROM website
WHERE is_scanned = 'yes'
AND cms_id =0
I want to update table website set the colum cms_id to 99 where all websites is_scanned = yes and cms_id = 0
will my query work?
This query doesn't work ?
UPDATE website SET cmd_id = 99
WHERE is_scanned = 'yes' AND cms_id = 0;
I think this accomplishes the goal you stated and should work in most databases:
UPDATE WEBSITE SET CMS_ID = 99
WHERE is_scanned = 'yes'
AND cms_id =0
The SELECT FROM is not required unless joins between different records or tables are important to the goal of the update. Here are some other examples for SQL Server