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.
Related
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
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 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 have a MySQL table where there are many rows for each person, and I want to write a query which aggregates rows with special constraint. (one per person)
For example, lets say the table is consist of following data.
name date reason
---------------------------------------
John 2013-04-01 14:00:00 Vacation
John 2013-03-31 18:00:00 Sick
Ted 2012-05-06 20:00:00 Sick
Ted 2012-02-20 01:00:00 Vacation
John 2011-12-21 00:00:00 Sick
Bob 2011-04-02 20:00:00 Sick
I want to see the distribution of 'reason' column. If I just write a query like below
select reason, count(*) as count from table group by reason
then I will be able to see number of reasons for this table overall.
reason count
------------------
Sick 4
Vacation 2
However, I am only interested in single reason from each person. The reason that should be counted should be from a row with latest date from the person's records. For example, John's latest reason would be Vacation while Ted's latest reason would be Sick. And Bob's latest reason (and the only reason) is Sick.
The expected result for that query should be like below. (Sum of count will be 3 because there are only 3 people)
reason count
-----------------
Sick 2
Vacation 1
Is it possible to write a query such that single latest reason will be counted when I want to see distribution(count) of reasons?
Here are some facts about the table.
The table has tens of millions of rows
For most of times, each person has one reason.
Some people have multiple reasons, but 99.99% of people have fewer than 5 reasons.
There are about 30 different reasons while there are millions of distinct names.
The table is partitioned based on date range.
SELECT T.REASON, COUNT(*)
FROM
(
SELECT PERSON, MAX(DATE) AS MAX_DATE
FROM TABLE-NAME
GROUP BY PERSON
) A, TABLE-NAME T
WHERE T.PERSON = A.PERSON AND T.DATE = A.MAX_DATE
GROUP BY T.REASON
Try this
select reason, count(*) from
(select reason from table where date in
(select max(date) from table group by name)) t
group by reason
In MySQL, it's not very efficient to do this kind of query since you don't have access to tools like partitionning query in SQL Server or Oracle.
You can still emulate it by doing a subquery and retrieve the rows based on the condition you need, here the maximum date :
SELECT t.reason, COUNT(1)
FROM
(
SELECT name, MAX(adate) AS maxDate
FROM #aTable
GROUP BY name
) maxDateRows
INNER JOIN #aTable t ON maxDateRows.name = t.name
AND maxDateRows.maxDate = t.adate
GROUP BY t.reason
You can see a sample here.
Test this query on your samples, but I'm afraid that it will be slow as hell.
For your information, you can do the same thing in a more elegant and much much faster way in SQL Server :
SELECT reason, COUNT(1)
FROM
(
SELECT name
, reason
, RANK() OVER(PARTITION BY name ORDER BY adate DESC) as Rank
FROM #aTable
) AS rankTable
WHERE Rank = 1
GROUP BY reason
The sample is here
If you are really stuck to MySql, and the first query is too slow, then you can split the problem.
Do a first query creating a table:
CREATE TABLE maxDateRows AS
SELECT name, MAX(adate) AS maxDate
FROM #aTable
GROUP BY name
Then create index on both name and maxDate.
Finally, get the results :
SELECT t.reason, COUNT(1)
FROM maxDateRows m
INNER JOIN #aTable t ON m.name = t.name
AND m.maxDate = t.adate
GROUP BY t.reason
The solution you are looking for seems to be solved by this query :
select
reason,
count(*)
from (select * from tablename group by name) abc
group by
reason
It is quite fast and simple. You can view the SQL Fiddle
Apologies if this answer duplicates an existing. Maybe I'm suffering from some form aphasia but I cannot see it...
SELECT x.reason
, COUNT(*)
FROM absentism x
JOIN
( SELECT name,MAX(date) max_date FROM absentism GROUP BY name) y
ON y.name = x.name
AND y.max_date = x.date
GROUP
BY reason;
I have a table of bookings. I want to count how many bookings occur on each day, starting from specified check in date and check out date. Eg. if check in date was 10-06-2012 and check out date was 14-06-2012 I require a table like this
Date Bookings
10-06-2012 1
11-06-2012 1
12-06-2012 2
13-06-2012 4
14-06-2012 3
I am struggling to get this working. I can count bookings in between the dates but not for each date between check in date and check out date.
I am not sure I understand your question. The query below assumes:
Your bookings table has (at least) columns date, checkin, checkout.
You are looking for bookings where checkin >= 10-06-2012 and checkout <= 14-06-2012.
Here is the query:
SELECT date, COUNT(*)
FROM bookings
WHERE checkin >= '2012-06-10' AND checkout <= '2012-06-14'
GROUP BY date
Use SUM() to find total bookings between a date range.
Try Below :
SELECT Date,SUM(Bookings)
FROM tablename
WHERE Date between 'startdate' AND 'enddate'
GROUP BY Date
First thing you need is a table of dates, day by day. Now mysql is not my thing, so I will try to write down as much info on what I'm doing as I can. Please correct these examples.
Table of dates might be prepared by a job checking for the last booking date and adding missing dates to table of dates. If this is not something you would accept, other solution is to create table dynamically, but there are some perils. To my knowledge there is no way to create such a table, but you can do a practically-working surrogate by selecting distinct dates from your booking table and cross joining this with table of days made in query itself:
((select distinct checkIn from bookings union select distinct checkOut from bookings)
cross join (select 0 union select 1 union select 2 ...))
The list of days should contain as many days as the biggest gap between checkin dates and each checkin and checkout date. This is something you will have to keep an eye on, or simply make the list sufficiently large, for example a hundred days.
Now that you have a table of dates, you need to count bookings matching this date. Complete query would look like this:
select tableOfDates.date, count(bookings.checkIn) bookings
from
(
(
select distinct dates.date + INTERVAL days.day DAY -- OR HOWEVER you add days in mysql
from
(select distinct checkIn date from bookings union select distinct checkOut from bookings) dates
cross join (select 0 day union select 1 union select 2 union 3 union 4 union 5 union 6 union 7) days
)
) tableOfDates
left join bookings
on tableOfDates.date between bookings.checkIn and bookings.checkOut
where tableOfDates.date between [YOUR DATE RANGE]