SQL OpenOffice Base "Not a Condition in Statement" - sql

So I tried using OpenOffice Base and I had a hard time. Now, I have this SQL query here and it works well:
SELECT "CUSTOMER"."CREDIT_LIMIT" AS "CREDIT_LIMIT",
COUNT(*) AS "TOTAL_NUMBER"
FROM "CUSTOMER"
WHERE "SLSREP_NUMBER" = 6
GROUP BY "CREDIT_LIMIT";
Query:
| CRED_LIMIT | TOTAL_NUMBER |
| 1500 | 1 |
| 750 | 2 |
| 1000 | 1 |
Now my problem is when I add this : AND ("TOTAL_NUMBER" > 1)
SELECT "CUSTOMER"."CREDIT_LIMIT" AS "CREDIT_LIMIT",
COUNT(*) AS "TOTAL_NUMBER"
FROM "CUSTOMER"
WHERE "SLSREP_NUMBER" = 6 AND "TOTAL_NUMBER" > 1
GROUP BY "CREDIT_LIMIT";
Open Office would throw an Error: "Not a condition in statement"
My questions are: is there something wrong with my syntax? Have I written something wrong? or is my copy of OOBase defective? or am I missing something?
Update: I tried using HAVING as suggested by potashin (Thank you for answering) and it seems like it's still not working.

#potashin was close but didn't quite have it right. Do not say AS "TOTAL_NUMBERS". Also, Base does not require quotes around UPPER case names.
SELECT CUSTOMER.CREDIT_LIMIT AS CREDIT_LIMIT, COUNT(*)
FROM CUSTOMER
WHERE SLSREP_NUMBER = 6
GROUP BY CREDIT_LIMIT
HAVING COUNT(*) > 1
See also: http://www.w3resource.com/sql/aggregate-functions/count-having.php

Related

Why does adding a SUM(column) throw a group by error [SQL]

I found some similar questions, but none of the solutions would work, nor did they explain what was causing the issue.
I have a working query
SELECT pages.pageString pageName, timeSpent
FROM
(SELECT `page_id`, SUM(`time_spent`) as timeSpent
FROM `pageViews`
WHERE `time_spent` > 0
GROUP BY `page_id`) myTable
JOIN pages ON pages.id = page_id
ORDER BY timeSpent DESC
LIMIT 5
This returns results that look like
+------------------------------+-----------+
| pageName | timeSpent |
+------------------------------+-----------+
| page 1 | 394292 |
| page 2 | 66990 |
| page 3 | 53896 |
| page 4 | 37796 |
| page 5 | 14982 |
+------------------------------+-----------+
I'd like to add a column containing the percentage of timeSpent relative to the other pages, to start I added a SUM(timeSpent) to my query but that throws an error
In aggregated query without GROUP BY, expression #1 of SELECT list contains nonaggregated column 'pages.pageString'
Im not sure why this column is effected by adding this new column to the select statement.
Sadly any solution involving changing sql settings won't work due to company policy.
I appreciate any advice
UPDATE
The failing sql statement is
SELECT pages.pageString pageName, timeSpent FROM
(SELECT `page_id`, SUM(`time_spent`) as timeSpent FROM
`pageViews` WHERE `time_spent` > 0 GROUP BY `page_id`) myTable
JOIN pages ON pages.id = page_id ORDER BY timeSpent DESC LIMIT 5
As per the first answer I added a groupBy which solves the error
SELECT pages.pageString pageName, timeSpent, SUM(timeSpent) FROM
(SELECT `page_id`, SUM(`time_spent`) as timeSpent FROM `pageViews` WHERE `time_spent` > 0 GROUP BY `page_id`) myTable
JOIN pages ON pages.id = page_id GROUP BY pageName ORDER BY timeSpent DESC LIMIT 5
This however does not give the proper output
+------------------------------+-----------+----------------+
| pageName | timeSpent | SUM(timeSpent) |
+------------------------------+-----------+----------------+
| page 1. | 390210 | 390210 |
| page 2 | 66972 | 66972 |
| page3 | 52332 | 52332 |
| page4 | 25454 | 25454 |
| page5 | 13552 | 13552 |
+------------------------------+-----------+----------------+
Ideally this SUM(timeSpent) would be 390210+ 66972 + 52332 + 25454 + 13552 so that I may do timeSpent / SUM(timeSpent)
You did not say where you tried to put the sum(timeSpent) but I believe one can try to reconstruct with the error message:
In aggregated query without GROUP BY, expression #1 of SELECT list contains nonaggregated column 'pages.pageString'
It says what the problem is. You added sum(timeSpent) to the projection, but the SQL statement does not have a GROUP BY, in particular it mentions the first item which should be aggregated pages.pageString.
It would mention the other ones too, once you fix this one.
On the other hand, please make sure you post exactly the failing SQL statement instead of trying to describe how to get the error you have. It's better for us who try to help.
Update:
You have two tables/views pages and pageViews. The first one is used to get the page name. I would just focus on the time calculation to make things easier. Figuring out the name afterwards is simple, because it is directly connected to the page_id.
The first information you want is the sum of all times spent so that you can calculate the ratio to this sum.
This is simply an aggregation where you sum the times over all pages.
The second information you want is the sum of the times per page_id. You already know how to do that. You group by the page_id while aggregating the sums of each.
Try to put those two together now. You have the first statement of which the result shall be applied to each row of the second statement so that you get the table form page_id, time_spent_page, time_spent_all.
When you have step 3 then it is easy to add the page_name now, since you have the page_id which is required for a simple join.
I tried no to give away the solution. Maybe you like to try again following the steps above. If you have difficulties, simply leave a comment (maybe showing how far you got).
It might look complex in the beginning, but once you have done that successfully I hope you'll see that it can be simple.
Adding a column containing the percentage of timeSpent relative to the sum of all pages
SELECT pages.pageString pageName, timeSpent,
, timeSpent / sum(timeSpent) over() * 100 p
FROM
(SELECT `page_id`, SUM(`time_spent`) as timeSpent
FROM `pageViews`
WHERE `time_spent` > 0
GROUP BY `page_id`) myTable
JOIN pages ON pages.id = page_id
ORDER BY timeSpent DESC
LIMIT 5

