How to use count with Distinct ON - sql

I have this query that already works, i need to write count query for this (need pagination), and i have issues using count with DISTINCT ON, anyone knows correct syntax and way to use it, i already googled but was not able to find any count queries with DISTINCT ON
As result i'm expecting total number of rows from this query that already works
select DISTINCT on (csd.team_contest_id)
c.id as contestId
from contest as c
left join company_sponsor_team as csd on csd.contest_id = c.id
left join sponsor as s on s.id = c.sponsor_id
left join team as d on d.id = c.team_id
left join player as m on c.creator_id = m.id
WHERE c.id = c.id
AND ((c.team_id is not null and c.sponsor_id is null and lower(d.name) LIKE LOWER(CONCAT('%TAN%')))
OR (c.team_id is not null and c.sponsor_id is not null and lower(s.name) LIKE LOWER(CONCAT('%TAN%')))
OR (c.team_id is null and lower(s.name) LIKE LOWER(CONCAT('%TAN%')))) AND (CURRENT_DATE < c.archive_date)

If you want to count the number of rows, use a subquery:
select count(*)
from ( <your query here> ) x;
If you have an aversion to subqueries, you can always do:
select count(distinct csd.team_contest_id)
from . . . <the rest of your query here>;
This returns the same value assuming that csd.team_contest_id is not NULL.

Related

Remove duplicates from result in sql

i have following sql in java project:
select distinct * from drivers inner join licenses on drivers.user_id=licenses.issuer_id
inner join users on drivers.user_id=users.id
where (licenses.state='ISSUED' or drivers.status='WAITING')
and users.is_deleted=false
And result i database looks like this:
And i would like to get only one result instead of two duplicated results.
How can i do that?
Solution 1 - That's Because one of data has duplicate value write distinct keyword with only column you want like this
Select distinct id, distinct creation_date, distinct modification_date from
YourTable
Solution 2 - apply distinct only on ID and once you get id you can get all data using in query
select * from yourtable where id in (select distinct id from drivers inner join
licenses
on drivers.user_id=licenses.issuer_id
inner join users on drivers.user_id=users.id
where (licenses.state='ISSUED' or drivers.status='WAITING')
and users.is_deleted=false )
Enum fields name on select, using COALESCE for fields which value is null.
usually you dont query distinct with * (all columns), because it means if one column has the same value but the rest isn't, it will be treated as a different rows. so you have to distinct only the column you want to, then get the data
I suspect that you want left joins like this:
select *
from users u left join
drivers d
on d.user_id = u.id and d.status = 'WAITING' left join
licenses l
on d.user_id = l.issuer_id and l.state = 'ISSUED'
where u.is_deleted = false and
(d.user_id is not null or l.issuer_id is not null);

SQL Select rows with value that appears x times

SELECT Opponent, JerseyNumber, A
FROM (SELECT * FROM Games_t INNER JOIN GameStats_t ON Games_t.GameID=GameStats_t.GameID)
WHERE A >=1 AND COUNT(Opponent) >3;
I'm trying to return games where there were at least three players who recorded one assist or more. If I don't have AND COUNT(Opponent) >3, the query returns almost what I want, but there are a few games where only three players recorded an assist.
Try this :
SELECT Opponent,
JerseyNumber,
A,
COUNT(Opponent) FROM
(
SELECT *
FROM Games_t INNER JOIN GameStats_t
ON Games_t.GameID=GameStats_t.GameID
)
WHERE A >=1
GROUP BY Opponent, JerseyNumber, A
HAVING COUNT(Opponent) >3
Use the following Query.
SELECT G_TEMP.GAME_ID, GT.OPPONENT, GT.JERSEYNUMBER, G.A FROM
(
SELECT GAME_ID, COUNT(OPPONENT) OPP_COUNT FROM GAMESTATS_T
HAVING COUNT(OPPONENT) > 3
GROUP BY GAME_ID
) G_TEMP
LEFT OUTER JOIN
GAMES_T G
ON
G.GAME_ID = G_TEMP.GAME_ID
AND G.A > 1
INNER JOIN
GAMESTATS_T GT
ON
G.GAME_ID = GT.GAME_ID
Working SQL Fiddle HERE
Note 1: When there are more than one table, it is always better to specify fields using tablename_alias.field_name syntax. This is a good practice, however it is optional.
For example, if Table TABLEA has fields FIELDA1, FIELDA2, FIELDA3 and if Table TABLEB has fields FIELDB1, FIELDB2
Then you can use query as:
SELECT A.FIELDA1, A.FIELDA3, B.FIELDB2
FROM TABLEA A JOIN TABLEB B ON A.FIELDA2 = B.FIELDB2
Use HAVING part in query to use some parameters after query completion:
SELECT Opponent, JerseyNumber, A
FROM (SELECT * FROM Games_t INNER JOIN GameStats_t ON Games_t.GameID = GameStats_t.GameID)
WHERE A >=1 HAVING COUNT(Opponent) > 3;

