SQL Where exists use value else use another - sql

I have a table where I want to join to bring through an i.d, straight forward enough but I only want to bring through values that are 'live' (referenced by a 1 in the flag column below). On the latest year no values are live yet but I need these values brought through too. It might be easier to explain in an example.
Joining Table:
Company Year Product ID Flag
A 2019 X 100 0
A 2019 X 101 1
A 2019 Y 102 1
A 2019 Y 103 0
A 2019 Y 104 0
A 2020 X 105 1
A 2020 Y 106 0
A 2020 Y 107 1
A 2020 Y 108 0
A 2020 Z 109 1
A 2021 X 110 0
A 2021 Y 111 0
A 2021 Y 112 0
A 2021 Y 113 0
A 2021 Z 114 0
I need to bring through those values that have a 1 in the Flag column and then all values with a year of 2021 (when 2021 begins the values in the flag column for 2021 will swap to zeroes and 1s, with the need to only bring through the rows with a 1 in the flag column, again).
The need to bring through next years values will reoccur at the end of every year so the idea is to future proof this from further changes so adding a when year =2021 is not an option.
The original table has the company, year and product so when I join it will be on these three fields.
Any thoughts, let me know
Thanks

Is this what you want?
select t.*
from mytable t
where flag = 1 or year = extract(year from current_date)
This brings rows where flag has value 1 or where year is the current year.
Note that this uses standard date functions extract() and current_date - not all databases support this syntax, but they all have equivalent.

Related

Return the first and last value from one column when value from another column changes

I am trying to write a PostgreSQL query to return the first and last dates corresponding to indices. I have a table:
Datetime
Index
March 1 2021
0
March 2 2021
0
March 3 2021
0
March 4 2021
1
March 5 2021
1
March 6 2021
2
In this case, I would want to return:
I am wondering how I would write the PostgreSQL query for this.
I think this can be done with the following:
SELECT MIN("Datetime") AS Start
, MAX("Datetime") AS End
, "Index"
FROM <your_table>
GROUP BY "Index"
ORDER BY "Index"
;

MS Access SQL – How can I count the occurrence of a number from one table in strings of another table

In MS Access 365 I have 2 tables and I want to count the occurrence of a year from the first table in part of a string of the second table, purely with SQL (so far I used VBA, but I want to simplify).
The first table (tDistinctYears) contains all the years, in which one of our members paid:
ID
PaymentYear
1
2015
2
2016
3
2017
3
2018
4
2019
5
2020
6
2021
7
2022
The second table (tPayments) has all payments from members with one column containing a membership number and the other one containing payment years. Sometimes a member pays for one year, sometime for several years. The table therefore looks like that:
MembershipNr
YearPayment
11
2016
11
2017
11
2018
26
2017
26
2018;2019
26
2020;2021;2022
38
2016
38
2017
38
2018;2019;2020;2021
I want a query which tells me how many members paid in which year:
PaymentYear
Count
2015
0
2016
2
2017
3
2018
3
2019
2
2020
2
2021
2
I used the following SQL query, which I found using various answers on stackoverflow:
SELECT tDistinctYears.PaymentYear, (COUNT(tPayments.YearPayment)) AS [Count]
FROM tDistinctYears
LEFT JOIN tPayments ON tDistinctYears.PaymentYear like "*" & tPayments.YearPayment & "*"
WHERE (tDistinctYears.PaymentYear > 0 AND tDistinctYears.PaymentYear <= YEAR(NOW()))
GROUP BY tDistinctYears.PaymentYear;
But what I get is this:
PaymentYear
Count
2015
0
2016
2
2017
3
2018
1
2019
0
2020
0
2021
0
It seems as if the above query does not use the “like” expression in the JOIN ON section.
Can someone help me, please?
I think you are close just alter column in where condition tPayments.YearPayment should be first and tDistinctYears.PaymentYear should be inside like operator.
SELECT tDistinctYears.PaymentYear, (COUNT(tPayments.YearPayment)) AS [Count]
FROM tDistinctYears
LEFT JOIN tPayments ON tPayments.YearPayment like "*" &
tDistinctYears.PaymentYear
& "*" WHERE (tDistinctYears.PaymentYear > 0 AND tDistinctYears.PaymentYear <=
YEAR(NOW()))
GROUP BY tDistinctYears.PaymentYear;

Compare data from for specific column grouping and Update based on criteria