SQL multipart messages in two tables. Doesn't work if second table is empty

I am working on a query that will fetch multipart messages from 2 tables. However, it only works IF there are multiple parts. If there is only a one part message then the the join condition won't be true anymore. How could I make it to work for both single and multipart messages?
Right now it fails if there is an entry in outbox and nothing in outbox_multipart.
My first table is "outbox" that looks like this.
TextDecoded | ID | CreatorID
Helllo, m.. | 123 | Martin
Yes, I wi.. | 124 | Martin
My second table is "outbox_multipart" that looks very similar.
TextDecoded | ID | SequencePosition
my name i.. | 123 | 2
s Martin. | 123 | 3
ll do tha.. | 124 | 2
t tomorrow. | 124 | 3
My query so far
SELECT
CONCAT(ob.TextDecoded,
GROUP_CONCAT(obm.TextDecoded
ORDER BY obm.SequencePosition ASC
SEPARATOR ''
)
) AS TextDecoded,
ob.ID,
ob.creatorID
FROM outbox AS ob
JOIN outbox_multipart AS obm ON obm.ID = ob.ID
GROUP BY
ob.ID,
ob.creatorID
Use a left join instead of an (implicit) inner join. Then, also use COALESCE on the TextDecoded alias to make sure that empty string (and not NULL) appears in the expected output.
SELECT
CONCAT(ob.TextDecoded,
COALESCE(GROUP_CONCAT(obm.TextDecoded
ORDER BY obm.SequencePosition
SEPARATOR ''), '')) AS TextDecoded,
ob.ID,
ob.creatorID
FROM outbox AS ob
LEFT JOIN outbox_multipart AS obm
ON obm.ID = ob.ID
GROUP BY
ob.ID,
ob.creatorID,
ob.TextDecoded;
Note: Strictly speaking, outbox.TextDecoded should also appear in the GROUP BY clause, since it is not an aggregate. I have made this change in the query.

SQL WHERE Clause not filtering to criteria MS-Access

