Adding an extra statement to existing SQL - sql

I am trying to modify an SQL statement that returns the number of Incidents logged by a user. The current statement is -
SELECT
USERS.NAME,
Count(INCIDENTS_H.SERVICEREQNO)
FROM Sostenuto.sunrise.INCIDENTS_H INCIDENTS_H
INNER JOIN Sostenuto.sunrise.USERS USERS
ON INCIDENTS_H.OWNERACCOUNT = USERS.SERVICEREQNO
WHERE (INCIDENTS_H.ADDEDDATE >= {ts '2013-11-25 00:00:00'})
AND (INCIDENTS_H.OPERATIONID = 102005166)
AND (INCIDENTS_H.OWNERGROUP = 123000012
OR INCIDENTS_H.OWNERGROUP=123000031
OR INCIDENTS_H.OWNERGROUP=123000047)
AND (INCIDENTS_H.ADDEDBY=INCIDENTS_H.OWNERACCOUNT)
GROUP BY USERS.NAME
Which works fine. Howeever I need to add another clause into the statement from a different table, I need to also include-
INCIDENTS.ADDEDBY = INCIDENTS_H.OWNERACCOUNT
However I am struggling to modify the original statement to include this. Can anyone give me any pointers?

SELECT
USERS.NAME,
Count(INCIDENTS_H.SERVICEREQNO)
FROM Sostenuto.sunrise.INCIDENTS_H INCIDENTS_H
INNER JOIN Sostenuto.sunrise.USERS USERS
ON INCIDENTS_H.OWNERACCOUNT = USERS.SERVICEREQNO
INNER JOIN INCIDENTS I
ON INCIDENTS.ADDEDBY = INCIDENTS_H.OWNERACCOUNT
WHERE (INCIDENTS_H.ADDEDDATE >= {ts '2013-11-25 00:00:00'})
AND (INCIDENTS_H.OPERATIONID = 102005166)
AND (INCIDENTS_H.OWNERGROUP = 123000012
OR INCIDENTS_H.OWNERGROUP=123000031
OR INCIDENTS_H.OWNERGROUP=123000047)
AND (INCIDENTS_H.ADDEDBY=INCIDENTS_H.OWNERACCOUNT)
GROUP BY USERS.NAME

try:
SELECT u.NAME, Count(h.SERVICEREQNO)
FROM Sostenuto.sunrise.INCIDENTS_H h
Join Sostenuto.sunrise.USERS u
ON h.OWNERACCOUNT = u.SERVICEREQNO
Join Incidents i
On i.ADDEDBY = h.OWNERACCOUNT
WHERE (h.ADDEDDATE>={ts '2013-11-25 00:00:00'})
AND (h.OPERATIONID=102005166)
AND (h.OWNERGROUP=123000012 OR h.OWNERGROUP=123000031 OR h.OWNERGROUP=123000047)
AND (h.ADDEDBY=h.OWNERACCOUNT)
GROUP BY u.NAME

Related

PostgreSQL query optimize

Here is my query
SELECT
DISTINCT(org.id),
org.name,
org.partner_id,
pos.partner_id,
pos.id,
org.partner_offer_section_id,
pos.title,
pos.offer_value,
pos.offer_currency,
(SELECT user_info.email FROM user_info WHERE user_info.org_id=org.id ORDER BY created ASC LIMIT 1) as user_email,
(SELECT CONCAT(user_info.first_name,' ',user_info.last_name) FROM user_info WHERE user_info.org_id=org.id ORDER BY created ASC LIMIT 1) as name
FROM org
INNER JOIN partner_offer_section pos ON org.partner_offer_section_id = pos.id
WHERE org.partner_offer_section_id != 0 AND org.partner_id != 0
Here is the same subquery that is executing the twice the same query. I was trying to left join this query but the problem is when I left join I got a null value. I have to get one user name or user email insted of multiple users aginst org.
SELECT org.name,
org.partner_id,
org.partner_offer_section_id,
org.offer_applied_date,
partner_offer_section.title,
partner_offer_section.offer_value,
partner_offer_section.offer_currency,
user_info.email
FROM org
left join (SELECT user_info.id, user_info.email,user_info.created, user_info.org_id FROM user_info WHERE role='Org Admin' LIMIT 1) user_info on org.id = user_info.org_id
left join partner_offer_section on org.partner_offer_section_id = partner_offer_section.id
where org.partner_id = 1
Now I wanna optime this query instead of multiple same subqueries.
You should join the table directly instead of doing a subquery. Bellow is the example, making a JOIN with the first table and the LEFT only with the last one. Also, DISTINCT applies to all columns, it's not a function, as user #a_horse_with_no_name pointed out
SELECT DISTINCT
org.name,
org.partner_id,
org.partner_offer_section_id,
org.offer_applied_date,
partner_offer_section.title,
partner_offer_section.offer_value,
partner_offer_section.offer_currency,
user_info.email
FROM org
join partner_offer_section on org.partner_offer_section_id = partner_offer_section.id
left join user_info on org.id = user_info.org_id
and user_info.role='Org Admin'
where org.partner_id = 1

