Storing/Quering multiple value in SQLite - sql

I'm trying to store a blooming season in month for each tree in SQLite3. Currently I had the field "month" then I store the month name in the field. For example
Tree Name Month
Tree1 Jan,Feb,Mar
Tree2 Nov,Dec,Jan
Tree3 Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec
Tree4 Mar,Apr,Nov,Dec
Tree5 Jan,Feb,Mar,Apr
I'm not sure if this is the best way to store it, Any recommendation is appreciate.
Secondly, I need to perform a query where I enter in the month and it should return me the tree name that match the search criteria. For example
If I search for
"Jan"
the result should be Tree1,Tree2,Tree3,Tree5
"Jan,Feb,Mar"
the result should be Tree1,Tree3,Tree5
"Jan,Feb,Mar,Apr"
the result should be Tree5
"Sep,Oct,Nov,Dec"
the result should be none
Which SQL query do I have to use in order to obtain the above result?
Thanks

No. This is not the best way to store it.
You should normalise your data and store one month/tree per row
Tree1 Jan
Tree1 Feb
Tree1 Mar
Tree2 Nov
Tree2 Dec
Tree2 Jan
....
(or perhaps store the months as numbers 1-12)
then you can
select treename from TreeBlooming where month = 'jan'
and
select treename from TreeBlooming
where month in ('jan','feb')
group by treename
having count(distinct month)=2

You can use Group_concat in following way:
SELECT Group_concat(name) AS [tree name]
FROM tree
WHERE month LIKE '%Jan,Feb,Mar%'
Check out SQLFIDDLE

Related

Get multiple columns for different WHERE clause on the same column in SQL

I have a table and column containing date (say in string). I need to get two columns such as countin(2020) and countin(2019) from the same date column such that date is like '2020%' or '2019%' and I want them as separate columns.
My query is kind of like this.
select C.pin_code, count(distinct(C.customer_code)) as 2020
from table
group by C.pin_code
My output is this
For me there should be another column beside 2020 called 2019 which give same data as 2020 in year 2019.
If I have under emphasized something, please let me know in the comments.
Select
Count(Year(year_col)) as year,
Pin_code
From T
Group_by pin_code
Order by pin_code desc;
You can use pivot in case you need those values in year column
For me there should be another column beside 2020 called 2019 which give same data as 2020 in year 2019.
If your data has a date in it, then I would expect a query like this:
select C.pin_code,
count(distinct case when year(C.date) = 2020 then C.customer_code end) as cnt_2020,
count(distinct case when year(C.date) = 2019 then C.customer_code end) as cnt_2019
from C
group by C.pin_code;
Date/time functions are notoriously database dependent. But year() is pretty common and all databases have this functionality somehow.

SQL store results table with month name

I have several CSV's stored to query against. Each CSV represents a month of data. I would like to count all the records in each CSV and save that data to a table as a row in the table. For instance, the table that represents May should return something that looks like this with June following. The data starts in Feb 2018 and continues to Feb 2019 so year value would be needed as well.
Month Results
----------------
May 18 1170
June 18 1167
I want to run the same query against all the tables for purposes of efficiency. I also want the query to work with all future updates eg. a March 19 table gets added, and the query will still work.
So far, I have this query.
SELECT COUNT(*)
FROM `months_data.*`
I am querying in Google Big Query using Standard SQL.
It sounds like you just want an aggregation that counts rows for each month:
SELECT
DATE_TRUNC(DATE(timestamp), MONTH) AS Month,
COUNT(*) AS Results
FROM `dataset.*`
GROUP BY month
ORDER BY month
You can use the DATE_FORMAT function if you want to control the formatting.
You seem to need union all:
select 2018 as yyyy, 2 as mm, count(*) as num
from feb2018
union all
select 2018 as yyyy, 3 as mm, count(*)
from mar2018
union all
. . .
Note that you have a poor data model. You should be storing all the data in a single table with a date column.

SQL Server : sum particular column for this year and last year

