Exclude results for a given year - sql

I need to exclude Jerry from 2019 (orderyear) and only show sales for him in 2018. What can I add to my code to remove Jerry's 2019 sales. I am using SSMS 2016.
select orderyear, case when code = '2099' then 'Laura'
when code = '3099' then 'John'
when code = '4099' then 'Jerry'
end as 'Members', count(sales)numberofsales
from mytable
group by orderyear, case when code = '2099' then 'Laura'
when code = '3099' then 'John'
when code = '4099' then 'Tony'
end
Results:
orderyear members numberofsales
2018 John 200
2019 John 100
2018 Laura 300
2019 Laura 350
2018 Jerry 400
2019 Jerry 450
Requested:
orderyear members numberofsales
2018 John 200
2019 John 100
2018 Laura 300
2019 Laura 350
2018 Jerry 400

Add:
where not (code = '4099' and orderyear = 2019)

You can simplify to this:
select
orderyear,
case code
when '2099' then 'Laura'
when '3099' then 'John'
when '4099' then 'Jerry'
end as Members,
count(sales) numberofsales
from mytable
where
orderyear <> 2019 or code <> '4099'
group by
orderyear,
code

Related

SQL Count with rollup shows totals as NULL

I need to know how I can replace the NULL with total.
Here is a copy of my query using ROLLUP.
SELECT DATEPART(YEAR, study_date) AS 'Year',
COUNT(distinct study_uid) AS 'Studies'
FROM local_studies
GROUP BY rollup (DATEPART(YEAR, study_date))
ORDER BY 'Year' DESC
This is the output:
Year Studies
2020 497
2019 165743
2018 165043
2017 182712
2016 210700
2015 219373
2014 214097
2013 211566
2012 212900
2011 217957
2010 213542
2009 193510
2008 95434
2007 53722
2006 44422
2005 12119
2004 129
2003 65
2000 4
NULL 2413535
I like to see the 'NULL" value replace with 'Total': (as shown below)
Year Studies
2020 497
2019 165743
2018 165043
2017 182712
2016 210700
2015 219373
2014 214097
2013 211566
2012 212900
2011 217957
2010 213542
2009 193510
2008 95434
2007 53722
2006 44422
2005 12119
2004 129
2003 65
2000 4
Total 2413535
Any advice for converting that NULL to the word TOTAL would be greatly appreciated.
I usually just use coalesce():
SELECT COALESCE(DATENAME(YEAR, study_date), 'Total') AS Year,
COUNT(distinct study_uid) AS 'Studies'
FROM local_studies
GROUP BY rollup (DATENAME(YEAR, study_date))
ORDER BY Year DESC;
Note that this switches to using DATENAME() so the column is a string and not a number.
Also, this doesn't work so well if the value could be NULL. For that, there is the GROUPING() function.
SELECT CASE GROUPING_ID(DATEPART(YEAR, study_date)) WHEN 1 THEN 'Total' ELSE CAST(DATEPART(YEAR, study_date) AS VARCHAR(10)) END AS 'Year',
COUNT(distinct study_uid) AS 'Studies'
FROM local_studies
GROUP BY rollup (DATEPART(YEAR, study_date))
ORDER BY GROUPING_ID(DATEPART(YEAR, study_date)), 'Year' DESC;

How to write a SQL query to select batsman wiht highest score than the previous year

Given this table:
Name Score Year
----------------------
Richie 50 2017
Richie 40 2016
Richie 30 2015
Mark 20 2017
Mark 30 2016
Smith 60 2015
Smith 50 2014
Select batsman, score whose score is greater than the previous score.
For example, here the output should be
Richie 50 2017
Richie 40 2016
Smith 60 2015
I don't know how to get this answer - my attempt so far:
select Name, score
from table
order by score ...
Output should be
Richie 50 2017
Richie 40 2016
Smith 60 2015
Use lag():
select t.*
from (select t.*, lag(score) over (partition by name order by year) as prev_score
from t
) t
where score > prev_score;
You can do it with a self join:
select t.*
from tablename t inner join tablename tt
on tt.name = t.name and tt.year = t.year - 1
where t.score > tt.score
or with exists:
select t.*
from tablename t
where exists(
select 1 from tablename
where name = t.name and year = t.year - 1 and score < t.score
)
See the demo.
Results:
> name | score | year
> :----- | ----: | ---:
> Richie | 50 | 2017
> Richie | 40 | 2016
> Smith | 60 | 2015
Do not use py = (cy.year - 1) or cy = (py.year + 1) in the join, it wouldn't work when there is a gap of 2 or more years.
Try this :
select distinct cy.name,cy.score,cy.year from tablename cy
join tablename py
on cy.NAME = py.NAME and cy.year > py.year and cy.score > py.score
order by cy.year desc;
Results :
NAME SCORE YEAR
-------------------- ---------- ----------
Richie 50 2017
Richie 40 2016
Smith 60 2015

How to replace all values in grouped column except first row

