SQl: Group by month and year - asp.net

Hi my code doesn't work, Im trying to group my blogentries by year and month here's my sql
SELECT * FROM(
SELECT WP_BlogEntries.BlogEntryID, WP_BlogEntries.AddedDate,
WP_BlogEntries.AddedBy, WP_BlogEntries.BlogID,
WP_BlogEntries.Title, WP_BlogEntries.Description, WP_BlogEntries.Body,
WP_BlogEntries.ReleaseDate, WP_BlogEntries.ExpireDate,
WP_BlogEntries.Approved, WP_BlogEntries.Listed,
WP_BlogEntries.CommentsEnabled, WP_BlogEntries.OnlyForMembers,
WP_BlogEntries.ViewCount, WP_BlogEntries.Votes,
WP_BlogEntries.TotalRating
FROM WP_BlogEntries
WHERE WP_BlogEntries.ReleaseDate < GETDATE()
AND WP_BlogEntries.ExpireDate > GETDATE()
AND Approved = 1
AND Listed = 1
AND WP_BlogEntries.BlogID = #BlogID) MonthEntries
GROUP BY YEAR(ReleaseDate), MONTH(ReleaseDate)

It would be helpful to know the error message.
You can't do a SELECT * FROM if you specify GROUP BY.
The only valid columns are those in the GROUP BY or an aggregate function.
If you group by year and month, then each row will contain one year and month, it is impossible for SQL to know which other columns to display as there could be more than one. (e.g. two blog entries in one month)
Did you mean to ORDER BY instead?

Simething like This :
select convert(varchar(50),YEAR(date)) +'/'+convert (varchar(50), MONTH(date)) ,Name , COUNT( Name) ,[DATE] from table1
group by convert(varchar(50),YEAR(date)) +'/'+convert (varchar(50), MONTH(date)) ,Name,[date]
order by [Date] Desc

Related

Can we use the at sign in sqlite for a constant?

It is actually possible to use # (the at sign) with sqlite to be able to use a calculated value as a constant in an other query ?
I am using a variable(a total) that i calculated previously to get an other variable (a proportion) over two time periods.
Total amout of sale
Proportion of sale between the first semester and second semester.
I copy the first query to get the constant and i had the first query to the second.
The answer is no BUT:-
This could possibly be done in a single query.
Consider this simple demo with hopefully easy to understand all-in-one queries:-
First the sales table:-
i.e. 2 columns semester and amount
10 rows in total so 1000 is the total amount
6 rows are S1 (amount is 600) so 60%
4 rows are S2 (amount is 400) so 40%
Created and populated using:-
CREATE TABLE IF NOT EXISTS sales (semester TEXT, amount REAL);
INSERT INTO sales VALUES('S1',100),('S1',100),('S1',100),('S1',100),('S1',100),('S1',100),('S2',100),('S2',100),('S2',100),('S2',100);
So you could use an all-in-one query such as:-
SELECT
(SELECT sum(amount) FROM sales) AS total,
(SELECT sum(amount) FROM sales WHERE semester = 'S1') AS s1total,
((SELECT sum(amount) FROM sales WHERE semester = 'S1') / (SELECT sum(amount) FROM sales)) * 100 AS s1prop,
(SELECT sum(amount) FROM sales WHERE semester = 'S2') AS s2total,
((SELECT sum(amount) FROM sales WHERE semester = 'S2') / (SELECT sum(amount) FROM sales)) * 100 AS s2prop
;
This would result in
i.e. s1prop and s2prop the expected results (the other columns may be useful)
An alternative, using a CTE (Common Table Expressions) that does the same could be:-
WITH cte_total(total,s1total,s2total) AS (SELECT
(SELECT sum(amount) FROM sales),
(SELECT sum(amount) FROM sales WHERE semester = 'S1'),
(SELECT sum(amount) FROM sales WHERE semester = 'S2')
)
SELECT total, s1total, (s1total / total) * 100 AS s1prop, s2total, (s2total / total) * 100 AS s2prop FROM cte_total;
you can have multiple CTE's and gather data from other tables or even being passed as parameters. They can be extremely useful and would even allow values to be accessed throughout.
e.g.
Here's an example where a 2nd cte is added (as the first cte) that mimics passing 3 dates (instead of the hard coded values ?'s could be coded and the parameters passed via parameter binding).
As the sales table has no date for the sale a literal value has been coded, this would be normally be the column with the sale date instead of WHERE '2023-01-01' /*<<<<< would be the column that holds the date */
the hard coded date has purposefully been used so result in the BETWEEN clause resulting in true.
if the date column did exist then WHERE criteria for the semester could then be by between the respective dates for the semester.
The example:-
WITH
dates AS (SELECT
'2023-01-01' /*<<<<< ? and can then be passed as bound parameter*/ AS startdate,
'2023-03-01' /*<<<<< ? and can then be passed as bound parameter*/ AS semester2_start,
'2023-05-30' /*<<<<< ? and can then be passed as bound parameter*/as enddate
),
cte_total(total,s1total,s2total) AS (SELECT
(SELECT sum(amount) FROM sales
WHERE '2023-01-01' /*<<<<< would be the column that holds the date */
BETWEEN (SELECT startdate FROM dates)
AND (SELECT enddate FROM dates)),
(SELECT sum(amount) FROM sales WHERE semester = 'S1'),
(SELECT sum(amount) FROM sales WHERE semester = 'S2')
)
SELECT total, s1total, (s1total / total) * 100 AS s1prop, s2total, (s2total / total) * 100 AS s2prop FROM cte_total;

