I am trying to use pivot to display my information. I want to use a subquery to select the columns in the report:
select * from
(select continent, country, population
from continents, countries
where continents.id=countries.id
)
pivot (sum(population) for country in (select distinct country from countries)
I keep getting an error when I try to use a subquery to get the list of countries.
I tried using pivot XML but that didn't work either since it returned meaningless xml code.
I want to see the actual numbers!
You can't use result of subquery in PIVOT clause as columns need to be defined statically. But you can generate dynamic SQL using results of your subquery and then execute it via execute immediate.
Related
Can you filter a SQL table based on an aggregated value, but still show column values that weren't in the aggregate statement?
My table has only 3 columns: "Composer_Tune", "_Year", and "_Rank".
I want to use SQL to find which "Composer_Tune" values are repeated in each annual list, as well as which ranks the duplicated items had.
Since I am grouping by "Composer_Tune" & "Year", I can't list "_Rank" with my current code.
The image shows the results of my original "find the duplicates" query vs what I want:
Current vs Desired Results
I tried applying the concepts in this Aggregate Subquery StackOverflow post but am still getting "_Rank is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause" from this code:
WITH DUPE_DB AS (SELECT * FROM DB.dbo.[NAME] GROUP BY Composer_Tune, _Year HAVING COUNT(*)>1)
SELECT Composer_Tune, _Year, _Rank
FROM DUPE_DB
You need to explicitly declare the columns used in the Group By expression in the select columns.
You can use the following documentation if you are using transact sql for the proper use of Group By.
Simply join the aggregated resultset to original unit level table:
WITH DUPE_DB AS (
SELECT Composer_Tune, _Year
FROM DB.dbo.[NAME]
GROUP BY Composer_Tune, _Year
HAVING COUNT(*) > 1
)
SELECT n.Composer_Tune, n._Year, n._Rank
FROM DB.dbo.[NAME] n
INNER JOIN DUPE_DB
ON n.Compuser_Tune = DUPE_DB.Composer_Tune
AND n._Year = DUPE_DB._Year
ORDER n.Composer_Tune, n._Year
I have a table BAR_DATA with two fields: LongDate, Time. Both are long integers. No Access Date/Time involved here.
For each distinct LongDate value there are hundreds of records, each with Time value which may be distinct or duplicate within that LongDate.
I need to create an SQL statement that will group by LongDate and give me a count of distinct Times within each LongDate.
The following SQL statement, (built by an Acess query) does NOT work (some LongDates are omitted):
Query A
SELECT DISTINCT BAR_DATA.LongDate, Count(BAR_DATA.Time) AS CountOfTime
FROM BAR_DATA
GROUP BY BAR_DATA.LongDate
HAVING (((Count(BAR_DATA.Time))<>390 And (Count(BAR_DATA.Time))<>210));
However, if I use Query B to reference Query DistinctDateTime, it does work:
Query B
SELECT DistinctDateTime.LongDate, Count(DistinctDateTime.Time) AS CountOfTime
FROM DistinctDateTime
GROUP BY DistinctDateTime.LongDate
HAVING (((Count(DistinctDateTime.Time))<>390 And (Count(DistinctDateTime.Time))<>210));
Query DistinctDateTime
SELECT DISTINCT BAR_DATA.LongDate, BAR_DATA.Time
FROM BAR_DATA;
My problem:
I need to get Query B and Query DistinctDateTime wrapped into a single SQL statement so I can paste it into a VBA function. I presume there
is some subquery techniques, but I have failed at every attempt, and find no pertinent example.
Any help will be greatly appreciated. Thanks!
Subquery your distinct table inside and perform your aggregates outside until you get the desired result:
SELECT DistinctDateTime.LongDate, Count(DistinctDateTime.Time) AS CountOfTime
FROM
(
SELECT DISTINCT BAR_DATA.LongDate, BAR_DATA.Time
FROM BAR_DATA
) AS DistinctDateTime
GROUP BY DistinctDateTime.LongDate
HAVING (((Count(DistinctDateTime.Time))<>390 And (Count(DistinctDateTime.Time))<>210));
when I run the following query in access
SELECT SUM(RegBed) AS RegBedTOTAL, PostcodeRESULTS_PostcodeNS as postcode
FROM cooltableless10;
I get the following error:
this query does not include the specified expression 'postcode' as part of an aggregate function.
Could somebody tell me why it is so?
SUM is an aggregate function, which means that any non-aggregated columns must be included in a GROUP BY clause. Try this:
SELECT SUM(RegBed) AS RegBedTOTAL, PostcodeRESULTS_PostcodeNS as postcode
FROM cooltableless10
GROUP BY PostcodeRESULTS_PostcodeNS
you need to add a group by clause
and group it by postcode
add some like this on your query:
group by postcode
you always need to add group by clause and group your data when
using aggregate functions on your query
I ran a query against Northwind database Products Table like below
select * from Northwind.dbo.Products GROUP BY CategoryID and i was hit with a error. I am sure you will also be hit by same error. So what is the correct statement that i need to execute to group all products with respect to their category id's.
edit: this like really helped understand a lot
http://weblogs.sqlteam.com/jeffs/archive/2007/07/20/but-why-must-that-column-be-contained-in-an-aggregate.aspx
You need to use an Aggregate function and then group by any non-aggregated columns.
I recommend reading up on GROUP BY.
If you're using GROUP BY in a query, all items in your SELECT statement must either be contained as part of an aggregate function, e.g. Sum() or Count(), else they will also need to be included in the GROUP BY clause.
Because you are using SELECT *, this is equivalent to listing ALL columns in your SELECT.
Therefore, either list them all in the GROUP BY too, use aggregating functions for the rest where possible, or only select the CategoryID.
i tried using this query:
"SELECT * FROM guests WHERE event_id=".$id." GROUP BY member_id;"
and I'm getting this error:
ERROR: column "guests.id" must appear in the GROUP BY clause or be used in an aggregate function
can anyone explain how i can work around this?
You can't Group By without letting the Select know what to take, and how to group.
Try
SELECT guests.member_id FROM guests WHERE event_id=".$id." GROUP BY member_id;
IF you need to get more info from this table about the guests, you'll need to add it to the Group By.
Plus, it seems like your select should actually be
SELECT guests.id FROM guests WHERE event_id=".$id." GROUP BY id;
Each of the columns used in a group by query needs to be specifically called out (ie, don't do SELECT * FROM ...), as you need to use them in some sort of aggregate function (min/max/sum/avg/count/etc) or be part of the group by clause.
For example:
SELECT instrument, detector, min(date_obs), max(date_obs)
FROM observations
WHERE observatory='SOHO'
GROUP BY instrument, detector;