I have written a query to gather the balances of two different days, find the percent difference and then display them. I added a Percent Filter section to my form to show only values that are >= the desired percentage.
When running the query, I get the results that are >= percent given. However, after the criteria is met, the results expand past and continue until 0, as if ignoring my WHERE clause. Is there something I'm not catching within my query?
Query being used:
SELECT [x].[ID], [x].[Name], [x].[Day1Date], [x].[Day1Bal], [x].[Day2Date], [x].[Day2Bal], [x].[Difference], IIf(([Day2Bal]>[Day1Bal]),((([Day2Bal]-[Day1Bal])/[Day1Bal])*100),(((([Day2Bal]-[Day1Bal])/[Day1Bal])*-1)*100)) AS PerDiff
FROM qryUnion AS x
WHERE IIf(([Day2Bal]>[Day1Bal]),((([Day2Bal]-[Day1Bal])/[Day1Bal])*100),(((([Day2Bal]-[Day1Bal])/[Day1Bal])*-1)*100)) > [Forms]![Compare]![txtPercent]
ORDER BY IIf(([Day2Bal]>[Day1Bal]),((([Day2Bal]-[Day1Bal])/[Day1Bal])*100),(((([Day2Bal]-[Day1Bal])/[Day1Bal])*-1)*100)) DESC
I have edited and re-written my IIf statement countless times but it still doesn't filter to criteria properly.
Results (Filtered for >= 10%) :
+----------+
| PerDiff |
+----------+
| 985.256 |
| 457.25 |
| 369.54 |
| 245.21 |
| 141.14 |
| 68.23 |
| 28.54 |
| 10.21454 |
| 10.1212 | <------- Criteria met
| 9.555 |
| 8.42 |
| 2.12 |
| 0.42 | <------- Ends at 0
+----------+
Obviously I'm wanting it to end at where the criteria is met, and I believe I've written my where clause to do so. I'm uncertain where else might be messing up.
qryUnion was a SubQuery but I had written just to get Dates and DateBals.
Any help is greatly appreciate! I'm still a bit new to SQL (and VBA for that matter). Thanks in advance!
EDIT1:
I have also tried
WHERE IIf(([Day2Bal]>[Day1Bal]),((([Day2Bal]-[Day1Bal])/[Day1Bal])*100),(((([Day2Bal]-[Day1Bal])/[Day1Bal])*-1)*100)) >= [Forms]![Compare]![txtPercent] _
AND NOT IIf(([Day2Bal]>[Day1Bal]),((([Day2Bal]-[Day1Bal])/[Day1Bal])*100),(((([Day2Bal]-[Day1Bal])/[Day1Bal])*-1)*100)) < [Forms]![Compare]![txtPercent]
As to not show any data that is less than the given percentage. This line didn't work. Is it possible that my WHERE clause isn't the issue? I'm uncertain where else the issue may lie.
*A better answer may exist, but this will accomplish your goal also:
You can create a subquery for PerDiff field before writing the final query:
SELECT [x].[ID], [x].[Name], [x].[Day1Date], [x].[Day1Bal], [x].[Day2Date], [x].[Day2Bal], [x].[Difference], IIf(([Day2Bal]>[Day1Bal]),((([Day2Bal]-[Day1Bal])/[Day1Bal])*100),(((([Day2Bal]-[Day1Bal])/[Day1Bal])*-1)*100)) AS PerDiff
FROM qryUnion AS x
Creating this subquery will then give you the results of the iff statement in your select clause that can then be used in the next query. So your final query could then use the Where clause like this:
WHERE PerDiff > [Forms]![Compare]![txtPercent]
ORDER BY PerDiff DESC
After a ton of trouble shooting, it seems my issue was the * 100 within my IIf statement.
SQL that worked:
SELECT [x].[DDANbr], [x].[Name], [x].[Day1Date], [x].[Day1Bal], [x].[Day2Date], [x].[Day2Bal], [x].[Difference], IIf(([Day2Bal]>[Day1Bal]),((([Day2Bal]-[Day1Bal])/[Day1Bal])),(((([Day2Bal]-[Day1Bal])/[Day1Bal])*-1))) AS PerDiff
FROM qry250CapAllCompare_Union AS x
--Added /100 at the end of WHERE clause to ensure that I was getting 10% because math
WHERE IIf(([Day2Bal]>[Day1Bal]),((([Day2Bal]-[Day1Bal])/[Day1Bal])),(((([Day2Bal]-[Day1Bal])/[Day1Bal])*-1)))>=Forms!frmCompare!txtPercent/100
ORDER BY IIf(([Day2Bal]>[Day1Bal]),((([Day2Bal]-[Day1Bal])/[Day1Bal])),(((([Day2Bal]-[Day1Bal])/[Day1Bal])*-1))) DESC

