I want to count how many exact values appear in the week of the year, I know the result will be in the next column but this is ok. I want to count how many X's, Y's and Z's are in the exact week of the year.
In the picture you can find what I wanted to achieve - last column:
Note: COUNT(1) OVER (PARTITION BY WEEK) - Counts how many X's, Y's and Z'(in overall) I have in the Particular Week, but also I want to know how many each of them is in the particular week.
I tried to write subquery but without the result, I don't know how to calculate the values that occur in a particular week also
I wanted to Use Sum(case When Then) but I could not figure it out how to do that.
Excel is so much easier to handle this
This is what I wrote:
SELECT
A.number,
B.flag_value,
B.add_data,
COUNT(1) OVER (PARTITION BY B.flag_value) flgcnt,
DatePart("ww",Add_data) AS Week_NO,
COUNT(1) OVER (PARTITION BY WEEK)
FROM table A AS "A"
LEFT JOIN table B AS "B" ON A.id = B.source_id
WHERE
GROUP BY A.number, B.flag_value
Thank you in advance
Related
I have a subquery that aggregates some UNION ALL selects. Over that I prepare the SELECT to create cross-tab and limit it to let's say 20. I would like to be able to retrieve the total COUNT of sub query results before I am limiting them in main query. This is for the purpose of trying to build a pagination that receives the total number of records and then the specific page record grid.
Sample query:
SELECT
name,
sumIf(metric_value, metric_name = 'data') AS data,
sumif(....
FROM
(SELECT
name, metric_name, SUM(metric_value) as metric_value
FROM
(SELECT
name, 'data' AS metric_name, SUM(data) AS metric_value
FROM
table
WHERE
date > '2017-01-01 00:00:00'
GROUP BY
name
UNION ALL
SELECT
name, 'data' AS metric_name, SUM(data) AS metric_value
FROM
table2
WHERE
date > '2017-01-01 00:00:00'
GROUP BY
name
UNION ALL
SELECT
name, 'data' AS metric_name, SUM(data) AS metric_value
FROM
table3
WHERE
date > '2017-01-01 00:00:00'
GROUP BY
name
UNION ALL
.
.
.)
GROUP BY
name, metric_name)
GROUP BY
name
ORDER BY
name ASC
LIMIT 0,20;
The first subselect returns tons of data, so I thought I can count it and return as one column value, or row and it would propagate to main select that limits 20 results. Because I need to know the entire set of results but don;t want to call the same query twice without limit and with limit just to get COUNT. There are at least 12 UNION ALL third level sub selects, so why waste resources. I am looking to try generic SQL solutions not necessarily related to ClickHouse
I was thinking of using count(*) OVER (), however that is not supported, so if thats only option I know I need to run query twice.
The first thing that one should mention is that nobody is usually interested in the exact number of pages on a query. It can be easily estimated and almost no one will care how exact is the estimation. However, if you have a link to the last page in your GUI, people will often click to link just to see whether it works.
Nevertheless, there are cases when an analyst should visit all the pages, and then the GUI should display the exact amount of work. A good news is that in that latter case, a better strategy is to cache a snapshot of the whole results table and counting the rows in the table becomes not a problem anymore.
I mean, it makes sense to discuss with the customers whether they really need it, because unneeded full scans many times per day may have effect on the database load and billing sums.
Anyway, if you still need to estimate the number of rows, you can simplify the query just to count the number of rows. As I understand this is something like:
SELECT SUM(cnt) as row_count
FROM (
SELECT COUNT(DISTINCT name) as cnt FROM table1 WHERE date > ...
UNION ALL
SELECT COUNT(DISTINCT name) as cnt FROM table2 WHERE date > ...
...
) as counts;
or if data is a constant metric name
SELECT COUNT(DISTINCT name) as row_count
FROM (
SELECT DISTINCT name FROM table1 WHERE date > ...
UNION ALL
SELECT DISTINCT name FROM table2 WHERE date > ...
...
) as names;
I'm trying to build a query to find average number of music tracks played per broadcast hour for a given day.
I have a table that logs when a track was played, based on a datetime value (created field).
So I need to count how many entries, or tracks, where logged per hour.
Then with the hourly totals, find the average.
So far I have this, but wondered if it is correct?
SELECT AVG(a.total) FROM (
SELECT HOUR(created) AS hour, COUNT(id) AS total
FROM `music_log` r
WHERE DATE(created) = DATE( DATE_SUB(NOW() , INTERVAL 1 DAY) ) group by HOUR(r.created)
) a
I got to admit, I formulated that from another post on stackoverflow, and don't understand what the a and r mean/reference.
I would like to know if I have this right, so I can expand query to cover a quarter (3 months) results.
You can calculate the average without a subquery:
SELECT COUNT(*) / COUNT(DISTINCT DATE(created), HOUR(created) ) as average
FROM `music_log`
WHERE QUARTER(created) = 1 AND YEAR(created) = YEAR(NOW()) ;
This calculates the total count and the number of hours without the need for a subquery.
As Strawberry says, it looks like I'm on the right track. Thanks Strawberry.
To expand this, and just in case it helps anyone else, I've included the query to cover a quarter, in this case the first quarter of the current year....he says hoping there's nothing else wrong with my query :)
SELECT AVG(a.total) FROM (
SELECT DATE(created) as day, HOUR(created) AS hour, COUNT(id) AS total
FROM `music_log`
WHERE QUARTER(created) = 1
AND YEAR(created) = YEAR(NOW())
group by DATE(created), HOUR(created)
) a
In order to calculate it correctly, I needed to group the hourly results by Date and Hour.
In the previous query in the question, it was only grouping by Hour. Which is fine if the Average calculation is over just a single day, but when you expand that beyond a day, the results become incorrect. This is because it will add the total of both occurrence of 11pm, for example, then work out the average.
Hope that helps...or if I've made a mistake, I hope someone picks up on it ;)
I have one table with this headers
id city date item
I am interested in identify the id with the same item in the same month and count how many items repeated receive in the same month. So my query in mysql is:
select a.id, concat(a.id, month(a.date), a.item) as a from table
where a = (select concat(b.id, month(b.date), b.item) as b from table)
group by a.id
having count(a=b)>=1
But that query take too much time and may not work, could you help me?
You haven't reacted to the comments made three hours ago. But from your comments to Seth McClaine's answer I read that you want a list of rows showing id (which despite its name is not the table's unique ID!), month, item, and the number of occurences.
One row per id, month and item means: group by id, month, item.
Use a HAVING clause in order to only show occurences > 1.
select id, month(date), item, count(*)
from mytable
group by id, month(date), item
having count(*) > 1;
Well, this is about what Seth McClaine already told you. And while you commented on his answer, you didn't say what is missing from it for you to accept it.
I think you should be able to do something like this, giving you the count total of items with matching id, month, and item
Select Count(*) as total, month(date) as month, item, id
From table
group by (item, month(date), id)
I am trying to substitute subquery results from another table to this query as a column result, each row is getting full table count, not sure how can I get this to work, please advise.
SELECT id, name, description, (SELECT count(*) FROM day WHERE event_id = 1) AS days
FROM event
I've my sql fiddle located at this address.
http://sqlfiddle.com/#!9/54697
I need an output like this.
id name days
1 'event 1' 3
2 'event 2' 0
I imagine that you want the number of days for each event. If so, you want a correlated subquery:
SELECT e.id, e.name, e.description,
(SELECT count(*) FROM day d WHERE d.event_id = e.id) AS days
FROM event e;
In my opinion, day is a lousy name for a table that stores the days when each event is scheduled. I would expect a table called day to have information about days, not events. You might consider renaming it to EventDays.
I have the following table denoting a tutor teaching pupils in small groups. Each pupil has an entry into the database. A pupil may be alone or in a group. I wish to calculate the tutors "salary" as such: payment is based on time spent - this means that for each sitting (with one or more pupils) only one sitting will be calculated - distinct sittings! The start and end times are unix times.
<pre>
start end attendance
1359882000 1359882090 1
1359867600 1359867690 0
1359867600 1359867690 1
1359867600 1359867690 0
1360472400 1360477800 1
1360472400 1360477800 1
1359867600 1359867690 1
1359914400 1359919800 1
1360000800 1360006200 1
1360000800 1360006200 0
1360000800 1360006200 1
</pre>
This is what I tried: with no success - I can't get the right duration (number of hours for all distinct sittings)
SELECT YEAR(FROM_UNIXTIME(start)) AS year,
MONTHNAME(STR_TO_DATE(MONTH(FROM_UNIXTIME(start)), '%m')) AS month,
COUNT(DISTINCT start) AS sittings,
SUM(TRUNCATE((end-start)/3600, 1)) as duration
FROM schedules
GROUP BY
YEAR(FROM_UNIXTIME(start)),
MONTH(FROM_UNIXTIME(start))
Thanks for your proposals / support!
EDIT: Required results
Rate = 25
Year Month Sittings Duration Bounty
2013 February 2 2.2 2.2*25
2013 April 4 12.0 12.0*25
You could probably do something with subqueries, I've had a play with SQL fiddle, how does this look for you. Link to sql fiddle : http://sqlfiddle.com/#!2/50718c/3
SELECT
YEAR(d.date) AS year,
MONTH(d.date) AS month,
COUNT(*) AS sittings,
SUM(d.duration) AS duration_mins
FROM (
SELECT
DATE(FROM_UNIXTIME(s.start)) AS date,
s.attendance,
end-start AS duration
FROM schedules s
) d
GROUP BY
year,
month
I couldn't really see where attendance comes into this at present, you didn't specify. The inner query is responsible for taking the schedules, extracting a start date, and a duration (in seconds).
The outer query then uses these derived values but groups them up to get the sums. You could elaborate from here i.e. maybe you only want to select where attendance > 0, or maybe you want to multiply by attendance.
In this next example I have done this, calculating the duration in hours instead, and calculating the applicable duration for where sessions have >1 attendance along with the appropriate bounty assuming bounty == hours * rate : http://sqlfiddle.com/#!2/50718c/21
SELECT
YEAR(d.date) AS year,
MONTH(d.date) AS month,
COUNT(*) AS sittings,
SUM(d.duration) AS duration,
SUM(
IF(d.attendance>0,1,0)
) AS sittingsWorthBounty,
SUM(
IF(d.attendance>0,d.duration,0)
) AS durationForBounty,
SUM(
IF(d.attendance>0,d.bounty,0)
) AS bounty
FROM (
SELECT
DATE(FROM_UNIXTIME(s.start)) AS date,
s.attendance,
(end-start)/3600 AS duration,
(end-start)/3600 * #rate AS bounty
FROM schedules s,
(SELECT #rate := 25) v
) d
GROUP BY
year,
month
The key point here, is that in the subquery you do all the calculation per-row. The main query then is responsible for grouping up the results and getting your totals. The IF statements in the outer query could easily be moved into the subquery instead, for example. I just included them like this so you could see where the values came from.