Issues when using HSQL and WHERE statement - hsqldb

I have an issue when using a WHERE statement in HSQL. When I enter the code as follows I get no errors:
"SELECT Year, ProjectName, (cast(sum(Missed) as float)/(select cast(sum(d.Missed) as float) from Draft d)) as MissedPer from Draft group by ProjectName, Year order by ProjectName"
However, when I add a WHERE statement inside the nested query I get an error:
"SELECT Year, ProjectName, (cast(sum(Missed) as float)/(select cast(sum(d.Missed) as float) from Draft d where Year = '19.12')) as MissedPer from Draft group by ProjectName, Year order by ProjectName"
The error is the following:
Exception in thread "main" java.sql.SQLSyntaxErrorException: expression not in aggregate or GROUP BY columns: CAST(( SUM(PUBLIC.DRAFT.MISSED)) AS DOUBLE)/(()) in statement [SELECT BranchNo, ProjectName, (cast(sum(Missed) as float)/(select cast(sum(d.Missed) as float) from Draft d where d.BranchNo = '19.12')) as MissedPer from Draft group by ProjectName, BranchNo order by ProjectName]
I don't know how to make this work, please help.

I checked with HSQLDB version 2.5.1 and the query returns a result:
create table draft (year varchar(10), projectname varchar (10), missed int);
insert into draft values '19.10', 'p alpha', 10
insert into draft values '19.11', 'p alpha', 12
insert into draft values '19.12', 'p alpha', 3
YEAR PROJECTNAME MISSEDPER
----- ----------- ------------------
19.10 p alpha 3.3333333333333335
19.11 p alpha 4.0
19.12 p alpha 1.0

Related

Which invoices are greater than $300, that have been paid prior to 7/15/2008 and are either TermsID 2 or 3