I have a table with the following structure:
Employee Project Task Accomplishment Score Year
John A 1 5 60 2016
John A 1 6 40 2018
John A 2 3 30 2016
Simon B 2 0 30 2017
Simon B 2 4 30 2019
David C 1 3 20 2015
David C 1 2 40 2016
David C 3 0 25 2017
David C 3 5 35 2017
I want to create a view with Oracle SQLout of the above table which looks like as follows:
Employee Project Task Accomplishment Score Year UpdateScore Comment
John A 1 5 60 2016 60
John A 1 6 40 2018 100 (=60+40)
John A 2 3 30 2016 30
Simon B 2 0 30 2017 30
Simon B 2 4 40 2019 40 (no update because Accomplishement was 0)
David C 1 3 20 2015 20
David C 1 2 40 2016 60 (=20+40)
David C 3 0 25 2017 25
David C 3 5 35 2017 35 (no update because Accomplishement was 0)
The Grouping is: Employee-Project-Task.
The Rule of the UpdateScore column:
If for a specific Employee-Project-Task group Accomplishment column value is greater than 0 for the previous year, add the previous year's score to the latest year for the same Employee-Project-Task group.
For example: John-A-1 is a group which is different from John-A-2. So as we can see for John-A-1 the Accomplishment is 5 (which is greater than 0) in 2016, so we add the Score from 2016 with the score of 2018 for the John-A-1 and the updated score becomes 100.
For Simon-B-2, the accomplishment was 0, so there will be no update for 2019 for Simon-B-2.
Note: I don't need the Comment field, it is there just for more clarification.
Use analytic functions to determine if there was a score for the previous year, and if so, add it to the UpdatedScore.
select Employee, Project, Task, Accomplishment, Score, Year,
case when lag(Year) over (partition by Employee, Project order by Year) = Year - 1
then lag(Score) over (partition by Employee, Project order by Year)
else 0
end + Score as UpdatedScore
from EmployeeScore;
This is a bit strange -- you are counting the accomplishment of 0 in one year but not the next. Okay.
Use analytic functions:
select t.*,
(case when lag(accomplishment) over (partition by Employee, Project, Task order by year) > 0
then lag(score) over (partition by Employee, Project, Task order by year)
else 0
end) + score as update_score
from t;
from t

How to get column value comparison in sql?

I have a table as below. The table holds the price of a product for each day in a year. I would like to get price change for each day by year.
Product Year 1Jan 2Jan .................... 31Dec
A 2018 10 20 .................... 120
A 2019 130 150 .................... 200
B 2018 15 23 .................... 90
B 2019 113 130 .................... 220
I would like to compare columns sequentially with year overlaps and get output as below.
• For the year 2018, by negating the value 2 Jan from 1 Jan (2 Jan-1 Jan), we get the new value of 2 Jan.
• For the year 2018, by negating the value 3Jan from 2 Jan (3 Jan-2 Jan), we get the new value of 3 Jan.
• For the year 2018, by negating the value 31Dec from 30 Dec (31 Dec-30 Dec), we get the new value of 31 Dec
• Now, For the year 2019, by negating the value 31 Dec(2018 year) from 1 Jan (2019 year), we get the new value of 1 Jan, 2019
So, in a nutshell, the value of a column is the difference of its value with previous day value.
Product Year 1Jan 2Jan .................... 31Dec
A 2018 10 10 .................... 15 (just assume value of 30Dec column is 105)
A 2019 10 20 .................... 10 (just assume value of 30Dec column is 190)
B 2018 15 8 .................... 8 (just assume value of 30Dec column is 82)
B 2019 23 17 .................... 10 (just assume value of 30Dec column is 210)
Let me know, if things are not clear.
Though logically there is nothing in this query, but still you have to work hard to write it -
SELECT Product
,Year
,1Jan
,2Jan - 1Jan 2Jan
,3Jan - 2Jan 3Jan
.
.
.
,31Dec - 30Dec 31Dec
FROM YOUR_TAB
ORDER BY Product
,Year;
first of all I think the design of the table could be better but thats a topic for some other time. Right now below code should work -
SELECT Product, Year,
1Jan AS '1st Jan',
2Jan-1Jan AS '2nd Jan',
3Jan-2Jan AS '3rd Jan',
4Jan-3Jan AS '4th Jan',
.
.
.
.
.
31Dec-30Dec AS '31st Dec',
FROM [table name];

sql running total math current quarter

Im trying to figure out the total for the quarter when the only data shown is a running total for the year:
Id Amount Periods Year Type Date
-------------------------------------------------------------
1 65 2 2014 G 4-1-12
2 75 3 2014 G 7-1-12
3 25 1 2014 G 1-1-12
4 60 1 2014 H 1-1-12
5 75 1 2014 Y 1-1-12
6 120 3 2014 I 7-1-12
7 30 1 2014 I 1-1-12
8 90 2 2014 I 4-1-12
In the data shown above. The items in type G and I are running totals for the period (in qtrs). If my query returns period 3, is there a sql way to get the data for the qtr? The math would involve retrieving the data for the 3rd period - 2nd period.
Right now my sql is something like:
SELECT * FROM data WHERE Date='4-1-12';
In this query, it will return row #1, which is a total for 2 periods. I would like it to return just the total for the 2nd period. Im looking to make this happen with SQLite.
Any help would be appreciated.
Thank alot
You want to subtract the running total of the previous quarter:
SELECT Id,
Year,
Type,
Date,
Amount - IFNULL((SELECT Amount
FROM data AS previousQuarter
WHERE previousQuarter.Year = data.year
AND previousQuarter.Type = data.Type
AND previousQuarter.Periods = data.Periods - 1
), 0) AS Amount
FROM data
The IFNULL is needed to handle a quarter that has no previous quarter.