Google sheets query order by SUM - google-sheets-query

I am trying to do this query:
=query(indirect($B$1), "select D, E, F, SUM(H) group by D,E,F pivot G order by SUM(H)",1)
It looks OK, but results in an error:
Unable to parse query string for Function QUERY parameter 2: NO_AGG_IN_ORDER_WHEN_PIVOT: H
If I try
=query(indirect($B$1), "select D, E, F, SUM(H) group by D,E,F pivot G order by H",1) the I get:
Unable to parse query string for Function QUERY parameter 2:
COL_IN_ORDER_MUST_BE_IN_SELECT: H
=query(indirect($B$1), "select D, E, F, SUM(H) group by D,E,F pivot G order by D",1) works OK.
How to order by SUM(H)?
Any idea how to order by SUM(H) for specific value of G (like in Pivot table in google sheets)?

You can't use ORDER BY and PIVOT at the same time. But you can use 2 query nested functions. In the first one using PIVOT and the second one with the ORDER BY.
Remmember that in the second query you must use de Col1, Col2, ... notation:
=query(query(indirect($B$1)
, "select D, E, F, SUM(H)
group by D, E, F
pivot G"
, 1)
, "select *
ORDER BY Col4"
, 1)

Related

Using an ALIAS in an INNER JOIN query?