Oracle SQL - how to NOT SHOW athlete name that apears only once

created a view called winners, it contains the columns: athlete_name,year,medal_won
its basicly athletes that won olympic medal and the year,
it look like that,
data base is in live sql: https://livesql.oracle.com/apex/f?p=590:1000:0
select distinct year,athlete_name,medal
from olym.olym_medals
join olym.olym_athlete_games on olym_athlete_games.id = olym_medals.athlete_game_id
join olym.olym_nations on olym_nations.id = olym_athlete_games.nation_id
join olym.olym_games on olym_games.id = Olym_athlete_games.game_id
join olym.olym_athletes on olym_athletes.id = olym_athlete_games.athlete_id
order by athlete_name
as you can see some name show only once and some names are showing more than once, i want to get rid off all lines of those who show ONLY ONCE, please help me.
thank you!
if i have understand your problem, must group your data,
select year,athlete_name,medal, count(*) "number of Medals"
from olym.olym_medals
join olym.olym_athlete_games on olym_athlete_games.id = olym_medals.athlete_game_id
join olym.olym_nations on olym_nations.id = olym_athlete_games.nation_id
join olym.olym_games on olym_games.id = Olym_athlete_games.game_id
join olym.olym_athletes on olym_athletes.id = olym_athlete_games.athlete_id
group by year,athlete_name,medal;
If I followed you correctly, you can use window functions:
select *
from (
select og.year, oa.athlete_name, om.medal, count(*) over(partition by oa.id) cnt
from olym.olym_medals om
join olym.olym_athlete_games oag on oag.id = om.athlete_game_id
join olym.olym_nations ona on ona.id = oag.nation_id
join olym.olym_games og on og.id = oag.game_id
join olym.olym_athletes oa on oa.id = oag.athlete_id
) t
where cnt > 1
order by athlete_name
Notes:
I am unsure why you were using distinct in the first place, so I removed it (I suspect it is actually not needed)
I added table aliases to shorten the query, and prefixed the columns in the select clause with the table they belong to (you might want to review that) - these are best practices when dealing with multi-table queries
Use GROUP BY and HAVING COUNT(*) > 1:
SELECT year,
athlete_name,
medal
FROM olym.olym_medals
INNER JOIN olym.olym_athlete_games
ON olym_athlete_games.id = olym_medals.athlete_game_id
INNER JOIN olym.olym_nations
ON olym_nations.id = olym_athlete_games.nation_id
INNER JOIN olym.olym_games
ON olym_games.id = Olym_athlete_games.game_id
INNER JOIN olym.olym_athletes
ON olym_athletes.id = olym_athlete_games.athlete_id
GROUP BY
year,
athlete_name,
medal
HAVING COUNT(*) > 1
ORDER BY athlete_name

Finding user with max(Audit_Date) and date not in range