SQL: SUM of MAX values WHERE date1 <= date2 returns "wrong" results

Hi stackoverflow users
I'm having a bit of a problem trying to combine SUM, MAX and WHERE in one query and after an intense Google search (my search engine skills usually don't fail me) you are my last hope to understand and fix the following issue.
My goal is to count people in a certain period of time and because a person can visit more than once in said period, I'm using MAX. Due to the fact that I'm defining people as male (m) or female (f) using a string (for statistic purposes), CHAR_LENGTH returns the numbers I'm in need of.
SELECT SUM(max_pers) AS "People"
FROM (
SELECT "guests"."id", MAX(CHAR_LENGTH("guests"."gender")) AS "max_pers"
FROM "guests"
GROUP BY "guests"."id")
So far, so good. But now, as stated before, I'd like to only count the guests which visited in a certain time interval (for statistic purposes as well).
SELECT "statistic"."id", SUM(max_pers) AS "People"
FROM (
SELECT "guests"."id", MAX(CHAR_LENGTH("guests"."gender")) AS "max_pers"
FROM "guests"
GROUP BY "guests"."id"),
"statistic", "guests"
WHERE ( "guests"."arrival" <= "statistic"."from" AND "guests"."departure" >= "statistic"."to")
GROUP BY "statistic"."id"
This query returns the following, x = desired result:
x * (x+1)
So if the result should be 3, it's 12. If it should be 5, it's 30 etc.
I probably could solve this algebraic but I'd rather understand what I'm doing wrong and learn from it.
Thanks in advance and I'm certainly going to answer all further questions.
PS: I'm using LibreOffice Base.
EDIT: An example
guests table:
ID | arrival | departure | gender |
10 | 1.1.14 | 10.1.14 | mf |
10 | 15.1.14 | 17.1.14 | m |
11 | 5.1.14 | 6.1.14 | m |
12 | 10.2.14 | 24.2.14 | f |
13 | 27.2.14 | 28.2.14 | mmmmmf |
statistic table:
ID | from | to | name |
1 | 1.1.14 | 31.1.14 |January | expected result: 3
2 | 1.2.14 | 28.2.14 |February| expected result: 7
MAX(...) is the wrong function: You want COUNT(DISTINCT ...).
Add proper join syntax, simplify (and remove unnecessary quotes) and this should work:
SELECT s.id, COUNT(DISTINCT g.id) AS People
FROM statistic s
LEFT JOIN guests g ON g.arrival <= s."from" AND g.departure >= s."too"
GROUP BY s.id
Note: Using LEFT join means you'll get a result of zero for statistics ids that have no guests. If you would rather no row at all, remove the LEFT keyword.
You have a very strange data structure. In any case, I think you want:
SELECT s.id, sum(numpersons) AS People
FROM (select g.id, max(char_length(g.gender)) as numpersons
from guests g join
statistic s
on g.arrival <= s."from" AND g.departure >= s."too"
group by g.id
) g join
GROUP BY s.id;
Thanks for all your inputs. I wasn't familiar with JOIN but it was necessary to solve my problem.
Since my databank is designed in german, I made quite the big mistake while translating it and I'm sorry if this caused confusion.
Selecting guests.id and later on grouping by guests.id wouldn't make any sense since the id is unique. What I actually wanted to do is select and group the guests.adr_id which links a visiting guest to an adress databank.
The correct solution to my problem is the following code:
SELECT statname, SUM (numpers) FROM (
SELECT statistic.name AS statname, guests.adr_id, MAX( CHAR_LENGTH( guests.gender ) ) AS numpers
FROM guests
JOIN statistics ON (guests.arrival <= statistics.too AND guests.departure >= statistics.from )
GROUP BY guests.adr_id, statistic.name )
GROUP BY statname
I also noted that my database structure is a mess but I created it learning by doing and haven't found any time to rewrite it yet. Next time posting, I'll try better.

