Can anyone help me to optimize my query? - sql-server-2008

SELECT p.ID, Name
FROM Policies p
INNER JOIN ProgramYears py ON p.ProgramYearID = py.id
INNER JOIN (SELECT MemberID, max(EffectiveDate) AS EffectiveDate
FROM Policies
GROUP BY MemberID) TEMP
ON p.memberid = TEMP.MemberID
AND p.EffectiveDate = TEMP.effectivedate
AND p.memberid NOT IN (SELECT MemberID
FROM InvoiceDetail
WHERE ProgramYear = NAME)

NOT EXISTS is usually a better substitute for NOT IN, but your choices largely depend on the data and the structure of your tables and indexes.
Try the query below, but compare its execution plan to that of your current query; what works for one scenario may not work for another.
SELECT p.ID, Name
FROM Policies p
INNER JOIN ProgramYears py ON p.ProgramYearID = py.id
INNER JOIN (SELECT MemberID, max(EffectiveDate) AS EffectiveDate
FROM Policies
GROUP BY MemberID) TEMP
ON p.memberid = TEMP.MemberID
AND p.EffectiveDate = TEMP.effectivedate
WHERE NOT EXISTS
(SELECT MemberID
FROM InvoiceDetail AS ID
WHERE ID.ProgramYear = NAME
AND p.MemberId = ID.MemberId)

You can try:
SELECT a.ID, a.Name
FROM (SELECT p.ID, Name,
ROW_NUMBER()OVER(PARTITION BY p.memberid ORDER BY p.EffectiveDate DESC) AS rnk
FROM Policies p
INNER JOIN ProgramYears py ON p.ProgramYearID = py.id
WHERE NOT EXISTS (SELECT MemberID
FROM InvoiceDetail AS ID
WHERE ID.ProgramYear = NAME
AND p.MemberId = ID.MemberId)
) a
WHERE a.rnk = 1

Related

I need to get specific ids from db if these are in current and last quarter using SQL

[DB Table]
SELECT b.first_name, b.last_name, a.pod_name, a.category, c.user_id,
SUM(IF(QUARTER(CURDATE())-1 OR (QUARTER(CURDATE())-2) AND a.user_id, 1, 0)) AS flag FROM kudos a
INNER JOIN users b ON a.user_id = b.id INNER JOIN users_groups c ON a.user_id = c.user_id
INNER JOIN groups d ON c.group_id = d.id WHERE a.group_name = 'G2' AND d.id IN (7,8,9,11,12,13,14,15,16,17,21,22,23,24,25,26,27,28)
AND QUARTER(CURDATE())-1 = a.quarter ORDER BY a.final_score+0 DESC
I need to get the user_ids of those users which are both in quarter 1 and 2 from table.
Tried above query but failed to get expected results.
Can someone please guide me on this?
if you only need user_id then you can do this :
select user_id
from tablename
where quarter in (1,2)
group by user_id
having count(distinct quarter) = 2
another way is to use window function, assuming you have one user id in each quarter:
select * from (
select * , count(*) over (partition by user_id) cn
from tablename
where quarter in (1,2)
) t where cn = 2

Limit results to 1 row for each group in subquery

as a result of the execution of this query, situations are possible when two rows have the same minimum price, but i still need to select one. I understand perfectly well that the standard limit cannot be dispensed with here. I do not have enough knowledge to understand from which side to approach the solution of this issue. Thank you in advance for your attension.
UPDATE offers t1
SET t1.deleted_at = NOW()
WHERE t1.id
NOT IN
(
SELECT f.id
FROM (
SELECT name, MIN(net_price) as minprice
FROM offers
WHERE
supplier_id = (SELECT id FROM suppliers WHERE name = 'somename')
group BY name
)
AS x inner join (SELECT * FROM offers) AS f ON f.name = x.name AND f.net_price = x.minprice
)
AND
t1.supplier_id = (SELECT id FROM suppliers WHERE name = 'somename');
I don't know somehowe, but this works for me:
UPDATE offers t1
SET t1.deleted_at = NOW()
WHERE t1.id
NOT IN
(
SELECT f.id
FROM (
SELECT id, name, MIN(net_price) as minprice
FROM offers
WHERE
supplier_id = (SELECT id FROM suppliers WHERE name = 'somename')
group BY name
)
AS x inner join (SELECT * FROM offers) AS f ON f.id = x.id
)
AND
t1.supplier_id = (SELECT id FROM suppliers WHERE name = 'somename');
Just add id to subquery select and put it on inner join f.id = x.id