I'm working on a SQL query where the user's maximum Audit_Date is not in a range, as in they haven't used the system for a long time. I tried it this way:
SELECT DISTINCT
UserID
,max(Audit_Date)
FROM RV_USERS RV_USERS
INNER JOIN RV_AUDIT RV_AUDIT ON
RV_USERS.UserID=RV_AUDIT.UserID
group BY RV_USERS.UserID
AND --it doesn't like the "and" here
not exists(
select *
FROM RV_USERS RV_USERS
INNER JOIN RV_AUDIT RV_AUDIT ON ON RV_USERS.UserID=RV_AUDIT.UserID
where
Audit_Date not between '2019-05-29 00:00:00' and '10/29/2019'
)
I tried to use not exists, like the example but it's not working in this case. I get incorrect syntax near the keyword 'AND', right before the not exists. I need to make a view out of this so I think variables and temp tables are out. It's going to be used in a crystal report and scheduled in Central Management Console.
**Update1: Tried this per answer:
SELECT DISTINCT
"RV_USERS"."UserID"
,"RV_AUDIT"."Audit_Date"
FROM "RV_USERS" "RV_USERS"
INNER JOIN "RV_AUDIT" "RV_AUDIT" ON "RV_USERS"."UserID"="RV_AUDIT"."UserID"
group BY "RV_USERS"."UserID", "RV_AUDIT"."Audit_Date"
HAVING
max("RV_AUDIT"."Audit_Date") < '2019-05-29 00:00:00'
and
"RV_USERS".UserID='me'
This returns me with dates in may, even though I have used the system since May. I checked that by removing the max date part and see my dates go to today.
**Update2: Tried this per other answer:
SELECT DISTINCT
"RV_USERS"."UserID"
,max("RV_AUDIT"."Audit_Date")
FROM "RV_USERS" "RV_USERS"
INNER JOIN "RV_AUDIT" "RV_AUDIT" ON "RV_USERS"."UserID"="RV_AUDIT"."UserID"
WHERE
not exists(
select *
FROM "RV_USERS" u2
INNER JOIN "RV_AUDIT" a2 ON u2."UserID"=a2."UserID"
where
a2."Audit_Date" not between '2019-05-27 00:00:00' and '10/31/2019'
)
group BY "RV_USERS"."UserID"
This is not returning anything, but we know there are managers that haven't used the system.
**Update 3 per answer:
SELECT DISTINCT
u."UserID"
,max(a."Audit_Date")
FROM "RV_USERS" u
INNER JOIN "RV_AUDIT" a ON u."UserID"=a."UserID"
WHERE
u.UserID not in(
select u2.UserID
FROM "RV_USERS" u2
INNER JOIN "RV_AUDIT" a2 ON u2."UserID"=a2."UserID"
where
a2."Audit_Date" between '2019-05-27 00:00:00' and '10/31/2019'
)
group BY u."UserID"
You have more than one mistakes, here is corrected code:
SELECT DISTINCT
RV_U.UserID
, max(RV_U.Audit_Date)
FROM RV_USERS RV_U
INNER JOIN RV_AUDIT RV_A ON RV_U.UserID=RV_A.UserID
WHERE
NOT EXISTS(
SELECT *
FROM RV_USERS RV_USERS
INNER JOIN RV_AUDIT RV_AUDIT ON RV_USERS.UserID=RV_AUDIT.UserID
WHERE Audit_Date not between '2019-05-29 00:00:00' and '10/29/2019'
)
GROUP BY RV_U.UserID;
Your line NNER JOIN RV_AUDIT RV_AUDIT ON ON
RV_USERS.UserID=RV_AUDIT.UserID has ON two times.
GROUP BY should go on the end
AND should be replaced with WHERE
Try to implement this changes.
I would suggest a having clause:
SELECT UserID, max(Audit_Date)
FROM RV_USERS RV_USERS INNER JOIN
RV_AUDIT RV_AUDIT
ON RV_USERS.UserID = RV_AUDIT.UserID
GROUP BY RV_USERS.UserID
HAVING max(Audit_Date) < '2019-05-29';
Your query seems much more complicated than necessary.
Replace and with where clause and put the group by at the last to make the above query run atleast

Why is my SQL Count Statement is counting too many times

