I have three tables called edum_application, edua_courseEvent and edua_coursePackage.
I'm writing a question to get all the applications from edum_application where all the courseEvent's coursePackage_id is x and all have the same applicationWrapper_id
This query works, but is it efficient?
SELECT app.application_id, app.applicationWrapper_id
FROM edum_application AS app
INNER JOIN edua_courseEvent AS ce ON app.courseEvent_id = ce.courseEvent_id
WHERE app.applicationWrapper_id = 662
AND app.courseEvent_id IN
(
-- Is this really efficient?
SELECT ce.courseEvent_id
FROM edua_courseEvent AS ce
WHERE ce.coursePackage_id =
(
SELECT coursePackage_id
FROM edua_courseEvent AS ce
WHERE ce.courseEvent_id = 13377
)
)
The output:
application_id applicationWrapper_id
72643 662
72645 662
72646 662
72647 662
Try this:
SELECT app.application_id, app.applicationWrapper_id
FROM edum_application AS app
INNER JOIN edua_courseEvent AS ce
ON app.courseEvent_id = ce.courseEvent_id
INNER JOIN edua_courseEvent AS ce2
ON ce.coursePackage_id = ce2.coursePackage_id
WHERE app.applicationWrapper_id = 662
AND ce2.courseEvent_id = 13377
You might need a DISTINCT depending on the number of rows in / relationships between the different tables.
Related
I have a FULLVISITORID in my table with 2 different visitid.
Each visitid has multiple hits. I want to select the visitid where one hits.page.pagepath = 'somepage'
and another hits.eventInfo.eventCategory = 'some event'. Both the conditions should be happening for the same visitid.
For Example:
Select * from my_table where FullVisitorid = '1'
FullVisitorid Visitid ........... hits.page.pagepath .....hits.event.eventCategory
1 123 A abc
B cde
c efg
1 147 somePage ggg
D fff
E SomeEvent
I want the result to be VistiID = 147 becuase the visitid has both pagepath = 'somepage' and eventcategory = 'someevent'
Thanks for your help!
Using CTEs, you can use simple join logic to get your results.
with unnested as (
-- Get the fields you care about
select FullVisitorid, Visitid, h.page.pagepath, h.event.eventCategory
from `dataset.table`
left join unnest(hits) h
),
somepage as (
-- Get somepage hit Visitids
select FullVisitorid, Visitid
from unnested
where pagepath = 'somepage'
group by 1,2
),
someevent as (
-- Get someevent hit Visitids
select FulVisitorid, Visitid
from unnested
where eventCategory = 'someevent'
group by 1,2
),
joined as (
-- Join the CTEs to get common Visitids
select FulVisitorid, Visitid
from somepage
inner join someevent using(FullVisitorid, Visitid)
)
select * from joined
I'd like to do something like this in postgres
select * from table t where t.one = 11 AND t.two = 12 and t.three = 13
union all
select * from table t where t.one = 21 AND t.two = 22 and t.three = 23
I tried join lateral and inner joins but the performance is too bad. So I need to union all these queries but I don't want just to concat an indefinate amount of these values, Is there something like these https://stackoverflow.com/a/55484168/1321514 for postgres?
I don't see the need for a UNION at all. And I don't understand how a JOIN would help here
Your query is equivalent to:
select *
from table t
where (t.one,t.two,t.three) in ( (11,12,13), (21,22,23) );
Alternatively you can try joining to a VALUES clause:
select t.*
from table t
join (
values (11,12,13), (21,22,23)
) as x(c1,c2,c3) on t.one = x.c1
and t.two = x.c2
and t.three = x.c3;
I'm trying to select data in a table for companies and dates that don't exist for a different type/id of data.
Put another way, I want company_id, dates_id, daily_val where wh_calc_id = 344 if the same company_id/dates_id combination doesn't exist where wh_calc_id = 368.
I'm loosely following this example:
Select rows which are not present in other table
These are my two attempts at it:
attempt 1:
SELECT distinct on (company_id, dates_id) company_id, dates_id, daily_val
FROM daily_data d1
WHERE NOT EXISTS (
SELECT 1
FROM daily_data d2
WHERE d1.company_id = d2.company_id
and d1.dates_id = d2.dates_id
and d1.wh_calc_id = 368
and d2.wh_calc_id = 368
)
and d1.wh_calc_id = 344
The problem:
It's super slow: 27 minutes
attempt 2: [removed]
All in one (giant) table:
company_id int (indexed),
dates_id int (indexed),
wh_calc_id int (indexed),
daily_val numeric
I'm open to adding an index that would help speed things up, but what index?
Postgres 10
PS - I've had to kill both queries before they completed, so I don't really know if they are written correctly. Hopefully my description helps.
I would do it with a left join this way:
SELECT distinct on (company_id, dates_id) company_id, dates_id, daily_val FROM daily_data d1 LEFT JOIN daily_data d2 ON d1.company_id = d2.company_id and d1.dates_id = d2.dates_id and d1.wh_calc_id = 368 and d2.wh_calc_id = 368 WHERE d1.wh_calc_id = 344 AND d2.company_id IS NULL;
and create the index over the columns to use:
Create index on table daily_data ( company_id, dates_id, wh_calc_id);
This does what I want I think:
SELECT
d1.*
from
daily_data d1
LEFT JOIN
daily_data d2
ON
d1.company_id = d2.company_id
AND d1.dates_id = d2.dates_id
AND d2.wh_calc_id = 368
AND d1.wh_calc_id = 344
where
and d1.wh_calc_id = 344
and d2.wh_calc_id is null
I have the following sql query Performing badly:
SELECT
Count(ExtCardID) as CardCount
from
CardIDs CARDS with (NoLock)
inner join
(select CustomerPK
from GroupMembership with (NoLock)
where CustomerGroupID = 14 and Deleted = 0) as GM on GM.CustomerPK = CARDS.CustomerPK
The following Select part from the above join returned 8 million records:
select
CustomerPK from GroupMembership with (NoLock)
where
CustomerGroupID = 14 and Deleted = 0
Is there a better way to write the above sql code? Please advise.
Did you try with LINQ?
LINQ is quite good rather than direct query!
Great Article
I need to update a field with concatenated results from a T-SQL query that uses an INNER JOIN and a LEFT JOIN. I was able to do this with the STUFF and FOR XML PATH functions with a simpler query, but my efforts at doing the same process with a more elaborate query have not been successful.
Here is the query that gives me the results I need with the ID field going to end up as the grouping and the Step field will be the one where the concatenated values need to be in the one field per one ID.
SELECT sc.ID, sc.STEP
FROM Table1 As sc
INNER JOIN Table2 As f
ON sc.STEP = f.Step AND sc.STEP_TYPE = f.StepType AND
sc.OldStep = f.OldStep
LEFT JOIN Table3 As l
ON sc.ID = l.ID
WHERE f.Group = l.Group AND sc.CompDate IS NULL
That will give me my results broken down into multiple fields per ID
•ID-----STEP
01 - 101
01 - 102
01 - 103
02 - 107
02 - 113
And what I need is:
•ID-----STEP
01 - 101, 102, 103
02 - 107, 113
Here is what i've tried so far:
;With OA As
( SELECT s.ID, STUFF((
SELECT ', ' + sc.STEP
FROM Table1 As sc
WHERE sc.ID = s.ID
ORDER BY sc.ID
FOR XML PATH('')),1,1,'') As Steps
FROM Table1 As s
INNER JOIN Table2 As f
ON s.STEP = f.Step AND s.STEP_TYPE = f.StepType
AND s.OldStep = f.OldStep
LEFT JOIN Table3 As l
ON s.ID = l.ID
WHERE f.Group = l.Group AND s.CompDate IS NULL
GROUP BY s.ID
)
SELECT * FROM OpenAuditSteps
The problem here is that I am getting a concatenation of all the reocrds, not just the ones grouped on the individual ID's. I've tried various ways of arranging the joins, but nothing has worked so far.
You are very nearly there: You already have your first query working. Assuming the results of that go into #Table1 then
SELECT Distinct
sc1.ID,
STUFF (( Select ',' + sc2.STEP
FROM #Table1 AS SC2
WHERE sc2.ID = sc1.ID
FOR XML PATH('')),1,1,'') AS STEPS
FROM #Table1 AS SC1
ORDER BY sc1.ID
So to combine it into one single query using WITH try this:
;WITH IDSteps AS (
SELECT sc.ID, sc.STEP
FROM Table1 As sc
INNER JOIN Table2 As f
ON sc.STEP = f.Step AND sc.STEP_TYPE = f.StepType AND
sc.OldStep = f.OldStep
LEFT JOIN Table3 As l
ON sc.ID = l.ID
WHERE f.Group = l.Group AND sc.CompDate IS NULL
)
SELECT Distinct
sc1.ID,
STUFF (( Select ',' + sc2.STEP
FROM IDSteps AS SC2
WHERE sc2.ID = sc1.ID
FOR XML PATH('')),1,1,'') AS STEPS
FROM IDSteps AS SC1
ORDER BY sc1.ID;