I have table like this:
ID Region CreatedDate Value
--------------------------------
1 USA 2016-01-01 5
2 USA 2016-02-02 10
3 Canada 2016-02-02 2
4 USA 2016-02-03 7
5 Canada 2016-03-03 3
6 Canada 2016-03-04 10
7 USA 2016-03-04 1
8 Cuba 2016-01-01 4
I need to sum column Value grouped by Region and CreatedDate by year and month. The result will be
Region Year Month SumOfValue
--------------------------------
USA 2016 1 5
USA 2016 2 17
USA 2016 3 1
Canada 2016 2 2
Canada 2016 3 13
Cuba 2016 1 4
BUT I want to replace all repeated values in column Region with empty string except first met row. The finish result must be:
Region Year Month SumOfValue
--------------------------------
USA 2016 1 5
2016 2 17
2016 3 1
Canada 2016 2 2
2016 3 13
Cuba 2016 1 4
Thank you for a solution. It will be advantage if solution will replace also in column Year
You need to use SUM and GROUP BY to get the SumOfValue. For the formatting, you can use ROW_NUMBER:
WITH Cte AS(
SELECT
Region,
[Year] = YEAR(CreatedDate),
[Month] = MONTH(CreatedDate),
SumOfValue = SUM(Value),
Rn = ROW_NUMBER() OVER(PARTITION BY Region ORDER BY YEAR(CreatedDate), MONTH(CreatedDate))
FROM #tbl
GROUP BY
Region, YEAR(CreatedDate), MONTH(CreatedDate)
)
SELECT
Region = CASE WHEN Rn = 1 THEN c.Region ELSE '' END,
[Year],
[Month],
SumOfValue
FROM Cte c
ORDER BY
c.Region, Rn
ONLINE DEMO
Although this can be done in TSQL, I suggest you do the formatting on the application side.
Query that follows the same order as the OP.

aggregate a few rows and display in oracle

I have a table ZXC
select NAME, MONTH, YEAR, DEPT, MONTHVAL, YEARVAL from ZXC
the column MONTHVAL has some values. I want to aggregate some rows based on the combination of name, dept and month, and display the aggregated value in YEARVAL column.
for example, if i have the table
Name Month Year Dept Monthval Yearval
BLAKE Jan 2011 100 124.542 0
KING Feb 2011 200 234.542 0
KING Jan 2011 200 27764.464 0
BLAKE March 2011 100 0 0
BLAKE Feb 2011 400 0 0
SCOTT Jan 2011 500 24564.464 0
KING March 2011 200 1265.542 0
KING April 2011 200 1065.542 0
then i want to see the result as
Name Month Year Dept Monthval Yearval
BLAKE Jan 2011 100 124.542 124.542
KING Jan 2011 200 27764.464 27764.464
SCOTT Jan 2011 500 24564.464 24564.464
KING Feb 2011 200 234.542 27999.006
BLAKE Feb 2011 100 0 124.542
KING March 2011 200 1265.542 29264.548
BLAKE March 2011 100 0 124.542
KING April 2011 200 1065.542 30330.09
What about this:
SELECT name
, dept
, year
, SUM( monthval ) yearval
FROM zxc
GROUP BY name
, dept
, year;
This would produce a total of monthly values for each year. I am not really sure if this is
what you needed, but looks like it to me.
You can make it even fancier by using ROLLUP() or CUBE() functions in GROUP BY functions (multiple level of aggregations).
Sounds like:
select NAME,
MONTH,
YEAR,
DEPT,
MONTHVAL,
SUM(MONTHVAL) OVER (PARTITION BY YEAR) YEARVAL
from ZXC
Based on your output, it seems like you want a running total for every person. Basically, the following query shows a general solution for this:
SELECT
Name,
Month,
Year,
Dept,
Monthval,
SUM(Monthval) OVER (PARTITION BY Name, Dept ORDER BY Year, Month) AS Yearval
FROM ZXC
But there might be a problem with ordering by Month, because the months seems to be stored as names in your table, not as numbers. I would then change the above like this:
SELECT
Name,
Month,
Year,
Dept,
Monthval,
SUM(Monthval) OVER (
PARTITION BY Name, Dept
ORDER BY TO_DATE(Year || '-' || SUBSTR(Month, 1, 3), '-01', 'YYYY-MON-DD')
) AS Yearval
FROM ZXC

How do i find out a value between two parameters in postgres sql?

For example:
name | startyear | endyear
jon 2003 2005
jake 1999 2002
blake 1997 1998
jake 1995 1996
jason 1993 1994
Is there a way to return blake?
I want to know who was treasurer between the two terms of jake.
You could use between, like:
select yt.name
from YourTable yt
where TheYear between yt.startyear and yt.endyear
between is inclusive, so this would return Blake for TheYear = 97 and 98.
Without more information, this is the best suggestion I can give:
SELECT name
FROM your_table
WHERE startyear > (SELECT min(endyear) FROM your_table WHERE name = 'jake')
AND endyear < (SELECT max(startyear) FROM your_table WHERE name = 'jake')