I want to count the number of etape an Employee work in a project
My table temps are:
Temps:
noProjet
noEtape
noEmploye
annee
mois
jrsHm
My query is
select
t.noEmploye, t.NoProjet, c.count
from
temps t
inner join
(select
noProjet, noEtape, count(*) as count
from
temps
group by
noProjet) c on t.noProjet = c.noProjet
order by
noEmploye
Error I get is
Msg 8120, Level 16, State 1, Line 1
Column 'temps.noEtape' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
The error is self explanatory. Remove noEtape column from subquery. If column is not in the group list you can not select it unless you apply some aggregations to that column:
select t.noEmploye, t.NoProjet, c.count
from temps t
inner join (select noProjet, count(*) as count
from temps
group by noProjet ) c on t.noProjet = c.noProjet
order by noEmploye
Or:
select t.noEmploye, t.NoProjet, c.count
from temps t
inner join (select noProjet, max(noEtape) as noEtape, count(*) as count
from temps
group by noProjet ) c on t.noProjet = c.noProjet
order by noEmploye
Is this what you want?
select distinct
noEmploye,
noProjet,
sum(noEtape) over (
partition by noProjet
) as EtapesdeProjet
from Temps
order by noEmploye
Maybe you can do this by using next query:
select
t.noEmploye,
t.NoProjet,
c.count
from temps t
inner join (select noProjet, noEtape, count(*) as count from temps group by noProjet, noEtape) as c
on t.noProjet = c.noProjet
order by noEmploye
Related
SELECT DISTINCT(t1.Ticker),t2.SecurityID,t2.ClosePrice,t2.QuoteDateTime FROM [Hub].[SecurityMaster].[SecurityMasterDetails] as t1
INNER JOIN [Hub].[SecurityMaster].[SecurityPrices] as t2
ON t2.SecurityID =t1.SecurityID
WHERE t2.QuoteDateTime IN (SELECT max(QuoteDateTime) FROM [Hub].[SecurityMaster].[SecurityPrices]) AND t1.SecurityTypeName = 'REIT'
I get an output with no data. The subquery doesn't run along with the other filter in the WHERE clause. I am not sure what I am doing wrong. Can somebody please help!
If you are trying to get the lastest row from SecurityPrices for each Ticker, one option is to use cross apply():
select --distinct /* distinct not needed if `Ticker` is unique on `smd`
smd.Ticker
, sp.SecurityID
, sp.ClosePrice
, sp.QuoteDateTime
from [Hub].[SecurityMaster].[SecurityMasterDetails] as smd
cross apply (
select top 1
i.SecurityID
, i.ClosePrice
, i.QuoteDateTime
from [Hub].[SecurityMaster].[SecurityPrices] i
where i.SecurityID = smd.SecurityID
order by i.QuoteDateTime desc
) as sp
where SecurityTypeName = 'REIT' /* which table does this column belong to? */
I think your query would be
SELECT DISTINCT TOP 1 WITH TIES
t1.Ticker,
t2.SecurityID,
t2.ClosePrice,
t2.QuoteDateTime
FROM [Hub].[SecurityMaster].[SecurityMasterDetails] as t1
INNER JOIN [Hub].[SecurityMaster].[SecurityPrices] as t2 ON t2.SecurityID =t1.SecurityID
WHERE SecurityTypeName = 'REIT'
ORDER BY t2.QuoteDateTime DESC
You aren't getting results because the max(QuoteDateTime) record doesn't have SecurityTypeName = 'REIT'. I think you want the max(QuoteDateTime) for this SecurityTypeName, so this can be done with an INNER JOIN.
SELECT DISTINCT
(t1.Ticker),
t2.SecurityID,
t2.ClosePrice,
t2.QuoteDateTime
FROM [Hub].[SecurityMaster].[SecurityMasterDetails] as t1
INNER JOIN [Hub].[SecurityMaster].[SecurityPrices] as t2
ON t2.SecurityID =t1.SecurityID
INNER JOIN
(SELECT max(QuoteDateTime) DT FROM [Hub].[SecurityMaster].[SecurityPrices]) P on P.DT = t2.QuoteDateTime
WHERE SecurityTypeName = 'REIT'
EDIT
Your data doesn't have what you think it does, I suspect. Here is how you can check...
--Find the SecurityID that matches the max date
SELECT
SecurityID ,
max(QuoteDateTime) DT
FROM [Hub].[SecurityMaster].[SecurityPrices]
GROUP BY SecurityID
--I'm betting this ID isn't in your SecurityMasterDetails where the Type is REIT
SELECT DISTINCT
SecurityID
FROM SecurityMasterDetails
WHERE SecurityTypeName = 'REIT'
Since the SecurityID returned in the first query isn't in the second query result set, you are going to get NULL results.
Julia asked her students to create some coding challenges. Write a query to print the hacker_id, name, and the total number of challenges created by each student. Sort your results by the total number of challenges in descending order. If more than one student created the same number of challenges, then sort the result by hacker_id. If more than one student created the same number of challenges and the count is less than the maximum number of challenges created, then exclude those students from the result.
Input Format
The following tables contain challenge data:
Hackers: The hacker_id is the id of the hacker, and name is the name of the hacker.
Hackers Table
Challenges: The challenge_id is the id of the challenge, and hacker_id is the id of the student who created the challenge.
Challenges Table
here is the query that i wrote
select H.hacker_id,H.name,T.challenges_created
from Hackers H join
(SELECT hacker_id ,
COUNT(Challeneges.challenge_id) as challenges_created
FROM Challenges
GROUP BY hacker_id
HAVING challenges_created >= max(challenges_created)
) T
on H.hacker_id=T.hacker_id
ORDER BY T.challenges_created desc, H.hacker_id asc
but i'm getting error saying that
Msg 207, Level 16, State 1, Server WIN-ILO9GLLB9J0, Line 12 Invalid
column name 'challenges_created'. Msg 207, Level 16, State 1, Server
WIN-ILO9GLLB9J0, Line 12 Invalid column name 'challenges_created'.
Msg 4104, Level 16, State 1, Server WIN-ILO9GLLB9J0, Line 9 The
multi-part identifier "Challeneges.challenge_id" could not be bound.
Line 9 The multi-part identifier "Challeneges.challenge_id" could not be bound.
Looks like you spelt Challenges wrong.
select C.Hacker_id, H.Name, count(challenge_id)
from Hackers H Inner Join Challenges C
ON H.Hacker_Id = C.Hacker_Id
group by C.Hacker_Id, H.Name
having count(challenge_id) not in (select x.ChallengeCount from (
select C.Hacker_id, H.Name, count(challenge_id) as ChallengeCount
from Hackers H Inner Join Challenges C
ON H.Hacker_Id = C.Hacker_Id
group by C.Hacker_Id, H.Name
) x
where x.ChallengeCount <> (select top 1 count(challenge_id) from Challenges group by hacker_Id order by 1 desc)
group by x.ChallengeCount
having count(x.challengecount) > 1)
order by 3 desc, 1
WITH TEMP AS
(
SELECT H.HACKER_ID AS HID,
H.NAME AS HNAME,
COUNT(C.CHALLENGE_ID) AS CNT
FROM HACKERS
JOIN CHALLENGES C
ON H.HACKER_ID=C.HACKER_ID
GROUP BY H.HACKER_ID,H.NAME
)
SELECT * FROM TEMP
WHERE CNT IN
( SELECT CNT FROM TEMP count challenges
GROUP BY CNT
HAVING COUNT(CNT)=1
) OR CNT=(SELECT MAX(CNT) FROM TEMP)
ORDER BY CNT DESC,HID
SELECT c.hacker_id, h.name, COUNT(c.challenge_id) AS cnt
FROM Hackers h, Challenges c
where h.hacker_id = c.hacker_id
GROUP BY c.hacker_id, h.name
HAVING
count(c.challenge_id) = (SELECT max(COUNT(c1.challenge_id)) FROM Challenges c1
GROUP BY c1.hacker_id)
OR
count(c.challenge_id) NOT IN (SELECT COUNT(c2.challenge_id) FROM Challenges c2
GROUP BY c2.hacker_id
HAVING c2.hacker_id <> c.hacker_id)
ORDER BY cnt DESC, c.hacker_id;
This not so complex logic might be easier to understand;
WITH now AS (SELECT hacker_id AS hi, COUNT(*) AS nmbr,
COUNT(COUNT(*)) OVER(PARTITION BY COUNT(*)) AS ccnt
FROM challenges
GROUP BY hacker_id)
SELECT n.hi, h.name, n.nmbr
FROM now AS n, hackers AS h
WHERE (n.nmbr = (SELECT MAX(nmbr) FROM now) OR n.ccnt = 1)
AND n.hi = h.hacker_id
ORDER BY n.nmbr DESC, n.hi
;
select ch.hacker_id,h.name,count(ch.challenge_id) as challenges_created
from hackers h
join
challenges ch
on
h.hacker_id=ch.hacker_id
group by ch.hacker_id,h.name
having count(ch.challenge_id)in (select max(a.cnt) from (select count(challenge_id) as cnt from challenges group by hacker_id)a)
union
select ch.hacker_id,h.name,count(ch.challenge_id) as challenges_created
from hackers h
join
challenges ch
on
h.hacker_id=ch.hacker_id
group by ch.hacker_id,h.name
having count(ch.challenge_id)IN(select c.chlng from (select b.chlng, count(*) as cnt from (select hacker_id,count(challenge_id) as chlng from challenges group by hacker_id)b group by b.chlng) c where c.cnt=1)
order by challenges_created desc, ch.hacker_id
with cte as(
select a.hacker_id,a.name,count(b.challenge_id) as challange,COUNT(COUNT(b.challenge_id)) OVER(PARTITION BY COUNT(b.challenge_id)) as rank_
from Hackers as a inner join Challenges as b
on a.hacker_id = b.hacker_id
group by a.hacker_id,a.name
) select hacker_id,name,challange from cte
where rank_>1 and challange=(select max(challange) from cte) or rank_ =1
order by challange desc,hacker_id
This is my answer to the question
with cte as
(
select h.hacker_id, h.name, count(c.challenge_id) counts
from hackers h inner join challenges c on c.hacker_id = h.hacker_id
group by h.hacker_id, h.name
)
select
a.hacker_id, a.name, a.counts
from
cte a
inner join (select count(1) rankie, counts from cte b group by counts) b on a.counts= b.counts
cross join ( select max(counts) maxCount from cte) c
where 1=1
and (a.counts < c.maxCount
and rankie <=1)
or a.counts = c.maxCount
order by a.counts desc, a.hacker_id desc
Normally you can't refer to field aliases in the HAVING clause
Instead use
COUNT(Challeneges.challenge_id)
You can also try this
SELECT h.hacker_id,
h.name,
COUNT(c.challenge_id) AS challenge_count
FROM Hackers h
JOIN Challenges c ON c.hacker_id = h.hacker_id
GROUP BY h.hacker_id, h.name
HAVING challenge_count =
(SELECT COUNT(challenge_id) AS count_max
FROM Challenges
GROUP BY hacker_id
ORDER BY count_max DESC limit 1)
OR challenge_count IN
(SELECT DISTINCT c_compare AS c_unique
FROM (SELECT h2.hacker_id,
h2.name,
COUNT(challenge_id) AS c_compare
FROM Hackers h2
JOIN Challenges c ON c.hacker_id = h2.hacker_id
GROUP BY h2.hacker_id, h2.name) counts
GROUP BY c_compare
HAVING COUNT(c_compare) = 1)
ORDER BY challenge_count DESC, h.hacker_id;
In my code I haven't use aliases thus it is not showing any errors.
I'm trying to convert this mysql query to run on SQL but having some issues with the syntax on join. Basically what I want to do is set the DWH_HISTO to 1 on duplicate rows based on the DWH_DATE. So the older duplicates should be marked.
This is what I've tried
UPDATE MAG_L_D3.dbo.INSCRIPT
INNER JOIN
(SELECT MAX(DWH_DATE) as lastId, CODINS
FROM INSCRIPT
WHERE DWH_HISTO=0
GROUP BY CODINS
HAVING COUNT(*) > 1) duplic on duplic.CODINS = MAG_L_D3.dbo.INSCRIPT.CODINS
SET DWH_HISTO = 1
WHERE MAG_L_D3.dbo.INSCRIPT.DWH_DATE < duplic.lastId
I believe this is the syntax you are looking for:
;WITH CTE as
(
SELECT *, row_number() over (partition by CODINS order by DWH_DATE desc)rn
)
UPDATE CTE
SET DWH_HISTO = 1
WHERE
rn > 1
and DWH_HISTO=0
Update using inner join:
UPDATE I
SET DWH_HISTO = 1 FROM MAG_L_D3.dbo.INSCRIPT I
INNER JOIN
(SELECT MAX(DWH_DATE) as lastId, CODINS
FROM INSCRIPT
WHERE DWH_HISTO=0
GROUP BY CODINS
HAVING COUNT(*) > 1) duplic on duplic.CODINS = I.CODINS
WHERE I.DWH_DATE < duplic.lastId
I am having problems grouping by the month of a date when using a function. It was working before but the query was less complicated as I am now using a function that uses a rolling year from the current month. Here is my code.
SELECT
CASE
WHEN DATEDIFF(mm,dbo.fn_firstofmonth(getdate()), dbo.fn_firstofmonth(D.expected_date)) < 12
THEN DATEDIFF(mm,dbo.fn_firstofmonth(getdate()), dbo.fn_firstofmonth(D.expected_date)) + 1
ELSE 13 END AS [Expected Month],
P.probability AS [Category], COUNT(O.id) AS [Customers]
FROM opportunity_probability P
INNER JOIN opportunity_detail D ON D.probability_id = P.id
INNER JOIN opportunities O ON D.opportunity_id = O.id
INNER JOIN
(
SELECT opportunity_id
FROM opportunity_detail
GROUP BY opportunity_id
) T ON T.opportunity_id = O.customer_id
GROUP BY P.probability, MONTH(D.expected_date)
ORDER BY P.probability, MONTH(D.expected_date)
It works if I have D.expected_date in the GROUP BY but I need to group on the MONTH of this date as it does not bring through the data correctly.
You could always remove the group by, then put your entire select into another select, and than group by the outer select:
select t.A, t.B from (select A, datepart(month, b) as B) t group by t.A, t.B
This way you can address your month field as if it where a normal field.
Example is far from complete, but should get you on your way.
You can try to find month by this code:
GROUP BY P.probability, DATEPART(month, D.expected_date)
try this
SELECT
to_char(D.expected_date, 'YYYY-MM'),
CASE
WHEN DATEDIFF(mm,dbo.fn_firstofmonth(getdate()), dbo.fn_firstofmonth(D.expected_date)) < 12
THEN DATEDIFF(mm,dbo.fn_firstofmonth(getdate()), dbo.fn_firstofmonth(D.expected_date)) + 1
ELSE 13 END AS [Expected Month],
P.probability AS [Category], COUNT(O.id) AS [Customers]
FROM opportunity_probability P
INNER JOIN opportunity_detail D ON D.probability_id = P.id
INNER JOIN opportunities O ON D.opportunity_id = O.id
INNER JOIN
(
SELECT opportunity_id
FROM opportunity_detail
GROUP BY opportunity_id
) T ON T.opportunity_id = O.customer_id
GROUP BY P.probability, to_char(D.expected_date, 'YYYY-MM')
ORDER BY P.probability, to_char(D.expected_date, 'YYYY-MM')
I am trying to inner join 2 temp tables
I know this can be done, I have done this before but i completely forgot how to do it
Please advise meBelow is the query that I try to execute
select tmp1.*, tmp2.cnt from
(
select
1 as ClassificationType,
tblMatches.IdGame,
tblMatches.IdPlayer,
sum(Score) as Score, sum(Points) as Points, sum(OpponentScore) as OpponentScore,
count(ID) as MatchesCount, count(distinct IdCompetition) as CompetitionsCount
from
tblMatches
group by IdPlayer, IdGame
) as tmp1
inner join (select IdWinner, count(IdWinner) as cnt from tblCompetitions where IdWinner = tmp1.IdPlayer) as tmp2
on tmp2.IdWinner = tmp1.IdPlayer
This will fail with
I think I am not allowed to use tmp1 in the subquery that create tmp2
Msg 4104, Level 16, State 1, Line 17
The multi-part identifier
"tmp1.IdPlayer" could not be bound.
You are not trying to join two temp tables, but two derived tables.
You cannot access the inner data of one derived table in outside of it unless it's in the SELECT clause.
Try the following:
select tmp1.*, tmp2.cnt from
(
select
1 as ClassificationType,
tblMatches.IdGame,
tblMatches.IdPlayer,
sum(Score) as Score, sum(Points) as Points, sum(OpponentScore) as OpponentScore,
count(ID) as MatchesCount, count(distinct IdCompetition) as CompetitionsCount
from
tblMatches
group by IdPlayer, IdGame
) as tmp1
inner join (select IdWinner, count(IdWinner) as cnt from tblCompetitions GROUP BY IdWinner) as tmp2
on tmp2.IdWinner = tmp1.IdPlayer
select
1 as ClassificationType,
tmp1.IdGame,
tmp1.IdPlayer,
sum(tmp1.Score) as Score,
sum(tmp1.Points) as Points,
sum(tmp1.OpponentScore) as OpponentScore,
count(tmp1.ID) as MatchesCount,
count(distinct tmp1.IdCompetition) as CompetitionsCount,
count(tmp2.IdWinner) as cnt
from
tblMatches tmp1
inner join
tblCompetitions tmp2
on tmp2.IdWinner = tmp1.IdPlayer
group by
tmp1.IdPlayer,
tmp1.IdGame
The where clause in tmp2 duplicates the join condition:
inner join (select IdWinner, count(IdWinner) as cnt
from tblCompetitions
where IdWinner = tmp1.IdPlayer) as tmp2
on tmp2.IdWinner = tmp1.IdPlayer
Just remove the where clause. In addition, like Astander noted in his now deleted post, the second query needs a group by too:
inner join (select IdWinner, count(IdWinner) as cnt
from tblCompetitions
group by IdWinner) as tmp2
on tmp2.IdWinner = tmp1.IdPlayer
The reason you can't reference the outer query from a subquery is that this would make the right part of the join depend on the left part of the join.
You shouldn't actually need the second subquery. What about this?
SELECT tmp1.ClassificationType, tmp1.IdGame, tmp1.IdPlayer,
COUNT(tblCompletions.IdWinner) as cnt FROM
(
SELECT
1 as ClassificationType,
tblMatches.IdGame,
tblMatches.IdPlayer,
sum(Score) as Score, sum(Points) as Points, sum(OpponentScore) as OpponentScore,
count(ID) as MatchesCount, count(distinct IdCompetition) as CompetitionsCount
FROM
tblMatches
GROUP BY IdPlayer, IdGame
) as tmp1
INNER JOIN tblCompletions ON tmp1.IdPlayer = tblCompletions.IdWinner
GROUP BY tmp1.ClassificationType, tmp1.IdGame, tmp1.IdPlayer