I have a query that is supposed to count how many times a user has logged into two different versions of our software based on unique session ids. My count in my outer select statement however is counting way too many times. For example I get 31000 sessions for one user which is incorrect. It should be something more like 40. Why is this happening?
SELECT X.FirstName, X.LastName, X.CompanyName, X.AQ8Sessions, AQ360Sessions = COUNT(RRUI.SessionId)
FROM(
SELECT RRUI.UserId, RRUI.FirstName, RRUI.LastName, RRUI.CompanyName, COUNT(distinct RRUI.SessionId) AQ8Sessions
FROM Authentication.dbo.RegReportUserInfo RRUI
INNER JOIN Authentication.dbo.RegReportSessions RRS
ON RRUI.SessionId = RRS.SessionId
INNER JOIN WebCatalog.Published.People P
ON P.PKey = RRUI.UserId
WHERE RRUI.ClientType = 'aq8' AND RRS.ExpiresAt <= '2013-11-24 23:59:59.999'
AND RRS.ExpiresAt >= '2013-11-18 00:00:00.000' AND RRUI.CompanyName NOT LIKE 'AutoQuotes%'
AND P.EMail NOT LIKE '%#aqnet.com'
GROUP BY RRUI.FirstName, RRUI.LastName, RRUI.CompanyName, RRUI.UserId
) X
INNER JOIN Authentication.dbo.RegReportSessions RRS
ON RRS.UserId = X.UserId
AND RRS.ExpiresAt <= '2013-11-24 23:59:59.999'
AND RRS.ExpiresAt >= '2013-11-18 00:00:00.000'
LEFT OUTER JOIN Authentication.dbo.RegReportUserInfo RRUI
ON X.UserId = RRUI.UserId AND RRUI.ClientType = 'aq360'
GROUP BY X.FirstName, X.LastName, X.CompanyName, X.AQ8Sessions
ORDER BY X.AQ8Sessions DESC, COUNT(RRUI.SessionId) DESC
Hard to say for sure without seeing the data but I expect one or both of these will fix it:
COUNT(DISTINCT RRUI.SessionId)
and / or
INNER JOIN Authentication.dbo.RegReportUserInfo
where you had
LEFT OUTER JOIN Authentication.dbo.RegReportUserInfo

Order By is ignored in Rails Group By query

All I'm trying to do is order posts by the number of impressions (an impression is created when someone views the post) over the past 7 days. This is my named scope
scope :popular_last_week, unscoped
.select("websites.*, COUNT(impressions.id) AS counted_impressions")
.joins("INNER JOIN impressions ON websites.id = impressions.impressionable_id")
.where("impressions.created_at >= ?", 7.days.ago)
.where(:is_published => true)
.group("websites.id")
.order("counted_impressions DESC")
("counted_impressions" is used to avoid a conflict on post record)
Yet this produces the following invalid SQL (counted_impressions is not a valid column):
SELECT COUNT(*) AS count_all, websites.id AS websites_id FROM "websites" INNER JOIN impressions ON websites.id = impressions.impressionable_id WHERE "websites"."is_published" = 't' AND (impressions.created_at >= '2013-01-11 17:48:03.954542') GROUP BY websites.id ORDER BY counted_impressions
Seems the select statement is just ignored. Where am I going wrong, or how should I do it so that the SQL statement is:
SELECT websites.*, COUNT(impressions.id) AS counted_impressions FROM "websites" INNER JOIN impressions ON websites.id = impressions.impressionable_id
WHERE "websites"."is_published" = 't' AND (impressions.created_at >= '2013-01-11 17:42:57.771777') GROUP BY websites.id ORDER BY counted_impressions DESC
Try this:
scope :popular_last_week, unscoped
.select(arel_table[Arel.star])
.select(Website.arel_table[:id].count.as("counted_impressions"))
.joins("INNER JOIN impressions ON websites.id = impressions.impressionable_id")
.where("impressions.created_at >= ?", 7.days.ago)
.where(:is_published => true)
.group("websites.id")
.order("counted_impressions DESC")
Seems like the query should be:
SELECT count(*) AS impression_count, w.id AS website_id
FROM websites as w
INNER JOIN impressions as i ON w.id = i.impressionable_id
WHERE w.is_published = 't' AND i.created_at >= '2013-01-11 17:48:03.954542'
GROUP BY w.id
ORDER BY impression_count DESC;
Seems like you could skip the join in this query and then run the "is_published" check on the next query to get the actual post data... assuming you're only using this query to get a list of ID's for a second query that gets the data.