I think the title explain very well my issue, I looked at a lot of subject in forum and else about this but I am still stuck. I don't really understand how to do it, and maybe someone here will be able to make me understand. (I hope)
My query is here:
SELECT Name, A, B, C, D, E, F
FROM Data
INNER JOIN User_Access ON Data.Name = User_Access.Name
WHERE User_Access.Channel = 'TEST'
I know that I have to use an alias for "Name" but I can not do it.
For now, I think my best almost-answer to my issue is this :
SELECT Name AS N, A, B, C, D, E, F
FROM Data
INNER JOIN User_Access ON Data.N = User_Access.Name
WHERE User_Access.Channel = 'TEST'
But it's not working and I have an invalid name error.
Thank's in advance for your help !
SELECT User_Access.Name, A, B, C, D, E, F
FROM Data
INNER JOIN User_Access ON Data.N = User_Access.Name
WHERE User_Access.Channel = 'TEST'
I have replaced the Name (as is key word) with User_Access.Name (changing the column name that is appending with the actual table's name).
Where a column name is common between n tables you need to qualify it so that sql knows which one you mean.This will work
SELECT data.Name, A, B, C, D, E, F
FROM Data
INNER JOIN User_Access ON Data.Name = User_Access.Name
WHERE User_Access.Channel = 'TEST'
as will
SELECT d.Name, A, B, C, D, E, F
FROM Data d
INNER JOIN User_Access ON d.Name = User_Access.Name
WHERE User_Access.Channel = 'TEST'
From Logical Processing Order of the SELECT statement:
The following steps show the logical processing order, or binding
order, for a SELECT statement. This order determines when the objects
defined in one step are made available to the clauses in subsequent
steps. For example, if the query processor can bind to (access) the
tables or views defined in the FROM clause, these objects and their
columns are made available to all subsequent steps. Conversely,
because the SELECT clause is step 8, any column aliases or derived
columns defined in that clause cannot be referenced by preceding
clauses. However, they can be referenced by subsequent clauses such as
the ORDER BY clause. The actual physical execution of the statement is
determined by the query processor and the order may vary from this
list.
FROM
ON
JOIN
WHERE
GROUP BY
WITH CUBE or WITH ROLLUP
HAVING
SELECT
DISTINCT
ORDER BY
TOP
Notice that the SELECT is in position 8, where as JOIN and ON are in positions 3 and 2 respectively. Therefore you cannot reference a column by it's alias defined in the SELECT in the ON; as the SELECT hasn't been processed yet. Effectively, the only place you can reference a column by it's alias (in the same scope) is in the ORDER BY.
If you really wanted to to this, you could use as CROSS APPLY and VALUES operator, but (honestly) you wanting to type N instead of Name in the ON is more laziness:
SELECT V.N, D.A, D.B, D.C, D.D, D.E, D.F --I assume there are all from the Data table
FROM Data D
CROSS APPLY (VALUES(D.[Name])) V(N)
INNER JOIN User_Access UA ON V.N = UA.Name
WHERE UA.Channel = 'TEST';
Name is a reserved word, you need to enclose that in square bracket
SELECT [Name], A, B, C, D, E, F
FROM Data
INNER JOIN User_Access ON Data.N = User_Access.Name
WHERE User_Access.Channel = 'TEST'

Multiple SELECT statements in MySQL Query

If I have the schemas:
Type(a,b,c,d)
Name(e, b, g)
I am trying to find all the resulting Name's 'E' where the 'D' of the Type is greater than a number that we access using the shared 'B'.
I am trying to understand how to have multiple SELECT statements such as:
SELECT e FROM Name WHERE b = (SELECT b FROM Type WHERE d > 1);
Can someone explain the syntax error and how to do nested SELECT statements or do I have to join the two tables.
Thanks
This can be accomplished using a simple INNER JOIN operation:
SELECT DISTINCT n.e
FROM Name AS n
INNER JOIN Type AS t ON n.b = t.b
WHERE t.d > 1
You can also use EXISTS:
SELECT n.e
FROM Name AS n
WHERE EXISTS (SELECT 1
FROM Type AS t
WHERE n.b = t.b AND t.d > 1)
I think you want to use IN instead of =
SELECT e FROM Name WHERE b IN (SELECT b FROM Type WHERE d > 1);
= to compare one value to another value.
IN to see if a value exist whiten a list of multiple values.

Correlated value from min query

I'm trying to get the correlated value in a table from a mysql query which looks like:
select min(c), d
from example
table example looks like:
c | d
----------------
'1,99', '30,99'
'5,99', '8,46'
'9,99', '14,99'
'11,79', '17,24'
'12,99', '19,44'
'15,99', '22,44'
'22,49', '34,48'
Given result:
1,99 & 34,48
Expected result:
1,99 & 30,99
What I want is the correlated value from the min(c) in this case '30,99'. How to do that?
You can do it with a sub query:
SELECT * FROM example
WHERE c = (SELECT min(c) from example)
EDIT: if there's more then 1 records the answer the condition, then you need to decide which one you wanna pick.
SELECT * FROM example
WHERE c = (SELECT min(c) from example)
ORDER BY d
LIMIT 1
This will take the one with the smallest d value.
To take the biggest, add DESC after the order by d in the query.
You need to use subquery:
select e.*
from (select min(c) as c from example) x
join example e
on x.c = e.c;

Calculated column in where-clause - performance

Since you can't use a calculated column in a where-clause in MySQL like this:
SELECT a,b,c,(a*b+c) AS d FROM table
WHERE d > n
ORDER by d
you have to use
SELECT a,b,c,(a*b+c) AS d FROM table
WHERE (a*b+c) > n
ORDER by d
Is the calculation (in that example "(a*b+c)" executed once per row or twice? Is there a way to make it faster? I find it strange it's possible to ORDER on the column but not to have a WHERE-clause.
You can use HAVING to filter on a computed column:
SELECT a,b,c,(a*b+c) AS d, n FROM table
HAVING d > n
ORDER by d
Note that you need to include n in the SELECT clause for this to work.
You could do this:
SELECT a,b,c,d FROM
(SELECT a,b,c,(a*b+c) AS d) AS tmp
WHERE d > n
ORDER BY d
But I am not sure what performance implications it could have.

MS Access query does not append any rows as an append query, but does select rows as a select query

I am getting really strange behavior in access with an append query.
When I try to run it, Access says that the query will append 0 rows, but does not give any error messages (saying some rows can't be appended).
I get the same behavior (append 0 rows) when I do a make table query (instead of an append/insert into), so I know it is not probably not a table mismatch in the destination table
When I run the same logic as a select query or open the apend query in datasheet view, I get ~1000 (correct) rows, so I know that my select logic is not wrong.
I checked all the indexes/requirements in the destination table, as suggested here
MS Access 2007 Append query trouble, but, again, I also get this error with a make table query. So I think something else is going on.
I am the only one using the database file
I've compacted and repaired the file
I'm very confused about how to go about debugging this further. Any suggestions? (I changed the field names to post...)
INSERT INTO [X] ( a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t)
SELECT a, b, c, d, e, f, g, h, i, j, k, l, m, n, o & p as expres, q, r, s, t, u
FROM AA INNER JOIN BB ON AA.id = BB.id;
Edit
The query works with three fields, but not with any more.
The first 2 work
INSERT INTO CC (a, b)
SELECT a, b
FROM AA INNER JOIN BB ON AA.id = BB.id;
WHERE (textField='-1'));
INSERT INTO CC (a, c)
SELECT a, c
FROM AA INNER JOIN BB ON AA.id = BB.id;
WHERE (textField='-1'));
But this does not
INSERT INTO CC (a, b, c)
SELECT a, b, c
FROM AA INNER JOIN BB ON AA.id = BB.id;
WHERE (textField='-1'));