Having trouble with a nested JOIN

So I'm trying to combine a number of queries, and I'm running into an issue:
SELECT OFFERS.ID AS ID, OFFERS.NAME as NAME, PROGRAM_ID, OFFER_TYPE, DATE_CREATED, PROGRAMS.NAME as PROGRAM_NAME, CLICKS_IN, CLICKS_OUT, SALES
FROM
(OFFERS INNER JOIN PROGRAMS ON PROGRAMS.ID = OFFERS.PROGRAM_ID)
INNER JOIN
(SELECT COUNT(*) AS CLICKS_IN FROM CLICKS_IN WHERE OFFER = ID)a
INNER JOIN
(SELECT COUNT(*) AS CLICKS_OUT FROM CLICKS_OUT WHERE OFFER = ID)b
INNER JOIN
(SELECT SUM(REVENUE) AS SALES FROM CONVERSIONS WHERE LOCAL_OFFER = ID)c
WHERE OFFER_ACTIVE = 1 AND OFFERS.USER_GROUP = ?
I want the OFFER = ID queries to be using the value from OFFERS.ID AS ID but I'm stumped as to how to get it to accomplish that.
I think your initial parenthesis are just confusing matters a bit, and the type of selects you are using are more appropriate for subqueries in the SELECTs expression list; try it this way instead:
SELECT OFFERS.ID AS ID, OFFERS.NAME as NAME, PROGRAM_ID, OFFER_TYPE
, DATE_CREATED, PROGRAMS.NAME as PROGRAM_NAME, CLICKS_IN, CLICKS_OUT, SALES
FROM OFFERS
INNER JOIN PROGRAMS ON PROGRAMS.ID = OFFERS.PROGRAM_ID
INNER JOIN
(SELECT OFFER, COUNT(*) AS CLICKS_IN FROM CLICKS_IN GROUP BY OFFER) AS a
ON a.OFFER = OFFERS.ID
INNER JOIN
(SELECT OFFER, COUNT(*) AS CLICKS_OUT FROM CLICKS_OUT GROUP BY OFFER) AS b
ON b.OFFER = OFFERS.ID
INNER JOIN
(SELECT LOCAL_OFFER, SUM(REVENUE) AS SALES FROM CONVERSIONS GROUP BY LOCAL_OFFER) AS c
ON c.LOCAL_OFFER = OFFERS.ID
WHERE OFFER_ACTIVE = 1 AND OFFERS.USER_GROUP = ?
This method, as opposed to correlated subqueries (subqueries that reference outer queries), tends to be more efficient unless the tables involved in the subqueries are really huge, and/or you expect very few results in the end. In such cases, your original subqueries can be moved to the SELECT clause almost "as is":
SELECT o.ID AS ID, o.NAME as NAME, PROGRAM_ID, OFFER_TYPE, DATE_CREATED, PROGRAMS.NAME as PROGRAM_NAME
, (SELECT COUNT(*) FROM CLICKS_IN AS t WHERE t.OFFER = o.ID) AS CLICKS_IN
, (SELECT COUNT(*) FROM CLICKS_OUT AS t WHERE t.OFFER = o.ID) AS CLICKS_OUT
, (SELECT SUM(REVENUE) FROM CONVERSIONS AS t WHERE t.LOCAL_OFFER = o.ID) AS SALES
FROM OFFERS AS o INNER JOIN PROGRAMS ON PROGRAMS.ID = o.PROGRAM_ID
WHERE OFFER_ACTIVE = 1 AND o.USER_GROUP = ?
Sidenote: In queries involving multiple tables it is a good practice to fully qualify any field names used. (For example, I can't be sure where any of these fields come from: PROGRAM_ID, OFFER_TYPE, DATE_CREATED, OFFER_ACTIVE).

Get Value from INNER JOIN 3 table with LASTEST RECORD from each table

I get problem to get value from some of tables. You can see picture below, I wanna get row what I block with red color.
I try with code below
SELECT p.id,
p.email,
p.name,
p.lastname,
p.gender,
ex.startwork,
ex.endwork,
e.degree,
e.majority,
j.division
FROM job_jobseeker AS p
INNER JOIN job_experience AS ex
ON p.email = (SELECT ex.email
FROM job_experience
ORDER BY ex.id DESC
LIMIT 1)
INNER JOIN job_education AS e
ON p.email = (SELECT e.email
FROM job_education
ORDER BY ex.id DESC
LIMIT 1)
INNER JOIN job_applying AS j
ON p.email = (SELECT j.email
FROM job_applying
ORDER BY ex.id DESC
LIMIT 1)
You need correlated sub-queries.
Find the latest id for each email in all the three tables
SELECT startwork,
endwork,
email
FROM job_experience a
WHERE a.id = (SELECT Max(b.id)
FROM job_experience b
WHERE a.email = b.email)
The above query will find the latest id for each email in job_experience table. Do the same for other two tables as well, then join the result with job_jobseeker table to get the result.
SELECT p.id,
p.email,
p.name,
p.lastname,
p.gender,
ex.startwork,
ex.endwork,
e.degree,
e.majority,
j.division
FROM job_jobseeker AS p
INNER JOIN (SELECT startwork,
endwork,
email
FROM job_experience a
WHERE a.id = (SELECT Max(b.id) FROM job_experience b
WHERE a.email = b.email)) AS ex
ON p.email = ex.email
INNER JOIN (SELECT email, //Just called column without initialize
degree,
majority
FROM job_education a
WHERE a.id = (SELECT Max(b.id) FROM job_education b
WHERE a.email = b.email)) AS e
ON p.email = e.email
INNER JOIN (SELECT email, //Just called column without initialize
division
FROM job_applying a
WHERE a.id = (SELECT Max(b.id) FROM job_applying b
WHERE a.email = b.email)) AS j
ON p.email = j.email

Mysql query distinct + multiple

I want to do this query:
SELECT *
FROM user k
INNER JOIN (
SELECT id, tagName, b.guid, name, owner, publicKey
FROM noteTags a
INNER JOIN (
SELECT *
FROM note
ORDER BY guid
LIMIT 0 , 12
)b ON a.guid = b.guid ORDER BY b.id DESC
)l ON k.owner = l.owner
But I want it to return DISTINCT b.guids.
Structure of the tables:
note
|
|=id
|=name
|=guid
|=owner
|=publicKey
noteTags
|
|=guid
|=tagName
user
|
|=owner
|=username
|=auth
Basically I want to select ALL data (with the limit on the deeper inner join) and return DISTINCT guids
Thanks!
Here's my initial answer,
SELECT *
FROM note a
INNER JOIN user b
ON a.owner = b.owner
INNER JOIN notetags c
ON a.guid = b.guid
INNER JOIN
(
SELECT guid, MAX(tagName) maxTag
FROM notetags
GROUP BY guid
) d ON c.guid = d.guid AND
c.tagName = d.maxTag
How about:
SELECT *
FROM user k
INNER JOIN (
SELECT id, tagName, b.guid, name, owner, publicKey
FROM noteTags a
INNER JOIN (
select id, name, MIN(guid) as guid, owner, publicKey
FROM note
GROUP BY guid
LIMIT 0 , 12
)b ON a.guid = b.guid ORDER BY b.id DESC
)l ON k.owner = l.owner