MYSQL - Combining Two Results in One Query

I have a query I need to perform to show search results for a project. What needs to happen, I need to sort the results by the "horsesActiveDate" and this applies to all of them except for any ad with the adtypesID=7. Those results are sorted by date but they must always result after all other ads.
So I will have all my ads in the result set be ordered by the Active Date AND adtypesID != 7. After that, I need all adtypesID=7 to be sorted by Active Date and appended at the bottom of all the results.
I'm hoping to put this in one query instead of two and appending them together in PHP. The way the code is written, I have to find a way to get it all in one query.
So here is my original query which has worked great until I had to ad the adtypesID=7 which has different sorting requirements.
This is the query that exists now that doesn't take into account the adtypesID for sorting.
SELECT
horses.horsesID,
horsesDescription,
horsesActiveDate,
adtypesID,
states.statesName,
horses_images.himagesPath
FROM horses
LEFT JOIN states ON horses.statesID = states.statesID
LEFT JOIN horses_images ON horses_images.himagesDefault = 1 AND horses_images.horsesID = horses.horsesID AND horses_images.himagesPath != ''
WHERE
horses.horsesStud = 0
AND horses.horsesSold = 0
AND horses.horsesID IN
(
SELECT DISTINCT horses.horsesID
FROM horses
LEFT JOIN horses_featured ON horses_featured.horsesID = horses.horsesID
WHERE horses.horsesActive = 1
)
ORDER BY adtypesID, horses.horsesActiveDate DESC
My first thought was to do two queries where one looked for all the ads that did not contain adtypesID=7 and sort those as the query does, then run a second query to find only those ads with adtypesID=7 and sort those by date. Then take those two results and append them to each other. Since I need to get this all into one query, I can't use a php function to do that.
Is there a way to merge the two query results one after the other in mysql? Is there a better way to run this query that will accomplish this sorting?
The Ideal Results would be as below (I modified the column names so they would be shorter):
ID | Description | ActiveDate | adtypesID | statesName | himagesPath
___________________________________________________________________________
3 | Ad Text | 06-01-2010 | 3 | OK | image.jpg
2 | Ad Text | 05-31-2010 | 2 | LA | image1.jpg
9 | Ad Text | 03-01-2010 | 4 | OK | image3.jpg
6 | Ad Text | 06-01-2010 | 7 | OK | image5.jpg
6 | Ad Text | 05-01-2010 | 7 | OK | image5.jpg
6 | Ad Text | 04-01-2010 | 7 | OK | image5.jpg
Any help that can be provided will be greatly appreciated!
I am not sure about the exact syntax in MySQL, but something like
ORDER BY case when adtypesID = 7 then 2 else 1 end ASC, horses.horsesActiveDate DESC
would work in many other SQL dielects.
Note that most SQL dialects allow the order by to not only be a column, but an expression.
This should work:
ORDER BY (adtypesID = 7) ASC, horses.horsesActiveDate DESC
Use a Union to append two queries together, like this:
SELECT whatever FROM wherever ORDER BY something AND adtypesID!=7
UNION
SELECT another FROM somewhere ORDER BY whocares AND adtypesID=7
http://dev.mysql.com/doc/refman/5.0/en/union.html
I re-wrote your query as:
SELECT h.horsesID,
h.horsesDescription,
h.horsesActiveDate,
adtypesID,
s.statesName,
hi.himagesPath
FROM HORSES h
LEFT JOIN STATES s ON s.stateid = h.statesID
LEFT JOIN HORSES_IMAGES hi ON hi.horsesID = h.horsesID
AND hi.himagesDefault = 1
AND hi.himagesPath != ''
LEFT JOIN HORSES_FEATURED hf ON hf.horsesID = h.horsesID
WHERE h.horsesStud = 0
AND h.horsesSold = 0
AND h.horsesActive = 1
ORDER BY (adtypesID = 7) ASC, h.horsesActiveDate DESC
The IN subquery, using a LEFT JOIN and such, will mean that any horse record whose horsesActive value is 1 will be returned - regardless if they have an associated HORSES_FEATURED record. I leave it to you for checking your data to decide if it should really be an INNER JOIN. Likewise for the STATES table relationship...