I got this far from my homework question, but I am little confused how the code will work for paid prior for date and termsID 2 or 3?
Write a SELECT statement that returns VendorID, InvoiceNumber, InvoiceDate, InvoiceTotal, TermsID and PaymentDate that answers the following question: Which invoices are greater than $300, that have been paid prior to 7/15/2008 and are either TermsID 2 or 3? (18 records will be returned)
Select VendorID, invoiceNumber, InvoiceDate, InvoiceTotal, TermsID, PaymentDate
From invoices
Where invoices > 300 and
Here are some pointers:
If your column for paid date is (as it should be) a date, you can structure a predicate that looks for things before a date using the < operator jsut as you would with a number. Later dates are greater:
--find all people born before 1970 jan 01
SELECT * FROM person WHERE birthdate < '1970-01-01'
Pass your date for comparison as a string (surrounded by ') in yyyy-MM-dd format. The db will convert the string to a date and run the comparison numerically
Use the IN operator when you want to look for a column being in a set of terms:
SELECT * FROM person WHERE jobrole IN ('manager', 'developer', 'support')
SELECT * FROM creature WHERE numberoflegs IN (2,4,6)
IN works like:
SELECT * FROM creature WHERE numberoflegs =2 OR numberoflegs = 4 OR numberoflegs = 6
Always, always include brackets when mixing AND and OR, to make it clear to the DB and to other people reading your code, what is to be combined in which way
--for this...
SELECT * FROM person WHERE name = 'john' and age = 32 or city = 'paris'
--which of these is it? very different things!
SELECT * FROM person WHERE (name = 'john' and age = 32) or city = 'paris'
SELECT * FROM person WHERE name = 'john' and (age = 32 or city = 'paris')

Problems with Joining Pivot Table

I am trying to join two tables one containing Dept codes another a pivot table but each time I try to join the table it throws me the following error:
An expression of non-boolean type specified in a context where a condition is expected, near 'D'. Is there a better way of doing this or have I overlooked an error. ?
I've tried various different joins but it all throws me the same error
SELECT D.Dept_Code, D.Department, S.Amount AS 'Total Amount' FROM DEPARTMENT AS D JOIN(
SELECT DEPT, (ISNULL([63121],0) +ISNULL([63122],0)+ ISNULL([63123],0)+ISNULL([63124],0)+ISNULL([63125],0)+ISNULL([63126],0)+ISNULL([63129],0)) AS 'Amount', (ISNULL([63131],0) + ISNULL([63139], 0)) AS '63130', ISNULL([63141], 0) AS '63141', ISNULL([63143],0) AS '63143', ISNULL([63144], 0) AS '63144', ISNULL([63145],0) AS '63145', ISNULL([63146],0) AS '63146', ISNULL([63149], 0) AS '632149'
FROM(SELECT DEPT, NATURE, SUM(CAST(Amount AS FLOAT)) AS AMOUNT FROM MFG_EXP_1 GROUP BY DEPT, NATURE) AS S
PIVOT
(
SUM(AMOUNT)
FOR NATURE IN ([63121], [63122], [63123], [63124], [63125], [63126], [63129], [63131], [63139], [63141], [63142], [63143], [63144], [63145], [63146], [63149])
) NATURE_CODE_BREAKDOWN) AS G ON D D.Dept = G.DEPT;
I try to join the table it throws me the following error:
An expression of non-boolean type specified in a context where a condition is expected, near 'D'
The Department table:
Dept_Code Dept Department
100 110 merchandsing
100 120 operations
the MFG_EXP 1 Table
Dept Nature Amount
110 1000 $200
120 2000 $300
`````````````````
When I Pivot the MFG_EXP_1 Table by the Nature codes I have the newly formed SourceTable Below:
`````````````````
Dept 1000 2000
110 $200.00 $0.00
120 $0.00 $300.00
I now want to join my SourceTable with my Department Table to have This as my final result
Dept Department 1000 2000
100 merchandise $200.00 $0.00
100 Operations $0.00 $300.00
I see a syntax problem at the end of your SQL statement:
D D.Dept = G.DEPT;
But in general if you use CTE and put your pivot table as CTE expression, you can simplify your SQL statement and easily test each separately.
Like this:
;USING myPivot AS (
-- just copied your statement here
SELECT DEPT, (ISNULL([63121],0) +ISNULL([63122],0)+ ISNULL([63123],0)+ISNULL([63124],0)+ISNULL([63125],0)+ISNULL([63126],0)+ISNULL([63129],0)) AS 'Amount', (ISNULL([63131],0) + ISNULL([63139], 0)) AS '63130', ISNULL([63141], 0) AS '63141', ISNULL([63143],0) AS '63143', ISNULL([63144], 0) AS '63144', ISNULL([63145],0) AS '63145', ISNULL([63146],0) AS '63146', ISNULL([63149], 0) AS '632149'
FROM(SELECT DEPT, NATURE, SUM(CAST(Amount AS FLOAT)) AS AMOUNT FROM MFG_EXP_1 GROUP BY DEPT, NATURE) AS S
PIVOT
(
SUM(AMOUNT)
FOR NATURE IN ([63121], [63122], [63123], [63124], [63125], [63126], [63129], [63131], [63139], [63141], [63142], [63143], [63144], [63145], [63146], [63149])
)
)
SELECT D.Dept_Code, D.Department, S.Amount AS 'Total Amount' FROM DEPARTMENT AS D
JOIN myPivot D ON D.Dept = G.DEPT
Here's a stab at fixing your query but not having anything to test it against it might still have some problem:
SELECT
D.Dept_Code,
D.Department,
S.Amount AS TotalAmount
FROM
DEPARTMENT AS D
INNER JOIN
(
SELECT
DEPT,
(ISNULL([63121],0) +ISNULL([63122],0)+ ISNULL([63123],0)+ISNULL([63124],0)+ISNULL([63125],0)+ISNULL([63126],0)+ISNULL([63129],0)) AS [Amount],
(ISNULL([63131],0) + ISNULL([63139], 0)) AS [63130],
ISNULL([63141], 0) AS [63141],
ISNULL([63143],0) AS [63143],
ISNULL([63144], 0) AS [63144],
ISNULL([63145],0) AS [63145],
ISNULL([63146],0) AS [63146],
ISNULL([63149], 0) AS [632149]
FROM
(
SELECT DEPT, NATURE, SUM(CAST(Amount AS FLOAT)) AS AMOUNT
FROM MFG_EXP_1
GROUP BY DEPT, NATURE
) AS S
PIVOT
(
SUM(AMOUNT)
FOR NATURE IN ([63121], [63122], [63123], [63124], [63125], [63126], [63129], [63131], [63139], [63141], [63142], [63143], [63144], [63145], [63146], [63149])
) NATURE_CODE_BREAKDOWN
) AS G ON D.Dept = G.DEPT;

ORACLE SQL select max(count()) to year

I have database of library and i am trying to assign most borrowed title to each year like
2015 - The Great Gatsby
2014 - Da vinci code
2013 - Harry Potter
....
I've tried this but i am not sure about it
select to_char(borrow_date,'YYYY'),title_name
from k_title
join k_book
using(title_id)
join k_rent_books
using(book_id)
group by to_char(borrow_date,'YYYY'),title_name
having count(title_id) = (
select max(cnt) FROM(select count(title_name) as cnt
from k_title
join k_book
using(title_id)
join k_rent_books
using(book_id)
group by title_id,title_name,to_char(borrow_date,'YYYY')));
I've got only 3 results
2016 - Shogun
2006 - The Revolt of Mamie Stover
1996 - The Great Gatsby
I will be happy for any help :)
Oracle has the nice capability to get the first or last value in an aggregation (as opposed to the min() or max()). This requires using something called keep.
So, the way to express what you want to do is:
select yyyy,
max(title_name) keep (dense_rank first order by cnt desc) as title_name
from (select to_char(borrow_date, 'YYYY') as yyyy,
title_name, count(*) as cnt
from k_title t join
k_book b
using (title_id) join
k_rent_books
using (book_id)
group by to_char(borrow_date, 'YYYY'), title_name
) yt
group by yyyy;
Your query is returning the year/title combinations that have the overall maximum count over all years, not the maximum per year.