How to use default time function in metabase

SELECT a_offer.name as Engagement Name, count(*) count
FROM u_user_offer_detail_record
left join a_offer on a_offer.id = u_user_offer_detail_record.offer_id
WHERE 1
and update_time_ms>= UNIX_TIMESTAMP([[{{start_date}} #]] date(Now()-Interval 1 DAY)) * 1000
and update_time_ms<= UNIX_TIMESTAMP([[{{end_date}} #]] Now()) * 1000
and award_status=12
and u_user_offer_detail_record.adset_id = [[{{adset_id}} #]]1459904136457728
group by a_offer.name
I want to user datetime picker, if not use default date, but it can't work when select date, How can I do?
order by count desc)

substring: row information to field names

I have information in an SQLite database. The database structure can not be changed.
I am trying to construct a query that will give me a result in which the TypeOfInformation entries are field names:
My first try was to work with subqueries:
SELECT (SELECT Value FROM FinData WHERE Type = 'Price') AS Price,
(SELECT Value FROM FinData WHERE Type = 'Volume') AS Volume
FROM FinData")
Seemed perfect, however, the result was a resultset in which EVERY entry in the columns Price and Volume are equal to the FIRST respective entry of Price and Volume in the original database:
I tried to get around this and to include the other Price and Volume information ­- but I failed. (Which is a pity, because the syntax seemed somehow easy to grasp.)
Next try was the following:
Select Date, Value AS Volume From FinData WHERE Volume IN
(SELECT Value FROM FinData WHERE (Type = 'Volume'))
This gives me a resultset with a Volume column and all volume information. Okay, so far. However, when I want to complement this resultset which a Price column via
Select Date, Value AS Volume From FinData WHERE Volume IN
(SELECT Value FROM FinData WHERE (Type = 'Volume'))
union
Select Date, Value AS Close From FinData WHERE Price IN
(SELECT Value FROM FinData WHERE (Type = 'Price'))
I get a resultset that shows Price and Volume information in only ONE column ("Volume"), which therefore is also useless.
To look up a value corresponding to a row in the outer query, you have to use a correlated subquery, which explicitly makes a connection between both:
SELECT Date,
(SELECT Value
FROM FinData
WHERE Date = Dates.Date
AND TypeOfInformation = 'Price'
) AS Price,
(SELECT Value
FROM FinData
WHERE Date = Dates.Date
AND TypeOfInformation = 'Volume'
) AS Volume
FROM (SELECT DISTINCT Date
FROM FinData) AS Dates;
(The DISTINCT subquery is used to prevent multiple rows for each date.)
Alternatively, group all rows for a date, and use aggregation functions and CASE expressions to extract the values from the proper rows:
SELECT Date,
MAX(CASE WHEN TypeOfInformation = 'Price' THEN Value END) AS Price,
MAX(CASE WHEN TypeOfInformation = 'Volume' THEN Value END) AS Volume
FROM FinData
GROUP BY Date;
Assuming dates are unique per price volume pair, you can do this:
with xxx(date,price,volume) as
(
select date,value,0 from findata where typeofinformation = 'Price'
union
select date,0,value from findata where typeofinformation = 'Volume'
)
select date,sum(price) price,sum(volume) volume from xxx group by date;

How to select top rated photos in the last few days?

Here is my data context:
Photos (ID, Title)
Users (ID, FullName)
Ratings (PhotoID, UserID, Value, Date)
Business rules:
users can rate a photo from 1 to 5
a given user can rate a given photo only once
I want to select the top rated photos by day in the last let's say 3 days. So which photo got the best rating today, yesterday and the day before yesterday? I would like to make the number of days variable if it possible. I have to display the last N days only they rated excluding empty days.
I would like to get the photos in a single query/result because I want to bind it to a ListView to display them on a web form.
I've started this way:
DECLARE #days INT = 3
SELECT TOP (#days) ... FROM Ratings
INNER JOIN Photos ON Photos.ID = Ratings.PhotoID
GROUP BY DATEDIFF(day, [Date], CURRENT_TIMESTAMP)
ORDER BY DATEDIFF(day, [Date], CURRENT_TIMESTAMP) DESC
How can I group my groups by PhotoID, order them by SUM(Value) and select the first one from each group? Thank you very much for your help.
SELECT Date, TotalRating, Photos.*
FROM Photos
INNER JOIN
(SELECT ROW_NUMBER() OVER (ORDER BY Date DESC) AS RowNumber,
PhotoID, Date, TotalRating
FROM (SELECT ROW_NUMBER() OVER (PARTITION BY Date, ORDER BY TotalRating DESC) AS inRowNumber,
PhotoID, Date, TotalRating
FROM (SELECT PhotoID, Date, SUM(Value) AS TotalRating
FROM Photos
GROUP BY PhotoID, Date
HAVING SUM(Value) > 0 ) t)
WHERE inRowNumber = 1) t ON Photos.Id = t.PhotoID
WHERE RowNumber <= #days

Preventing Max function from using timestamp as part of criteria on a date column in PL/SQL

If I query:
select max(date_created) date_created
on a datefield in PL/SQL (Oracle 11g), and there are records that were created on the same date but at different times, Max() returns only the latest times on that date. What I would like to do is have the times be ignored and return ALL records that match the max date, regardless of their associated timestamp in that column. What is the best practice for doing this?
Edit: what I'm looking to do is return all records for the most recent date that matches my criteria, regardless of varying timestamps for that day. Below is what I'm doing now and it only returns records from the latest date AND time on that date.
SELECT r."ID",
r."DATE_CREATED"
FROM schema.survey_response r
JOIN
(SELECT S.CUSTOMERID ,
MAX (S.DATE_CREATED) date_created
FROM schema.SURVEY_RESPONSE s
WHERE S.CATEGORY IN ('Yellow', 'Blue','Green')
GROUP BY CUSTOMERID
) recs
ON R.CUSTOMERID = recs.CUSTOMERID
AND R.DATE_CREATED = recs.date_created
WHERE R.CATEGORY IN ('Yellow', 'Blue','Green')
Final Edit: Got it working via the query below.
SELECT r."ID",
r."DATE_CREATED"
FROM schema.survey_response r
JOIN
(SELECT S.CUSTOMERID ,
MAX (trunc(S.DATE_CREATED)) date_created
FROM schema.SURVEY_RESPONSE s
WHERE S.CATEGORY IN ('Yellow', 'Blue','Green')
GROUP BY CUSTOMERID
) recs
ON R.CUSTOMERID = recs.CUSTOMERID
AND trunc(R.DATE_CREATED) = recs.date_created
WHERE R.CATEGORY IN ('Yellow', 'Blue','Green')
In Oracle, you can get the latest date ignoring the time
SELECT max( trunc( date_created ) ) date_created
FROM your_table
You can get all rows that have the latest date ignoring the time in a couple of ways. Using analytic functions (preferrable)
SELECT *
FROM (SELECT a.*,
rank() over (order by trunc(date_created) desc) rnk
FROM your_table a)
WHERE rnk = 1
or the more conventional but less efficient
SELECT *
FROM your_table
WHERE trunc(date_created) = (SELECT max( trunc(date_created) )
FROM your_table)

Resources