I have the following Data Set :
| user_id | Campaingid| <br>
| 1 | campaign1| <br>
| 1 | campaign2| <br>
| 2 | campaign1| <br>
| 1 | campaign3| <br>
| 3 | campaign5| <br>
| 3 | campaign2|<br>
| 3 | campaign3|<br>
| 4 | campaign6| <br>
| 5 | campiagn5| <br>
I am trying to find the overlap of user_id in campaigns, in other words, how many people in campaign1 were also in campaign2:
I am able to find the distinct users in each campaign by using a group on the campaign id, but I need help with the overlap between different campaigns: The results I am trying to achieve can be demonstrated with a matrix below:
Campaign ID| 1 | 2 | 3 | 4| 5| 6| <br>
1 <br>
2 <br>
3 <br>
4 <br>
The diagonal gives the people exclusively in campaign1, campaign1-campaign2 is the people who are in campaign1 and also camapaign2.
Is there a way to do it in SQL (Bigquery).
Thank you
This is more simply produced as three columns:
campaignid1
campaignid2
num users
For this you can use a self-join and aggregation:
select d1.campaignid, d2.campaignid, count(*)
from dataset d1 join
dataset d2
on d1.userid = d2.userid
group by d1.campaignid, d2.campaignid;
You can pivot these results, but that requires knowing the campaigns:
select d1.campaignid,
countif(d2.campaignid = 1) as campaign_1,
countif(d2.campaignid = 2) as campaign_2,
countif(d2.campaignid = 3) as campaign_3,
countif(d2.campaignid = 4) as campaign_4,
countif(d2.campaignid = 5) as campaign_5
from dataset d1 join
dataset d2
on d1.userid = d2.userid
group by d1.campaignid;
Related
I would like to get the oldest only one from every type product and sum of the prices listed in listofproduct table. Another thing is to search only between prodacts that has at least one peace on lager.
With the SQL I managed to get all the products has at least one on the stock. But the rest I am stack...
So the sum cold be done later, that was my plan, but if you have better idea feel free to write
Here is my data:
+-------------+----------------+---------------+----------+
| IDProizvoda | NazivProizvoda | DatumKupovine | NaLageru |
+-------------+----------------+---------------+----------+
| 77 | Cokolada | 25-Feb-20 | 2 |
| 44 | fgyhufrthr | 06-Aug-20 | 5 |
| 55 | Auto | 06-Aug-23 | 0 |
| 55 | Auto | 11-Aug-20 | 200 |
| 77 | Cokolada | 06-Aug-27 | 0 |
| 77 | Cokolada | 25-Feb-20 | 10 |
| 77 | Cokolada | 25-Jan-20 | 555 |
| 77 | Cokolada | 25-Mar-20 | 40 |
+-------------+----------------+---------------+----------+
Access.ExeQuery("SELECT * FROM Products " &
"WHERE IDProizvoda IN (SELECT value FROM STRING_SPLIT(#listofproduct, ',')) " &
"AND NaLageru > 0 ")
I tried to add GROUP BY and HAVING but it does not worked because i choose the whole table. But I need Product ID and Stock field for edit it later, to subtract one from the stock for those products.
I would like to get the result:
+-------------+----------------+---------------+----------+
| IDProizvoda | NazivProizvoda | DatumKupovine | NaLageru |
+-------------+----------------+---------------+----------+
| 44 | fgyhufrthr | 06-Aug-20 | 5 |
| 55 | Auto | 11-Aug-20 | 200 |
| 77 | Cokolada | 25-Jan-20 | 555 |
+-------------+----------------+---------------+----------+
Thank you for all the help.
You can do it with a Cross Apply, this would be your SQL query:
Select P.IDProizvoda,
P.NazivProizvoda,
N.DatumKupovine,
N.NaLageru,
N.IDKupovine,
N.CenaPoKomadu
From
products P
Cross Apply
(
Select top 1 DatumKupovine,
NaLageru,
IDKupovine,
CenaPoKomadu
From products P2
where P2.IDProizvoda = P.IDProizvoda
and P2.NaLageru > 0
order by DatumKupovine
) N
group by P.IDProizvoda, P.NazivProizvoda, N.DatumKupovine, N.NaLageru, N.IDKupovine, N.CenaPoKomadu
And this your ExeQuery:
Access.ExeQuery("Select P.IDProizvoda, P.NazivProizvoda, N.DatumKupovine, N.NaLageru, N.IDKupovine, N.CenaPoKomadu From products P " &
" Cross Apply( Select top 1 DatumKupovine, NaLageru, IDKupovine, CenaPoKomadu From products P2 where P2.IDProizvoda = P.IDProizvoda and P2.NaLageru > 0 order by DatumKupovine) N " &
" where P.IDProizvoda in (Select value From STRING_SPLIT(#listofproduct, ',')) " &
" group by P.IDProizvoda, P.NazivProizvoda, N.DatumKupovine, N.NaLageru, N.IDKupovine, N.CenaPoKomadu " )
I think this is just aggregation with a filter:
SELECT IDProizvoda, NazivProizvoda, MAX(DatumKupovine),
SUM(NaLegaru)
FROM Products p
WHERE NaLegaru > 0
GROUP BY IDProizvoda, NazivProizvoda;
This should do it:
with cte as (
SELECT *, row_number() over (
partition by NazivProizvoda
order by DatumKupovine
) as rn
FROM Products
WHERE IDProizvoda IN (
SELECT value
FROM STRING_SPLIT(#listofproduct, ',')
)
AND NaLageru > 0
)
select *
from cte
where rn = 1;
By way of explanation, I'm using a common table expression to select the superset of the data you want by criteria and adding a column that enumerates each row within a group (a group being defined here as having NazivProizvoda be the same) in order of the DatumKupovine). With that done, anything that admits the value of 1 for that enumeration will be the oldest in the group. If you data is such that more than one row can be the oldest, use rank() instead of row_number().
I am trying to create a query to show the top 24 most-viewed pages by joining 3 tables.
But, I am having trouble getting it to work. Either it has an issue with the use of UNION, JOIN or a part of the written function/script, in general.
The tables are:
+---------------+
| dbo_Good_URLs |
+---------------+
| Url |
| HTTPAlias |
| PortalID |
| page_title |
+---------------+
+-----------------+
| dbo_vw_GoodURLs |
+-----------------+
| URL |
| PortalID |
| HTTPAlias |
| Title |
+-----------------+
+-----------------------+
| dbo_analytics_history |
+-----------------------+
| URL |
| PortalId |
| HTTPAlias |
| Page_Title |
| Report_Month |
| Report_Year |
| Pageviews |
| Unique_Pageviews |
| Entrances |
| Total_Time_on_Page |
| Bounces |
| Exits |
| Avg_Time_on_Page |
| Bounce_Rate |
| Exit_Rate |
+-----------------------+
I've tried to use an IIF(Is Null(**) And I've looked through to script itself to see why UNION and JOIN seem to not work and I can't seem to figure it out.
I've been playing around with this all week and it's just not coming to me.
SELECT TOP 24 dbo_Good_URLs.Url, Nz(dbo_analytics_history.Pageviews, 0) AS Total_Pageviews,
Nz(dbo_analytics_history.Pageviews, 0) AS Month1
FROM (SELECT Url FROM dbo_Good_URLs WHERE HTTPAlias IN ('x.org', 'ab.x.org'))
UNION
SELECT Url FROM dbo_vw_GoodURLs WHERE dbo_Good_URLs.HTTPAlias IN ('x.org', 'ab.x.org')
LEFT OUTER JOIN dbo_analytics_history
ON dbo_Good_URLs.Url = dbo_analytics_history.URL AND dbo_analytics_history.HTTPAlias IN ('x.org', 'ab.x.org') AND dbo_analytics_history.Report_Month = 10
GROUP BY dbo_Good_URLs.Url, dbo_analytics_history.Pageviews
ORDER BY Nz(dbo_analytics_history.Pageviews, 0) DESC;
The result that I am looking for is for it to show the top 24 pages viewed for the month of October(I.e. month 10)
I would hazard a guess that you're actually looking for something like the following:
select top 24 q.url, nz(a.pageviews, 0) as Total_Pageviews, nz(a.pageviews, 0) as Month1
from
(
select dbo_good_urls.url from dbo_good_urls
where dbo_good_urls.httpalias in ('x.org', 'ab.x.org')
union
select dbo_vw_goodurls.url from dbo_vw_goodurls
where dbo_vw_goodurls.httpalias in ('semcog.org', 'loggedin.semcog.org')
) q
left join dbo_analytics_history a on q.url = a.url
)
where
a.report_month is null or a.report_month = 10
order by
nz(a.pageviews, 0) desc;
Here, the target URLs are selected by the two unioned subqueries, with the result of such union left joined to your dbo_analytics_history table on the url field.
Using Postgres 10 I have tables representing 'units', the 'group' to which each unit belongs, and the 'distance' between each pair of units.
I now want a group-to-group distance table that aggregates all the unit-to-unit distances for each pair of groups - i.e. an aggregate array of the distances from all the units in one group to all the units in the other group.
What I have
'units' 'unit_distances'
id | group this_unit_id | that_unit_id | distance
---------- --------------------------------------
1 | 1 1 | 2 | d_12
2 | 1 1 | 3 | d_13
3 | 2 1 | 4 | d_14
4 | 3 2 | 3 | d_23
... | ... ... | ... | ...
What I want
'group_distances'
this_group_id | that_group_id | all_distances
---------------------------------------------------
1 | 2 | {d_13, d_23}
1 | 3 | {d_14, d_24}
2 | 3 | {d_34}
... | ... | {..., ...
I'm not sure how to return all such arrays for all group-group pairings and generate the table depicted above. At the moment I can only get these arrays by defining the sites individually (as x and y below).
with dist as (
select distance
from unit_distances
inner join units
on unit_distances.this_unit_id = units.id
WHERE units.group = x
intersect
select distance
from unit_distances
inner join units
on unit_distances.that_unit_id = units.id
WHERE units.group = y)
select array_agg(distance) from dist;
Thanks
If I understand correctly, this is just two joins to get the groups and an aggregation for the distances:
select u1.group, u2.group, array_agg(ud.distance) as all_distances
from unit_distances ud join
units u1
on ud.this_unit_id = u1.id join
units u2
on ud.that_unit_id = u2.id
group by u1.group, u2.group;
I have three tables :
BookingNode , Booking AirTrip
AirTrip :
+----+------------+
| ID | Name |
+----+------------+
| 0 | One way |
| 1 | Round trip |
| 2 | Circle |
| 3 | Other |
+----+------------+
When ever we make a booking we store the data as :
BookingNode table
+--------+-------------------+------------+----------------------+
| ID | CustomerGivenName | IPAddress | Email |
+--------+-------------------+------------+----------------------+
| 177022 | xfghfh | 2130706473 | mikehussey#gmail.com |
| 177021 | cfggjfj | 2130706473 | mikehussey#gmail.com |
+--------+-------------------+------------+----------------------+
Booking Table :
+--------+---------------+-----------+------------+------------+
| ID | BookingNodeID | AirTripID | AirLineId | Provider |
+--------+---------------+-----------+------------+------------+
| 181251 | 177020 | 1 | 978 | Jet |
| 181252 | 177021 | 0 | 982 | Go |
| 181253 | 177021 | 0 | 978 | Jet |
+--------+---------------+-----------+------------+------------+
If round trip flight is booked and ProviderID is same then a single entry is done in Booking Table with AirTripID value as 1.(Booking ID : 181251 and Provider Jet )
But if providers are different for both the legs then two entries are done in Booking Table with AirTripID for both entries are one(Booking ID : 181252 and 181253 Provider Go,Jet ).In this case BookingNodeID value being same.
Prob : I have to write a query to get different type of Bookings.(Oneway, RoundTrip,Circle).But when I apply join on AirTripID , it is giving me incorrect results.
How can I write my query to give correct results knowing that BookingNodeID is going to be the same for roundtrip (both entries in Booking Table)
Sample Output
+-------------+---------------+-------------------+------------+
| AirTripName | BookingNodeID | CustomerGivenName | IPAddress |
+-------------+---------------+-------------------+------------+
| TwoWay | 177020 | xfghfh | 2130706473 |
| TwoWay | 177021 | cfggjfj | 2130706473 |
+-------------+---------------+-------------------+------------+
Basically, this code might have an error due to my laziness syntom of data entry. But, the logic of the query is, if b.AirTripID is 0, add extra condition which group by Booking. if result return more than 1 row, is actually 2 way. so AirTripType will become 1, otherwise, remain the same as b.AirTripID. You may copy below on and try fix if theres any error. i believe the logic should work based on your expected result.
select
bd.ID,
bd.CustomerGivenName,
case b.AirTripID
when 1 then 1
when 2 then 2
when 3 then 3
when 0 then
case select BookingNodeID
from Booking
where Booking.BookingNodeID = bd.ID group by BookingNodeID having Count(BookingNodeID)
when 1 then 1
else 0 end as AirTripType,
bd.IPAddress
from BookingNode bd
inner join (select BookingNodeID ,AirTripID from Booking group by BookingNodeID ,AirTripID) as b on b.BookingNodeID = bd.ID
where id=177021
Try This
WITH CTE
AS
(
SELECT
SeqNo = ROW_NUMBER() OVER(PARTITION BY BN.ID ORDER BY B.ID),
B.BookingNodeID,
BN.CustomerGivenName,
BN.IPAddress,
AirTripId = A.ID,
AirTripNm = A.Name
FROM Booking B
INNER JOIN AirTrip A
ON A.ID = B.AirTripID
LEFT JOIN BookingNode BN
ON B.BookingNodeID = BN.id
)
SELECT
C1.SeqNo,
AirTripName = CASE WHEN C2.SeqNo IS NOT NULL
THEN 'Round trip'
ELSE C1.AirTripNm END,
C1.BookingNodeID,
C1.CustomerGivenName,
C1.IPAddress
FROM CTE C1
LEFT JOIN CTE C2
ON C1.BookingNodeID = C2.BookingNodeID
AND C2.SeqNo = 2
WHERE c1.SeqNo = 1
SQL Fiddle Link Here
Select distinct bk.bookingnodeid,cst.customername,ipaddress,
case when count(airtripid)over(partition by bookingnodeid order by bookingnodeid)=2 then 'RoundTrip' else name end As AirTripName
from booking bk
inner join airlinetrip at
on bk.airtripid=at.id
inner join customer cst
on cst.id=bk.bookingnodeid
I'm trying to make a query that pair a worker that work on the same place. The relational model I'm asking looks like this:
Employee(EmNum, name)
Work(FiNum*, EmNum*)
Field(FiNum, Title)
(bold indicates primary key)
right now my code looks like
SELECT work.finum, e1.name,e1.emnum,e2.name,e2.emnum
FROM employee e1
INNER JOIN employee e2
on e1.EmNum = e2.EmNum
INNER JOIN work
on e1.emnum = work.emnum
This gives me result like
| finum | name | emnum | name_1 | emnum_1 |
| 1 | a | 1 | a | 1 |
| 1 | b | 2 | b | 2 |
| 2 | c | 3 | c | 3 |
| 3 | d | 4 | d | 4 |
| 3 | e | 5 | e | 5 |
while I want the result to be like
| finum | name | emnum | name_1 | emnum_1 |
| 1 | a | 1 | b | 2 |
| 1 | b | 2 | a | 1 |
| 3 | d | 4 | e | 4 |
| 3 | e | 5 | d | 5 |
I'm quite new at sql so I can't really think of a way to do this. Any help or input would be helpful.
Thanks
Your question is slightly unclear, but my guess is that you're trying to find employees that worked on the same place = same finum in work, but different row. That you can do this way:
SELECT w1.finum, e1.name,e1.emnum, e2.name,e2.emnum
from work w1
join work w2 on w1.finum = w2.finum and w1.emnum != w2.emnum
join employee e1 on e1.emnum = w1.emnum
join employee e2 on e2.emnum = w2.emnum
If you don't want to repeat the records (1 <-> 2 + 2 <-> 1 change the != in the join to > or <)
I'm trying to make a query that pair a worker that work on the same place.
Presumably the "places" are represented by the Field table. If you want to pair up employees on that basis then you should be performing a join conditioned on field numbers being the same, as opposed to one conditioned on employee numbers being the same.
It looks like your main join wants to be a self-join of Work to Work of records with matching FiNum. To get the employee names in the result then you will need also to join Employee twice. To avoid employees being paired with themselves, you will want to filter those cases out via a WHERE clause.