Left outer join and group by issue

I wrote a query. this query sum fields from 2 different table. And grouped by main table id field. But second left outer join is not grouped and giving me different results.
SELECT s.*,
f.firma_adi,
sum(sd.fiyat) AS konak,
sum(ss.fiyat) AS sponsor
FROM fuar_sozlesme1 s
INNER JOIN fuar_firma_2012 f
ON ( s.cari = f.cari )
LEFT OUTER JOIN fuar_sozlesme1_detay sd
ON ( sd.sozlesme_id = s.id )
LEFT OUTER JOIN fuar_sozlesme1_sponsor ss
ON ( ss.sozlesme_id = s.id )
GROUP BY s.id
ORDER BY s.id DESC
I know, it is really complicated but I'm stucking on this issue.
My question is: why second left outer join is not correctly sum of field . If I remove second left outer join or first, everything is normal.
The problem is that you have multiple dimensions on your data, and the number of rows is multiplying beyond what you expect. I would suggest that you run the query for one id, without the group by, to see what rows the join is producing.
One way to fix this is by using correlated subqueries:
select s.*, f.firma_adi,
(select SUM(sd.fiyat)
from fuar_sozlesme1_detay fd
where sd.sozlesme_id = s.id
) as konak,
(select SUM(ss.fiyat)
from fuar_sozlesme1_sponsor ss
where (ss.sozlesme_id = s.id)
) as sponsor
from fuar_sozlesme1 s inner join
fuar_firma_2012 f
on (s.cari = f.cari)
order by s.id DESC
By the way, you appear to by using MySQL (because your query is not parsable in any other dialect). You should tag your questions with the version of the database you are using.

i want to modify this SQL statement to return only distinct rows of a column

select
picks.`fbid`,
picks.`time`,
categories.`name` as cname,
options.`name` as oname,
users.`name`
from
picks
left join categories
on (categories.`id` = picks.`cid`)
left join options
on (options.`id` = picks.oid)
left join users
on (users.fbid = picks.`fbid`)
order by
time desc
that query returns a result that like:
my question is.... I would like to modify the query to select only DISTINCT fbid's. (perhaps the first row only sorted by time)
can someone help with this?
select
p2.fbid,
p2.time,
c.`name` as cname,
o.`name` as oname,
u.`name`
from
( select p1.fbid,
min( p1.time ) FirstTimePerID
from picks p1
group by p1.fbid ) as FirstPerID
JOIN Picks p2
on FirstPerID.fbid = p2.fbid
AND FirstPerID.FirstTimePerID = p2.time
LEFT JOIN Categories c
on p2.cid = c.id
LEFT JOIN Options o
on p2.oid = o.id
LEFT JOIN Users u
on p2.fbid = u.fbid
order by
time desc
I don't know why you originally had LEFT JOINs, as it appears that all picks must be associated with a valid category, option and user... I would then remove the left, and change them to INNER joins instead.
The first inner query grabs for each fbid, the FIRST entry time which will result in a single entity for the FBID. From that, it re-joins to the picks table for the same ID and timeslot... then continues for the rest of the category, options, users join criteria of that single entry.
2 options, you could write a group by clause.
Or you could write a nested query joined back to itself to get pertinent info.
Nested aliased table:
SELECT
n.fBids
FROM
MyTable t
INNER JOIN
(SELECT DISTINCT fBids
FROM MyTable) n
ON n.ID = t.ID
Or group by option
SELECT fBId from MyTable
GROUP BY fBID
select picks.`fbid`, picks.`time`, categories.`name` as cname,
options.`name` as oname, users.`name` from picks left join categories
on (categories.`id` = picks.`cid`) left join options on (options.`id` = picks.oid)
left join users on (users.fbid = picks.`fbid`)
order by time desc GROUP BY picks.`fbid`
select
picks.fbid,
MIN(picks.time) as first_time,
MAX(picks.time) as last_time
from
picks
group by
picks.fbid
order by
MIN(picks.time) desc
However, if you want only distinct fbid's you cannot display cname and other columns at the same time.

Multiple COUNT in 1 SQLITE Query

Using SQLite.
SELECT c.*,
COUNT(m.course_id) AS "meeting_count",
COUNT(r.meeting_id) AS "race_count"
FROM course c
LEFT JOIN meeting m ON m.course_id = c.id
LEFT JOIN race r ON r.meeting_id = m.id
GROUP BY c.id
Course has meetings has races.
Trying to select the correct count for course meetings and course races. The problem is the above query is returning the same count for "meeting_count" as "race_count". What am I doing wrong?
try adding DISTINCT like COUNT(DISTINCT m.course_id)