SELECT
a.ERSDataValues_ERSCommodity_ID,c.ersGeographyDimension_country,
b.ERSTimeDimension_Year,
SUM(a.ERSDataValues_AttributeValue) as Total
FROM
cosd.ERSDataValues a, cosd.ERSTimeDimension_LU b,
cosd.ERSGeographyDimension_LU c
WHERE
a.ERSDataValues_ERSCommodity_ID IN (SELECT ERSBusinessLogic_InputDataSeries
FROM [AnimalProductsCoSD].[CoSD].[ERSBusinessLogic]
WHERE ERSBusinessLogic_InputGeographyDimensionID = 7493
AND ERSBusinessLogic_InputTimeDimensionValue = 'all months'
AND ERSBusinessLogic_Type = 'time aggregate')
AND a.ERSDataValues_ERSTimeDimension_ID = b.ERSTimeDimension_ID
AND c.ersGeographyDimension_country != 'WORLD'
AND a.ERSDataValues_ERSGeography_ID = c.ERSGeographyDimension_ID
GROUP BY
b.ERSTimeDimension_Year, a.ERSDataValues_ERSCommodity_ID,
c.ersGeographyDimension_country
ORDER BY
b.ERSTimeDimension_Year, a.ERSDataValues_ERSCommodity_ID
All I want is that sum function above to return sum from Jan 2018 to june 2018 and also I want a sum from previous year for the same time period. I do not want to hardcode the months but I rather want it dynamically.
I thought of using conditional aggregrate functions, but the output does not match to my requirement . Any ideas ?
This is the output I want: https://imgur.com/a/YtDgR8s
You can add a filter to a where clause to limit time dimension to current and previous year, and then add something like this to both the SELECT list and GROUP BY:
CASE
WHEN YEAR(b.date)=YEAR(GETDATE()) THEN 'Current Year'
WHEN YEAR(b.date)=YEAR(GETDATE())-1 THEN 'Previous Year'
ELSE NULL
END
It may look a little different depending on how you define current and previous year, but that's the idea.
In terms of limiting Jan to June this has to be in the WHERE clause. If you do not want to hard-code specific months (Jan/June) then I think you have to reference something else from you time dimension - e.g. if you have quarter attribute you can say quarter_number in (1,2).

Order an SQL table by year and ranges of years

I would like to be able to order the results in the following way.
There are two columns, one stores years and the other year ranges, and, sometimes, dates, like this:
2017
2016
2014–2016
1980-ongoing
2013
2000 28-27 March
1970
At the moment, I concatenate them and order by DESC, Getting this (showing the concatenated temporary column):
order by CONCAT(IFNULL(CAST(Year_Pub AS VARCHAR(16)) THEN '' ELSE CAST(Year_Pub AS VARCHAR(16))), IFNULL(Date_Freeform THEN '' ELSE Date_Freeform)) DESC
The result is:
2017
2016
2014-2016
2013
200028-27 March
1980-ongoing
1970
However, what I would like to get is this (imagine that this is a list of activities for a CV or similar):
1980-ongoing
2017
2016
2014-2016
2013
2000
1970
That is if there is a span of years, I would like to have the ongoing engagements to appear first, ordered by the start year, then have spans of years ordered by last year and mixed with single years. Dates only occur when Year_Pub is NULL and will have to be removed before concatenation, I imagine.
The separator is an ndash, so I need to split those strings by that somehow as I see from examples that show how to order by the family names in tables that have first name and family name in one column but this is a more complicated situation and I am not really familiar with SQL.
Also, this operation will be performed on a table that comes with an application so I do not want to insert data or columns into their database in case something gets broken.
Using SQL on an ElevateDB database (SQL 2003 standard (ANSI ISO/IEC 9075:2003), but a generic solution will do, I can look up the syntax).
Thank you for the advice.
This is one way to achieve your result:
SELECT
year_pub,
date_freeform,
COALESCE(CAST(year_pub AS VARCHAR(4)), date_freeform) AS year_list
FROM
table_name
ORDER BY
COALESCE(CAST(year_pub AS VARCHAR(4)),
CASE WHEN RIGHT(date_freeform, 4) = 'oing'
THEN '9999'
ELSE RIGHT(date_freeform, 4)
END
) DESC,
date_freeform DESC;

View data by date after Format 'mmyy'

I'm trying to answer questions like, how many POs per month do we have? Or, how many lines are there in every PO by month, etc. The original PO dates are all formatted #1/1/2013#. So my first step was to Format each PO record date into 'mmyy' so I could group and COUNT them.
This worked well but, now I cannot view the data by date... For example, I cannot ask 'How many POs after December did we get?' I think this is because SQL does not recognize mm/yy as a comparable date.
Any ideas how I could restructure this?
There are 2 queries I wrote. This is the query to format the dates. This is also the query I was trying to add the date filter to (ex: >#3/14#)
SELECT qryALL_PO.POLN, Format([PO CREATE DATE],"mm/yy") AS [Date]
FROM qryALL_PO
GROUP BY qryALL_PO.POLN, Format([PO CREATE DATE],"mm/yy");
My group and counting query is:
SELECT qryALL_PO.POLN, Sum(qryALL_PO.[LINE QUANTITY]) AS SUM_QTY_PO
FROM qryALL_PO
GROUP BY qryALL_PO.POLN;
You can still count and group dates, as long as you have a way to determine the part of the date you are looking for.
In Access you can use year and month for example to get the year and month part of the date:
select year(mydate)
, month(mydate)
, count(*)
from tableX
group
by year(mydate)
, month(mydate)
You can format it 'YYYY-MM' , and then use '>' for 'after' clause