SQL 2008 VS 2012 Error: Incorrect syntax near the keyword 'COMPUTE'

My friend sent me the commands that he wrote in server 2008 and they worked with no problems, mine however from a copy and past did not work with 2012. Is there any reason why? Here is the code:
Use Kudler_Database
SELECT AccountNumber, [Description], ShortDescription,Balance
FROM Chart_of_Accounts
ORDER BY left (AccountNumber, 2)
COMPUTE SUM(Balance) BY left (AccountNumber, 2)
COMPUTE SUM(Balance);
Here is the error :
Msg 156, Level 15, State 1, Line 6 Incorrect syntax near the keyword
'COMPUTE'.
COMPUTE is no longer available in SQL server 2012, thats why you are getting that error. See this page:
Discontinued Database Engine Functionality in SQL Server 2012
It said that:
This topic describes the Database Engine features that are no longer
available in SQL Server 2012:
*Transact-SQL syntax | COMPUTE / COMPUTE BY *
A kind of hack with RollUp since Compute By is deprecated in SQL Server 2012 - (see "SQL SERVER – Use ROLL UP Clause instead of COMPUTE BY")
DECLARE #t TABLE(AccountNumber VARCHAR(10),[Description] VARCHAR(100),ShortDescription VARCHAR(100),Balance INT)
INSERT INTO #t SELECT '1234567890','Some Description for 1st Account','Short Description for 1st Account',2000 Union All
SELECT '2345678901','Some Description for 2nd Account','Short Description for 2nd Account',3000 Union All
SELECT '1234567890','Some Description for 1st Account','Short Description for 1st Account',4000
SELECT
AccountNumber
,Balance
,Total = SUM(Balance)
FROM #t
GROUP BY AccountNumber,Balance
WITH ROLLUP
Result
AccountNumber Balance total
1234567890 2000 2000
1234567890 4000 4000
1234567890 NULL 6000
2345678901 3000 3000
2345678901 NULL 3000
NULL NULL 9000
OR
you can use the below
DECLARE #t TABLE(AccountNumber VARCHAR(10),[Description] VARCHAR(100),ShortDescription VARCHAR(100),Balance INT)
INSERT INTO #t SELECT '1234567890','Some Description for 1st Account','Short Description for 1st Account',2000 Union All
SELECT '2345678901','Some Description for 2nd Account','Short Description for 2nd Account',3000 Union All
SELECT '1234567890','Some Description for 1st Account','Short Description for 1st Account',4000
;With CTE AS
(
SELECT
AccountNumber
,[Description]
,ShortDescription
,Balance
,SubTotal = SUM(Balance) OVER (PARTITION BY AccountNumber ORDER BY LEFT (AccountNumber, 2))
,Rn = ROW_NUMBER() OVER(PARTITION BY AccountNumber ORDER BY LEFT (AccountNumber, 2))
FROM #t)
SELECT
AccountNumber
,[Description]
,ShortDescription
,Balance = CAST(Balance AS VARCHAR(10))
,SubTotal = CASE WHEN Rn != 1 THEN NULL ELSE SubTotal END
FROM CTE
UNION ALL
SELECT
' ', ' ',' ' ,'Total Amount' , SUM(Balance) FROM CTE
The output being
AccountNumber Description ShortDescription Balance SubTotal
1234567890 Some Description for 1st Account Short Description for 1st Account 2000 6000
1234567890 Some Description for 1st Account Short Description for 1st Account 4000 NULL
2345678901 Some Description for 2nd Account Short Description for 2nd Account 3000 3000
Total Amount 9000
You can create something similar with GROUPING SETS but it all comes in one resultset, eg something like:
SELECT AcGroup, AccountNumber, [Description], ShortDescription, SUM( Balance ) Balance, GROUPING_ID(AcGroup, AccountNumber)
FROM ( SELECT LEFT( AccountNumber, 2 ) AcGroup, * FROM Chart_of_Accounts ) x
GROUP BY GROUPING SETS( (AcGroup), ( AccountNumber, [Description], ShortDescription ), () )
SELECT AcGroup, SUM( Balance ) Balance
FROM ( SELECT LEFT( AccountNumber, 2 ) AcGroup, * FROM Chart_of_Accounts ) x
GROUP BY GROUPING SETS( AcGroup, () )
SELECT AcGroup, SUM( Balance ) Balance
FROM ( SELECT LEFT( AccountNumber, 2 ) AcGroup, * FROM Chart_of_Accounts ) x
GROUP BY AcGroup WITH CUBE
I've added GROUPING_ID() which makes it easier to work out if the source is an original, summary to total row.
I always wondered how you would consume something like that as the multiple resultsets make it difficult to handle. You can't pass it to another stored procedure, you can't copy it paste it directly to Excel (without messing around), passing to a .net client would be awkward. How did you consume the previous code?
HTH

Difference of data per day

I have a table called Addim and the data looks like:
TName Idate Number
Integrated 3/21/2012 26984013
Integrated 3/20/2012 26959226
Integrated 3/19/2012 26933190
I want the output as:
Idate Diff
3/21/2012 24787
3/20/2012 26036
I did something like this:
Select Count(*),Idate
from dbo.Addim
group by Idate
But i am getting output like this:
Idate Diff
03/21/2012 1
03/20/2012 1
basically what it does is it takes the difference from previous day
for example:
for 3/21/2012 the diff is 26984013(3/21/2012)-26959226(3/20/2012) = 24787
and for
3/20/2012 is 26959226(3/20/2012)-26933190(3/19/2012) = 26036
the trick is to join the table back to itself for the previous day, like this:
DECLARE #Addim table (TName varchar(10), Idate datetime,Number int)
INSERT INTO #Addim VALUES ('Integrated','3/21/2012',26984013)
INSERT INTO #Addim VALUES ('Integrated','3/20/2012',26959226)
INSERT INTO #Addim VALUES ('Integrated','3/19/2012',26933190)
SELECT
a.TName,a.Idate, a.Number-b.Number
FROM #Addim a
INNER JOIN #Addim b ON a.TName=b.TName AND a.Idate=b.Idate+1
OUTPUT:
TName Idate
---------- ----------------------- -----------
Integrated 2012-03-21 00:00:00.000 24787
Integrated 2012-03-20 00:00:00.000 26036
(2 row(s) affected)
I wasn't sure the significance of TName, so I joined on that column too, assuming that you'd have multiple different values there as well. You can easily remove it from the join if it is not used like that.
Try this:
;WITH CTE AS
(
SELECT TName, Idate, Number, ROW_NUMBER() OVER(ORDER BY Idate) Corr
FROM #Temp1--YourTable
)
SELECT A.Idate, A.number - B.number Diff
FROM CTE A
INNER JOIN CTE B
ON A.Corr = B.Corr + 1
This assumes one record per day, but it will work even if there are missing days.